# jLab：郭宇的Web3开发最佳实践阅读笔记-4


### jLab：郭宇的最佳实践阅读笔记-4

### 概述

阅读大牛郭宇的文章

https://guoyu.mirror.xyz/RD-xkpoxasAU7x5MIJmiCX4gll3Cs0pAd5iM258S1Ek

第三篇笔记见这里：[here](https://blog.jlab.tech/jlab-3)，主要是优秀应用、优秀合约库的推荐。

下面开始说一些实践，就是开发套路、流程（工作流程，单元测试）。

**Hardhat**：这个不用说了，大部分人都在用它做本地链的搭建和本地合约的部署、测试等。

特性包括：本地链创建部署、公开私钥调试、本地合约编译和本地测试网络，内存网络中运行单元测试；对接不同的区块链网络，部署合约到生成环境；fork某个特定高度区块链到本地来集成测试。

**整合 Hardhat工作流**：

1. 新建： `npx hardhat`，follow流程即可

2. 已经初始化了，比如react或者其他模板初始化过，那就直接添加`hardhat.config.js`

   然后安装对应依赖 `@nomiclabs/hardhat-waffle ethereum-waffle chai @nomiclabs/hardhat-ethers ethers`

3. hardhat主要依靠task，来编译，部署，测试，你的智能合约。

4. 主要任务：`npx hardhat node`, `npx hardhat deploy`, 都在这里面：`hardhat.config.js`，测试可以用`contractInstance.connect(signer)`来更改调用用户。（推销下foundry，郭宇写的，测试起来更方便，有点学习成本）

5. 因为测试需要，我们需要在每次 `beforeEach` 钩子中重新发布我们的合约并使其从零状态开始运行。反复发布会效率很低，推荐`hardhat-deploy`插件，支持使用`evm_snapshot`快速跳到特定区块高度，可以在在单元测试中维护测试前、中、后以及各种特定高度状态，极大地加快测试速度，[Github](https://github.com/wighawag/hardhat-deploy).

6. 安装插件需要注意，引入 `hardhat-deploy` 插件，需要修改对应的 `@nomiclabs/hardhat-ethers` 插件来源，这可能会导致在未来的 `npm install` 中带来版本冲突，如果你遇到了版本冲突，可以使用 `npm install --force` 跳过版本依赖检查，强制安装两者。

   ```
   "devDependencies": {
       "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
       "hardhat-deploy": "^0.11.2",
       ...
   }
   ```

   `hardhat-deploy` 插件还提供了非常多的 HRE 实用函数, 例如支持在`./deploy`编写每个合约的发布脚本。但是也替代了默认脚本（npx hardhat run），详细大家权衡，参考插件的docs。

7. 对权限敏感的合约，可以用`execute`函数立即修改发布后的合约状态: 

```
   const { deploy, execute } = deployments;
   const shareGovernor = await deploy('ShareGovernor', {
       contract: 'TreasuryGovernor',
       from: deployer,
       args: [name + '-ShareGovernor', share.address, treasury.address, settings.share.governor],
       log: true,
     });
   
     // Setup governor roles
     // Both membership and share governance have PROPOSER_ROLE by default
     await execute(
       'Treasury',
       { from: deployer },
       'grantRole',
       PROPOSER_ROLE,
       membershipGovernor.address
     );
```

`getNamedAccounts` 能帮助我们命名本地测试账户，更多参考docs。

8. 测试的覆盖和报告，推荐两个 hardhat 插件 `hardhat-gas-reporter` 与 `solidity-coverage`，`hardhat-gas-reporter` 插件帮助你了解运行单元测试中部署和执行合约方法消耗的 gas 费用，如果在本地环境变量中提供 `COINMARKETCAP_API_KEY`，它会自动将这些成本折算为美元或其他法币计价。

   ![img]()

   [Github](https://github.com/cgewecke/hardhat-gas-reporter), [Github](https://github.com/sc-forks/solidity-coverage)

9. 两个其他的使用插件，他们是 `@nomiclabs/hardhat-etherscan` 和 `@tenderly/hardhat-tenderly`,注意，依赖第三方服务的 API Key！`hardhat-etherscan` 插件将 etherscan 网站的源码 verify 功能整合到发布工作流中，能够将所发布合约的源码和 ABI 都展示在合约地址页面，我自己在用，[Github](https://github.com/NomicFoundation/hardhat). `hardhat-tenderly` 插件整合了 Tenderly 工作流，后者是一个新兴的 CI/监控 平台，能够帮助我们监控线上合约的状态并提供 debug 建议,[Websit](https://tenderly.co/),[Github](https://github.com/Tenderly/hardhat-tenderly)

10. 终于到了Foundry，很棒的工具，学习曲线不陡峭，[Site](https://book.getfoundry.sh/index.html),Foundry 由它的命令行工具 `Forge` 与 `cast` 组成，前者帮助我们安装第三方依赖组件（使用 git submodule 方式）运行测试，发布合约，后者帮助我们与合约进行 RPC 通信交互。思路是不再依赖Nodejs的技术体系。测试文件与合约源码在同一个文件夹中管理，通常以 `ContractName.t.Sol` 特殊后缀结尾。有一系列的测试套件工具帮助我们编写基于 Sol 的单元测试。包括可继承的 `Test` 合约，和一个特殊的，与 vm 通信的合约 `Cheatcodes` 帮助我们改变外部调用者地址，进行错误断言等等功能。

    
