编程日记:连接本地区块链(2022-08-21)

编程学习

行动目录

  1. 搭建运行环境:

    1. 安装 VSCode,

    2. 安装 Node.js

    3. 安装 VSCode 插件

  2. 迁移智能合约:

    1. 简化笔记内容,探索笔记格式。

    2. 重写代码,并修改报错。

  3. 编译智能合约:

    1. 安装 solc 包。

    2. 学习使用 solc 命令,学习使用脚本打包命令。

  4. 部署智能合约:

    1. 安装和运行 WSL 上的本地区块链网络 Ganache, 使用 Ganache 在本地部署合约。

    2. td 使用 Ether.js 执行区块链操作。

做了什么?

  1. 成功理解了 JavaScript Promise 的本质,并将其用笔记清晰地表述了出来。

  2. 成功理解了包 solc 的作用,并知道了每一个 option 的具体作用和用法,最后还将 solc 编译命令用脚本打包表示。

  3. 成功解决 Ganache 在 WSL 上的安装和运行问题。

  4. 成功理解了 RPC 是什么。

  5. 成功理解了服务器地址的本质,也具体了解了地址的三个组成部分: Protocal, IP 和 Port.

  6. 成功就 WSL-2 无法连接到代理的问题,在 Stack Overflow 上进行了提问。

问题

编译器版本问题

报错:

ParserError: Source file requires different compiler version (current compiler is 0.8.7+commit.e28d00a7.Emscripten.clang)

原因:solc 0.8.7-fixed 的版本存在问题。

解决方法:当 solc 更新至最新版本后,compiler version 的问题就不存在了。

package.json 无法链接到代理

警告:

Failed to establish a socket connection to proxies

原因推测:

根据这个 Github 回答,可能是 WSL 在使用代理的过程中,出现了问题。根据回答中提到的 VSCode 官方文档来看,可能是因为我的代理设置出现了问题。

解决方法:

根据 VSCode 官方文档,我想尝试 Manual proxy address, 但是遇见了两个问题:

  1. 根据 VSCode 官方文档来看,如何在命令行当中使用如下命令:--proxy-server=<scheme>=<uri>[:<port>][;...] | <uri>[:<port>] | "direct://"

  2. 根据 Github 回答来看,WSL Server IP 在 /etc/resolv.conf 当中,但是我还是不知道如何根据这个路径找到 resolv.conf 文件?

对于以上两个问题,我将自己的思路用英文表述了一遍,并在 Stackoverflow 上面进行了提问

重启 VSCode 以后,warning 就消失了。

收获了什么?

JS Promise

Promise 是什么?有什么用?

"Producing code" 是提供数据的函数,执行该函数需要一段时间; "Consuming code" 是使用数据的函数,执行该函数前需要等待数据处理出来。 Promise, 则是连接 producing code 和 consuming code 的 JavaScript 对象。

Promise 可以从 state 和 result 的角度,分为两类:

  • Promise state 有三种,分别是 pending, fulfilled, rejected.

  • Promise result 也有三种,且与 state 一一对应,分别是:undefined, a result value, an error object.

如何使用 Promise?

Promise 从用法上看,分为 producing code 和 consuming code 两个部分。

举个例子:

let myPromise = new Promise(function(meResolve, myRejected) => {
    /* producing code */
    myResolve();
    myRejected();
});

/* comsuming code */
myPromise.then(
    function(value) { /* code if resolve */ },
    function(error) { /* code if rejected */ }
);

其中,创建 Promise 的代码就叫做 producing code, 而根据 Promise 的情况去决定下一步该怎么做的代码就叫做 consuming code.

td 如果碰见了新的不会的内容,可以再回过头来,完善对 Promise 使用部分的理解和记录。

solc

solc 是用于编译 Solidity 的包。

它的安装方式有两种,一种是通过 nmp 包管理器,命令行为: npm install solc;另一种是通过 yarn 包管理器,命令行为:yarn add solc.

通过运行 solc 脚本,可以将指定的 solidity 合约以指定的形式编译出来。

举个例子:

solcjs --bin --include-path node_modules/ --base-path . MainContract.sol

这是 solc 官网给出的例子,根据官网的提示和 yarn solcjs --help 自带的提示,可以知道以上 options 的含义:

  • "--bin": 代表编译出合约的二进制形式,并以 .bin 文件的形式表示。

  • "--include-path": 代表合约所导入的包的位置

  • "--base-path": 代表合约的位置。

再举个例子:

yarn solcjs --bin --abi --include-path node_module/ --base-path . -o . SimpleStorage.sol

这是 Patrick 视频教程中的例子,分别解释一下官网当中所没有的 options 及其含义:

  • "--abi": 代表编译出合约的 ABI, 并以 .abi 文件的形式表示。

  • "-o": 代表编译后的内容的输出目录 (output directory) ,即 .bin 文件和 .abi 文件的存放位置。

用脚本打包命令

对于一长串的命令,可以通过脚本来简化输入。

举个例子:

我们可以在 package.json 文件中,添加如下代码:

{
    "scripts": {
        "compile": "yarn solcjs --bin --abi --include-path node_module/ --base-path . -o . SimpleStorage.sol"
    }
}

这样一来,我们输入 yarn compile 就等同于输入 yarn solcjs --bin --abi --include-path node_module/ --base-path . -o . SimpleStorage.sol. 因此也就通过脚本,简化了输入。

RPC

RPC 维基百科解释:

RPC is a request-response protocal.

An RPC is initiated by the client, which sends a request messega to a known remote server to execute a specific procedure with supplied parameter.

The remote server sends a response to the client, and the applications continue its process.

RPC 指 Remote Procedure Call 即远程过程调用。个人认为,它和 http 请求很像,向服务器发送请求,服务器返回响应。

服务器地址

对于 Ganache 上的 RPC Server 来说,它由协议、 ip 地址和端口组成的服务器地址为:http://0.0.0.0:8545.

如何理解这些信息呢?可以分成三个部分来看:

  1. Protocal 协议:与 RPC 服务器通讯的客户端,需要遵守 http 协议,这样客户端的请求才能够被服务器理解。

  2. IP 地址:0.0.0.0 代表本地 IP 地址,代表该服务器是本地服务器。

  3. Port 端口:8545 代表访问该 Ganache 服务器所应当通过的端口,因为每一个应用程序都在监听一个端口,只有通过特定的端口,才能访问到该服务器上特定的应用

对于 Ganache 而言,Ganache 就运行在端口 8545 上,因此想要访问 Ganache 本地服务器,那么就需要通过 8545 来找到 Ganache.