forked from dukedaily/solidity-expert
-
Notifications
You must be signed in to change notification settings - Fork 0
/
07_综合教程.md
358 lines (214 loc) · 8.89 KB
/
07_综合教程.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# 一、概述
## 1. 本教程介绍
1. 使用hardhat部署到不同网络,自动verify代码
2. 单元测试编写
3. deploy脚本,deploy插件使用
4. 可升级合约编写,使用,页面关联
你对工具链的所有疑问都会在这里得到demo答案!
## 2. hardhat框架的好处
1. 在config文件中配置网络,部署在node,hardhat,其他指定的网络
2. 在.env中写秘钥等信息
3. 可以自动部署,Verify代码
4. 可以编写单元测试
# 二、代码目录
参考链接:
1. 教程:https://medium.com/@rahulsethuram/the-new-solidity-dev-stack-buidler-ethers-waffle-typescript-tutorial-f07917de48ae
2. hardhat:https://learnblockchain.cn/docs/hardhat/guides/waffle-testing.html
# 三、部署在localhost
安装:
```sh
npm install
```
编译:
```sh
npm run compile
```
单元测试:
```sh
npm run test
```
启动本地内存区块链环境:
```sh
npx hardhat node
```
## 1. 普通部署
方式1,使用hardhat-deploy包部署,具体编写查看`deploy`文件夹
```js
npx hardhat --network localhost deploy
```
方式2,使用脚本部署
```js
npx hardhat run --network localhost scripts/deploy.ts
```
测试一下,需要修改地址`testV1.ts`中的地址为刚刚部署的地址。
```js
npx hardhat run scripts/testV1.ts --network localhost
```
## 2. 可升级部署
### - 以可升级方式部署合约
1. 执行命令:
```sh
npx hardhat run --network localhost scripts/01-deploy_counter.ts
```
> 得到地址:0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
### - 调用后查看运行结果
1. 修改testV1.ts中的地址为: `0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9`
2. 执行命令:
```js
npx hardhat run --network localhost scripts/testV1.ts
```
### - 修改代码后开始升级
1. 首先创建新文件:CounterV2Upgrade.sol,相比之下比之前的合约增加了`changeOwner`方法。
2. 修改`02-upgradeCounterV2.t`中的合约地址为:`0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9`。
3. 执行升级命令:
```sh
npx hardhat run --network localhost scripts/02-upgradeCounterV2.ts
```
### - 调用合约,确认结果
1. 修改`testV2.ts`中的地址为:`0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9`
2. 执行命令,查看结果,结果应该`加1`,`manager`也应该发生改变。
```sh
npx hardhat run --network localhost scripts/testV2.ts
```
# 四、部署在kovan
首先需要修改.env.bak文件,修改为.env,并且填入自己的API_KEY信息:(自行搜索🔍)
```js
MNEMONIC="你的助记词"
#DEBUG=true
PRIVATE_KEY="你指定的一个私钥"
INFURA_API_KEY="你的Infura私钥"
# Optional Etherscan key, for automatize the verification of the contracts at Etherscan
ETHERSCAN_API_KEY="你的ETHERSCAN_API_KEY"
```
## 1. 普通部署(略)
略,同上,只需要将localhost改为kovan即可。
```sh
#部署在本地:
npx hardhat --network localhost deploy
#部署在kovan:
npx hardhat --network kovan deploy
```
## 2. 可升级部署
> 先备份.openzeppelin下面的kovan.json文件(若有)
### - 以可升级方式部署合约
1. 执行命令:
```sh
npx hardhat run --network kovan scripts/01-deploy_counter.ts
```
2. 该操作会部署三个合约,得到三个地址(存在vscode工程下:.openzeppelin/kovan.json文件中)
1. **proxy合约(==对外不变的==):**
1. 地址:0xF5deCF1CB99C4D6Aa22Ee49A3D32Eb21bee73d22。
2. 默认verify,因为这个升级合约是openzeppelin官方提供的,很多人已经验证过了。
2. **proxyAdmain合约:**
1. 地址:0x5670ffB7167bc72d3B11e209133aCC73Fb9292be。
2. 默认verify,proxy的管理合约,用于修改代理与实现升级操作。
3. **我们的Counter合约:**
1. 地址:0x06e166edB942fe7Dd2b04d13443BbB6e835aEd39。
2. 我们真正关心的业务逻辑。
### - 调用后查看运行结果
1. 修改`testV1.ts`中的地址为: `0xF5deCF1CB99C4D6Aa22Ee49A3D32Eb21bee73d22`。
2. 执行命令:
```js
npx hardhat run --network kovan scripts/testV1.ts
```
3. 通过浏览器,输入代理合约Proxy地址,我们可以看到已经成功调用了一次CountUp,数据变成:1, 并且通过Internal Txns标签看到交互的合约是具体实现合约:
![image-20211105102513240](assets/image-20211105102513240.png)
具体交互合约正是我们的Counter合约,如下图:
![image-20211105102538738](assets/image-20211105102538738.png)
疑问:为什么上面还有个:0x0000交互?细节需要看代码。
4. 查看`proxyAdmin`合约,检查一下数据,在读方法中,如下图:输入proxy地址,可以得到我们的Counter合约地址:
![image-20211105103020934](assets/image-20211105103020934.png)
在写方法,可以看到proxyAdmain的相关方法:更换管理员,更换实现合约
![image-20211105103208502](assets/image-20211105103208502.png)
4. 接下来我们verify我们的Counter合约代码:
```sh
#npx hardhat verify --network kovan <合约地址> constructor参数
npx hardhat verify --network kovan 0x06e166edB942fe7Dd2b04d13443BbB6e835aEd39
```
![image-20211105104228647](assets/image-20211105104228647.png)
5. 为了在proxy下可以直接操作具体的实现逻辑,需要我们手动关联proxy和implementation的关系,操作为:在proxy页面点击:more option -> is this a proxy?
![image-20211105104327033](assets/image-20211105104327033.png)
点击:verify
![image-20211105104422997](assets/image-20211105104422997.png)
点击:save
![image-20211105104438472](assets/image-20211105104438472.png)
此时,回到proxy页面,可以看到implementation对应的方法
![image-20211105104520515](assets/image-20211105104520515.png)
![image-20211105104554392](assets/image-20211105104554392.png)
点击:countUp后,数据变成:2
![image-20211105104708548](assets/image-20211105104708548.png)
### - 修改代码后开始升级
1. 修改:(proxy地址)
```sh
02-upgradeCounterV2.ts中的地址为:0xF5deCF1CB99C4D6Aa22Ee49A3D32Eb21bee73d22
```
2. 执行:
```sh
npx hardhat run --network kovan scripts/02-upgradeCounterV2.ts
```
在upgradeCounterV2合约中,我们增加了一个`changeOwner`方法,其他内容未改变。
```js
function changeOwner(address owner) public {
require(msg.sender == manager, "forbidden!");
manager = owner;
}
```
升级成功:
![image-20211105105010525](assets/image-20211105105010525.png)
3. 到adminProxy中检查升级后的implementation地址: [0xC564f82cA3109F701420a212c345C4747Bc16b0f](https://kovan.etherscan.io/address/0xC564f82cA3109F701420a212c345C4747Bc16b0f)
![image-20211105105154465](assets/image-20211105105154465.png)
4. 回到proxy中,查看内部交易,发现:
![image-20211105105413746](assets/image-20211105105413746.png)
5. 对新发布的implementation合约进行verify代码:
```js
npx hardhat verify --network kovan 0xC564f82cA3109F701420a212c345C4747Bc16b0f
```
![image-20211105105930918](assets/image-20211105105930918.png)
6. 查看proxy的写方法,我们的新方法中,看到新方法已经存在:
![image-20211105110041907](assets/image-20211105110041907.png)
读方法中,getCount依然为升级之前的值:2
![image-20211105110110236](assets/image-20211105110110236.png)
### - 调用合约,确认结果
1. 修改`testV2.ts`中的地址为:0xF5deCF1CB99C4D6Aa22Ee49A3D32Eb21bee73d22
2. 执行命令
```sh
npx hardhat run --network kovan scripts/testV2.ts
```
3. 效果
![image-20211105110641875](assets/image-20211105110641875.png)
数值改变,owner改变:
![image-20211105110709232](assets/image-20211105110709232.png)
## 其他琐碎问题:
1. 需要安装:
```js
npm i --save-dev @types/chai-as-promised
npm install --save-dev solidity-coverage #为了运行coverage
```
2. 什么是覆盖测试?这个使用solidity-coverage提供的功能
3. hre与hardhat的关系,这回终于弄清楚了。
```sh
#hardhat这个包export的是env,这个env就是:HardhatRuntimeEnvironment
import hre from 'hardhat'
#这句的意思是从env中解析出ethers,因为HardhatRuntimeEnvironment是包含ethers的
import { ethers} from "hardhat";
上面这句等价于从hre对象解析出了:ethers
即hre中包含ethers
#hre.ethers
#{ ethers} = hre
#想导入原生的ethers需要指定为
import ethers_raw from "ethers"
#hre.ethers包里面实现了原生包的所有功能,并且做了增强
```
4. chai和hardhat-waffle的关系是什么?
## deploy
https://learnblockchain.cn/article/2354
```js
npm install -D hardhat-deploy
```
## 升级
翻译:https://learnblockchain.cn/article/1990
原文:https://docs.openzeppelin.com/learn/upgrading-smart-contracts
```js
npm install --save-dev @openzeppelin/hardhat-upgrades
npm i @openzeppelin/contracts
```