Skip to content

Commit 812709c

Browse files
authored
Merge branch 'Dapp-Learning-DAO:main' into main
2 parents ded8774 + 0c38313 commit 812709c

File tree

38 files changed

+3323
-5127
lines changed

38 files changed

+3323
-5127
lines changed

basic/02-web3js-transaction/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const privatekey = process.env.PRIVATE_KEY;
1010
*/
1111
// Provider
1212
const providerRPC = {
13-
development: 'https://kovan.infura.io/v3/' + process.env.INFURA_ID
13+
development: 'https://kovan.infura.io/v3/' + process.env.INFURA_ID,
14+
moonbase: 'https://rpc.testnet.moonbeam.network',
1415
};
1516
const web3 = new Web3(providerRPC.development); //Change to correct network
1617

basic/06-ethersjs-waffle/README-cn.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[English](https://github.com/Dapp-Learning-DAO/Dapp-Learning/main/basic/06-ethersjs-waffle/README.md)
1+
中文 / [English](./README.md)
22

33
## 前言
44

basic/06-ethersjs-waffle/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[中文](https://github.com/Dapp-Learning-DAO/Dapp-Learning/main/basic/06-ethersjs-waffle/README-CN.md)
1+
[中文](./README-CN.md) / English
22

33
## Preface
44

basic/07-hardhat/README-cn.md

+324
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
中文 / [English](./README.md)
2+
3+
4+
# Hardhat
5+
6+
Hardhat 是一个编译、部署、测试和调试以太坊应用的开发环境。
7+
8+
它可以帮助开发人员管理和自动化构建智能合约和 dApps 过程中固有的重复性任务,并围绕这一工作流程轻松引入更多功能。这意味着 hardhat 在最核心的地方是编译、运行和测试智能合约。
9+
Hardhat 内置了 Hardhat 网络,这是一个专为开发设计的本地以太坊网络。主要功能有 Solidity 调试,跟踪调用堆栈、console.log()和交易失败时的明确错误信息提示等。
10+
11+
Hardhat Runner 是与 Hardhat 交互的 CLI 命令,是一个可扩展的任务运行器。它是围绕任务和插件的概念设计的。每次你从 CLI 运行 Hardhat 时,你都在运行一个任务。例如,`npx hardhat compile` 运行的是内置的 compile 任务。任务可以调用其他任务,允许定义复杂的工作流程。用户和插件可以覆盖现有的任务,从而定制和扩展工作流程。
12+
13+
## 准备工作 - Preparatory Work
14+
15+
在开始学习 hardhat 之前,你需要提前了解以下知识点:
16+
17+
- dotenv 将私钥存放在 `.env` 文件中可以避免将私钥暴露在服务器上,格式为 "PRIVATE_KEY=xxxx", 然后代码自动从中读取,详情参考 [dotenv](https://www.npmjs.com/package/dotenv)
18+
- npx 想要解决的主要问题,就是调用项目内部安装的模块。详情参考 [npx 使用教程](https://www.ruanyifeng.com/blog/2019/02/npx.html)
19+
- ethers.js 与以太坊网络交互的工具库,相比 web3.js 接口设计更加易于使用(注意 v5 和 v4 接口差别较大) [ethers.js v5 文档](https://docs.ethers.io/v5/)
20+
- mocha.js 测试框架,用于编写合约交互的测试案例 [mochajs 文档](https://mochajs.org/#getting-started)
21+
- chai.js 断言库,辅助测试脚本编写,使用方法参考 [ethereum-waffle chai 使用文档](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html)
22+
- infura 连接区块链的节点服务商,有免费的使用额度,足够开发调试使用 [infura 官网](https://infura.io/)
23+
24+
## 项目结构和配置 hardhat
25+
26+
```sh
27+
mkdir 07-hardhat // 创建项目文件夹
28+
cd 07-hardhat // 移动到项目文件夹下
29+
npm install --save-dev hardhat // 安装hardhat
30+
npx hardhat // 创建hardhat项目
31+
```
32+
33+
输入`npx hardhat`后,命令行中会出现如下的界面:
34+
35+
```sh
36+
888 888 888 888 888
37+
888 888 888 888 888
38+
888 888 888 888 888
39+
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
40+
888 888 "88b 888P" d88" 888 888 "88b "88b 888
41+
888 888 .d888888 888 888 888 888 888 .d888888 888
42+
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
43+
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
44+
45+
Welcome to Hardhat v2.9.0
46+
47+
? What do you want to do? ...
48+
> Create a basic sample project
49+
Create an advanced sample project
50+
Create an advanced sample project that uses TypeScript
51+
Create an empty hardhat.config.js
52+
Quit
53+
```
54+
55+
我们使用'Create a basic sample project'选项,创建一个基础项目,后面的两个选项直接敲回车选择默认值。
56+
57+
### 项目结构
58+
59+
一个标准的使用 hardhat 构建的项目通常是这样的:
60+
61+
```sh
62+
contracts/
63+
scripts/
64+
test/
65+
hardhat.config.js
66+
```
67+
68+
- contracts 用于存放 solidity 合约文件
69+
- scripts 用于存放脚本文件,如部署合约的脚本
70+
- test 用于存放测试脚本,通常以 `contractName.test.js` 的形式命名
71+
- `hardhat.config.js` 是 hardhat 的配置文件
72+
73+
### 配置 hardhat
74+
75+
`hardhat.config.js` 配置文件示例
76+
77+
```js
78+
require('@nomiclabs/hardhat-waffle');
79+
require('dotenv').config();
80+
81+
module.exports = {
82+
networks: {
83+
// hardhat 内置测试网络(选填)
84+
hardhat: {
85+
// 可以设置一个固定的gasPrice,在测试gas消耗的时候会很有用
86+
gasPrice: 1000000000,
87+
},
88+
// 你可以在这里配置任意网络
89+
// rinkeby 测试网络
90+
rinkeby: {
91+
// 请将 INFURA_ID 替换成你自己的
92+
// url: 'https://rinkeby.infura.io/v3/{INFURA_ID}',
93+
url: 'https://rinkeby.infura.io/v3/' + process.env.INFURA_ID, //<---- 在.env文件中配置自己的INFURA_ID
94+
95+
// 填写测试账户的私钥,可填写多个
96+
accounts: [process.env.PRIVATE_KEY, ...]
97+
}
98+
},
99+
solidity: {
100+
version: "0.8.0", // 合约编译的版本,必填
101+
settings: { // 编译设置,选填
102+
optimizer: { // 优化设置
103+
enabled: true,
104+
runs: 200
105+
}
106+
}
107+
},
108+
// 项目路径配置,可指定任意路径,但下列是常用的一种结构
109+
// sources, tests, scripts 下的目录文件会被自动逐一执行
110+
paths: {
111+
sources: "./contracts", // 合约目录
112+
tests: "./test", // 测试文件目录
113+
cache: "./cache", // 缓存目录,由hardhat自动生成
114+
artifacts: "./artifacts" // 编译结果目录,由hardhat自动生成
115+
},
116+
// 测试框架设置
117+
mocha: {
118+
timeout: 20000 // 运行单元测试的最大等待时间
119+
}
120+
}
121+
```
122+
123+
### 内置 hardhat 网络
124+
125+
hardhat 内置了一个特殊的安全测试网络,其名称也叫 `hardhat`, 通常你不需要对他进行特殊配置。该网络会模拟真实区块链网络的运行机制,并为你生成好 10 个测试账户(和 truffle 类似)。
126+
127+
### 使用插件
128+
129+
Hardhat 的很多功能都来自于插件,而作为开发者,你可以自由选择想使用的插件。
130+
131+
例如常用的 waffle 插件,使得 hardhat 可以集成 waffle 框架,进行开发,测试,部署。
132+
133+
```js
134+
// hardhat.config.js
135+
require('@nomiclabs/hardhat-waffle'); // hardhat waffle 插件
136+
...
137+
```
138+
139+
### 安装依赖
140+
141+
1. 安装 nodejs (略)
142+
143+
2. 安装项目依赖:
144+
145+
```sh
146+
npm install --save-dev @nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers dotenv
147+
```
148+
149+
或使用 yarn 安装(需要先安装 yarn 依赖)
150+
151+
```sh
152+
yarn add -D hardhat-deploy-ethers ethers chai chai-ethers mocha @types/chai @types/mocha dotenv
153+
```
154+
155+
3. 配置私钥和网络:
156+
157+
在项目文件夹下新建`.env`文件,并且在 `.env` 文件中填写私钥和 infura 节点
158+
159+
```js
160+
PRIVATE_KEY = xxxxxxxxxxxxxxxx; // 替换为你的私钥
161+
INFURA_ID = yyyyyyyy; // 替换为infura节点
162+
```
163+
164+
## usage
165+
166+
hardhat 的用法
167+
168+
### compile
169+
170+
运行如下命令,hardhat 会自动编译配置中 `sources` 路径下的所有合约文件,默认是 `./contracts` 路径。
171+
172+
```sh
173+
npx hardhat compile
174+
```
175+
176+
### test
177+
178+
运行如下命令,hardhat 会自动运行配置中 `tests` 路径下的所有测试文件,默认是 `./test` 路径。
179+
180+
```sh
181+
npx hardhat test
182+
```
183+
184+
也可以指定运行某个特定测试文件
185+
186+
```sh
187+
npx hardhat test ./test/Greeter.test.js
188+
```
189+
190+
### run
191+
192+
拷贝 script 目录下的脚本,作为我们的运行脚本:
193+
194+
windows:
195+
196+
```bash
197+
copy .\scripts\sample-script.js .\scripts\deploy.js
198+
```
199+
200+
linux:
201+
202+
```bash
203+
cp ./scripts/sample-script.js ./scripts/deploy.js
204+
```
205+
206+
运行指定脚本。如果不指定运行网络,会默认在 hardhat 内置网络内运行 (Hardhat Network)。
207+
208+
```sh
209+
npx hardhat run ./scripts/deploy.js
210+
```
211+
212+
指定运行的网络,例如在 rinkeby 测试网部署合约(请确保钱包地址在 rinkeby 测试网有足够的 gas 才能成功部署)
213+
214+
```sh
215+
npx hardhat run ./scripts/deploy.js --network rinkeby
216+
```
217+
218+
### task
219+
220+
hardhat 本身预设了一些程序任务,例如编译合约,运行测试文件,这些其实在 hardhat 中是预先配置好的任务。
221+
222+
实际上你也可以自定义一些 task,比如打印一下当前网络中的账户状态:
223+
224+
```js
225+
// hardhat.config.js
226+
...
227+
228+
task('accounts', 'Prints the list of accounts', async () => {
229+
const accounts = await ethers.getSigners();
230+
231+
for (const account of accounts) {
232+
console.log(account.address);
233+
}
234+
});
235+
236+
...
237+
```
238+
239+
运行 task
240+
241+
```sh
242+
npx hardhat accounts
243+
```
244+
245+
命令行会打印出 10 个测试账户地址
246+
247+
```sh
248+
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
249+
...
250+
```
251+
252+
### console
253+
254+
hardhat 的控制台模式,实时与链上交互。默认会启动 hardhat 内置网络。
255+
256+
```sh
257+
npx hardhat console
258+
```
259+
260+
控制内置 ethers 和 web3 库,可以直接使用,无须引入。
261+
262+
```js
263+
// hardhat console mode:
264+
// 可以直接使用 async/await 语法
265+
> await ethers.provider.getBlockNumber() // 0
266+
```
267+
268+
### console.log debug
269+
270+
hardhat 提供了一个 `console.log()` 方法,可以在合约运行时打印日志,方便调试和测试。**此方法仅在 hardhat 内置网络中运行有效。**
271+
272+
在合约中引入 `hardhat/console.sol` 即可使用:
273+
274+
```solidity
275+
import "hardhat/console.sol";
276+
277+
contract Greeter {
278+
...
279+
280+
function setGreeting(string memory _greeting) public {
281+
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
282+
greeting = _greeting;
283+
}
284+
285+
}
286+
```
287+
288+
在运行测试文件时,可以看到打印出的日志:
289+
290+
```sh
291+
Changing greeting from 'Hello, world!' to 'hello Dapp-Learning!'
292+
```
293+
294+
## 实操流程
295+
296+
### 编译和测试
297+
298+
1. 编译合约
299+
300+
```bash
301+
npx hardhat compile
302+
```
303+
304+
2. 批量运行测试脚本
305+
306+
```bash
307+
npx hardhat test
308+
```
309+
310+
3. 部署到测试网:
311+
312+
```bash
313+
npx hardhat run scripts/deploy.js --network <network-name>
314+
```
315+
316+
这里的 `network-name` 替换成你指定的网络名称,这里可以换成 `rinkeby`,对应配置文件中的网络名称。
317+
318+
## 参考文档
319+
320+
- hardhat 官方文档: <https://hardhat.org/guides/project-setup.html>
321+
- hardhat 中文文档: <https://learnblockchain.cn/docs/hardhat/getting-started/>
322+
- ethers.js 和 hardhat 基础使用讲解: <https://www.bilibili.com/video/BV1Pv411s7Nb>
323+
- <https://rahulsethuram.medium.com/the-new-solidity-dev-stack-buidler-ethers-waffle-typescript-tutorial-f07917de48ae>
324+
- erc20 openzepplin介绍: <https://segmentfault.com/a/1190000015400380>

0 commit comments

Comments
 (0)