Skip to content

Commit 8a6ad34

Browse files
committed
Merge branch 'task/liun1an' of github.com:LiuN1an/Dapp-Learning into task/liun1an
2 parents 122d7a8 + 44173e6 commit 8a6ad34

File tree

471 files changed

+41942
-4210
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

471 files changed

+41942
-4210
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*/node_modules
22
**/.env
33
**/sk.txt
4+
**/env.py
45
**/sk*.txt
56
**/sk*.json
67
**/__pycache__
@@ -38,3 +39,4 @@ yarn-error.log*
3839

3940
.idea
4041
.vscode
42+
mnemonic.txt

README-CN.md

Lines changed: 427 additions & 0 deletions
Large diffs are not rendered by default.

README-en.md

Lines changed: 0 additions & 320 deletions
This file was deleted.

README.md

Lines changed: 271 additions & 229 deletions
Large diffs are not rendered by default.

basic/01-web3js-deploy/README-cn.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
中文 / [English](./README-en.md)
2+
## 前言
3+
通过本样例代码,使开发者了解合约编译,部署的基本流程,并掌握基本的 web3js 接口使用方法
4+
5+
- 本样例发送交易到 Infura , 需要创建相应的 Infura Project, 可以参考如下资料进行创建
6+
https://ithelp.ithome.com.tw/articles/10202794 在成功创建 Infura Project 后,可以获取相应的PROJECT ID
7+
8+
- 本样例中,需要自己来生成私钥。可通过多种方式来生成私钥。常见的方式是通过Metamask。可参考《精通以太坊》或其他文档安装: https://www.bookstack.cn/read/ethereum_book-zh/spilt.4.77adf5064f4455e8.md 安装完成后,连接到Kovan测试网络,点击账户详情-导出私钥,获得创建的测试账号的私钥PRIVATE_KEY。
9+
10+
- 给Kovan测试网络中的测试账号充值。上一步开立的账号中,余额为0, 可通过faucets来充值: https://faucets.chain.link/kovan 每次冲入0.1Eth。
11+
12+
- 为方便代码测试, 在 .env 中放入私钥和Infura Project ID,格式为 "PRIVATE_KEY=xxxx" "INFURA_ID=yyyyyyyy", index.js代码会自动从中读取, 样例文件可参考 .env.example
13+
14+
- 同时在 BiliBili 上有上传本样例代码的讲解演示:
15+
https://www.bilibili.com/video/BV1Y44y1r7E6/
16+
17+
## 合约功能说明
18+
constructor: 构造函数, 用于部署合约时调用, 同时在其中初始化了公共变量 number 的值
19+
increment: 增值函数, 根据传入的数值 ( _value ), 对公共变量 number 进行增值 ( number + _value )
20+
reset: 重置函数, 用于重置公共变量 number 的值为 0
21+
getNumber: 查询函数, 用于查询公共变量 number 当前的数值
22+
23+
## 测试流程:
24+
1) 安装依赖
25+
```
26+
npm install
27+
```
28+
29+
2) 配置 .env
30+
```
31+
cp .env.example .env
32+
33+
## 修改 .env 中的 INFURA_ID 和 PRIVATE_KEY 为实际的值
34+
PRIVATE_KEY=xxxxxxxxxxxxxxxx
35+
INFURA_ID=yyyyyyyy
36+
```
37+
38+
3) 执行 index.js
39+
```
40+
node index.js
41+
```
42+
## index.js 代码逻辑说明
43+
1) 读取私钥
44+
出于安全考虑, 私钥没有进行硬编码, 而是通过环境变量的方式进行获取. 启动测试时, dotenv 插件自动读取 .env 配置文件中的配置项, 然后加载为环境变量, 之后在代码中可以通过 process.env 读取私钥 ( 也包括其他环境变量 )
45+
```js
46+
require("dotenv").config();
47+
const privatekey = process.env.PRIVATE_KEY;
48+
```
49+
50+
2) 编译合约
51+
我们无法直接使用 .sol 文件, 需要把它编译为 bin 文件 ( 二进制文件 ), 因此在代码中需要进行这一步的逻辑处理.
52+
- 读取文件
53+
第一步, 我们先进行文件的读取, 把 sol 文件加载为 source 变量
54+
```js
55+
56+
// Load contract
57+
const source = fs.readFileSync("Incrementer.sol", "utf8");
58+
```
59+
60+
- 进行合约编译
61+
这里进行编译动作. 把 sol 源码编译为 solidity 对象. 这里需要注意的是不同的 sol 源码版本, 编译的方式可能稍有不同, 这里因为 "Incrementer.sol" 对应的是 sol 是 0.8.0 版本, 所以我们可以使用如下的方式进行编译
62+
```js
63+
// compile solidity
64+
const input = {
65+
language: "Solidity",
66+
sources: {
67+
"Incrementer.sol": {
68+
content: source,
69+
},
70+
},
71+
settings: {
72+
outputSelection: {
73+
"*": {
74+
"*": ["*"],
75+
},
76+
},
77+
},
78+
};
79+
80+
const tempFile = JSON.parse(solc.compile(JSON.stringify(input)));
81+
```
82+
83+
3) 获取二进制对象
84+
在上一步编译成功的 solidity 对象里面包含很多的属性/值, 而我们需要的是其中合约对象的二进制, abi 属性值. 如下, 我们通过属性提取方式进行获取. solidity 对象的其他属性可以通过代码调试方式进行调试, 这里不再赘述.
85+
```js
86+
const contractFile = tempFile.contracts["Incrementer.sol"]["Incrementer"];
87+
88+
// Get bin & abi
89+
const bytecode = contractFile.evm.bytecode.object;
90+
const abi = contractFile.abi;
91+
```
92+
93+
4) 构造 web3 对象
94+
通过 web3 对象可以很方便的发送相应的交易到区块链网络, 同时获取区块链的处理结果.
95+
构造 web3 对象时, 主要需要传入一个参数, 就是对应的区块链网络, 包括 kovan, ropsten , rinkeby 等测试网络, 或是 mainnet 主网.
96+
这里我们使用 kovan 测试网络. 如果没有 kovan 网络的测试币, 可以切换到其他的测试网络.
97+
同时需要注意的是, 这里我们通过 infura 向对应的区块链网络发送交易, 而 INFURA_ID 这个变量值也需要配置在 .env 文件中, 具体如何获取 infura_id, 可自行搜索查找相关文档
98+
```js
99+
// Create web3 with kovan provider,you can change kovan to other testnet
100+
const web3 = new Web3(
101+
"https://kovan.infura.io/v3/" + process.env.INFURA_ID
102+
);
103+
```
104+
105+
5) 获取账户地址
106+
在区块链上, 每个用户都有一个对应的账户地址, 而这个账户地址可以通过私钥进行获取. 这里, 我们调用 web3.eth.accounts.privateKeyToAccount 接口, 传入对应的私钥, 就可以获取对应的账户地址
107+
```js
108+
// Create account from privatekey
109+
const account = web3.eth.accounts.privateKeyToAccount(privatekey);
110+
const account_from = {
111+
privateKey: privatekey,
112+
accountAddress: account.address,
113+
};
114+
```
115+
116+
6) 构造合约实例
117+
在步骤 3 中, 我们获取了 sol 源文件编译后的二进制 和 abi, 这里就可以使用对应的 abi 构造相应的合约实例, 以便在后续中通过合约实例进行交易的发送
118+
```js
119+
// Create contract instance
120+
const deployContract = new web3.eth.Contract(abi);
121+
```
122+
123+
7) 创建合约交易
124+
调用 deployContract.deploy 接口, 我们创建了部署合约的二进制交易. 这里, 此交易还没有发送到区块链网络, 即合约还没有被创建
125+
```js
126+
// Create Tx
127+
const deployTx = deployContract.deploy({
128+
data: bytecode,
129+
arguments: [5],
130+
});
131+
```
132+
133+
8) 交易签名
134+
如下使用私钥对交易进行签名,
135+
```js
136+
// Sign Tx
137+
const deployTransaction = await web3.eth.accounts.signTransaction(
138+
{
139+
data: deployTx.encodeABI(),
140+
gas: 8000000,
141+
},
142+
account_from.privateKey
143+
);
144+
```
145+
146+
9) 部署合约
147+
这里使用发送签名后的交易到区块链网络, 同时会去返回的交易回执. 从返回的交易回执中可以得到此次部署的合约的地址
148+
```js
149+
const deployReceipt = await web3.eth.sendSignedTransaction(
150+
deployTransaction.rawTransaction
151+
);
152+
console.log(`Contract deployed at address: ${deployReceipt.contractAddress}`);
153+
```
154+
155+
## 参考文档
156+
- Web3js官方文档:
157+
https://web3js.readthedocs.io/en/v1.2.11/getting-started.html
158+
- Web3js中文文档(1.2.6):
159+
https://learnblockchain.cn/docs/web3.js/web3-eth-contract.html
160+
- 样例代码参考如下链接
161+
https://docs.moonbeam.network/getting-started/local-node/deploy-contract/
162+
- Web3js使用参考文档:
163+
https://www.dappuniversity.com/articles/web3-js-intro
164+
- nodejs参考文档:
165+
http://nodejs.cn/api/fs.html
166+

0 commit comments

Comments
 (0)