# Hardhat简洁教程 **Published by:** [lolieatapple](https://paragraph.com/@lolieatapple/) **Published on:** 2022-08-17 **URL:** https://paragraph.com/@lolieatapple/hardhat ## Content 1. 概述HardHat为开发者提供了许多合约开发的便捷功能,包括合约的编译、部署、验证、调试等方面。相对于使用其它工具,使用HardHat进行智能合约开发,可以:方便的启动内置模拟节点;使用内置打印接口在solidity代码内打印调试日志(console.log)在合约报错查看call-stack,和详细报错原因fork现有网络和状态来启动模拟节点2. 开发环境搭建可以使用npm install将hardhat工具嵌入到任意现有的solidity工程代码目录内,或者创建全新的工程代码,使用如下代码在空目录中创建全新的solidity合约开发目录框架:$ yarn add -D hardhat $ yarn hardhat init 初始化完成后,目录结构如下:. ├── README.md ├── contracts │ └── Lock.sol ├── hardhat.config.js ├── package.json ├── scripts │ └── deploy.js ├── test │ └── Lock.js └── yarn.lock contracts目录放置solidity合约代码,scripts目录放置部署脚本test目录放置测试脚本。3. Fork现有区块链网络使用Fork功能可以基于现有区块链网络RPC创建一个模拟的开发节点。这里的RPC推荐使用Alchemy提供的节点服务。 例如使用下面代码fork一个ethereum的主网开发环境: (暂时不支持Wanchain,因为不识别transaction type: 255)$ yarn hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/<YouAlchemyApiKey> 也可在后方加入 --fork-block-number 14390000 参数来指定基于某一个块的状态来进行fork。 fork成功后,它会自动注入20个包含10000ETH的开发账号。同时包含以太坊的所有合约以及地址状态信息。 fork后的默认的RPC是: http://localhost:8545 chainId会发生变化,可以在添加到MetaMask的时候看到新chainId。(我本地当前是31337) 将fork节点添加到MetaMask网络,并将生成的测试私钥导入MetaMask钱包中,方便下一步开发使用。4. 使用remix开发和调试为方便代码部署和调试,这里使用remix绑定本地文件目录功能,绑定刚刚建好的hardhat目录。使用如下指令绑定当前目录到remix:(remixd需要使用npm全局安装)$ remixd -s . 在浏览器中打开: https://remix.ethereum.org/ 在workspace位置选择localhost,即可连接到本地绑定目录,并看到我们的实例代码文件。remix界面截图可以看到Lock.sol中的示例代码。我们在其中加入两行console.log日志打印,并在编译窗口选择合适的solidity版本进行编译。编译合约在合约部署页面,选择使用MetaMask部署。合约部署输入错误的构造函数参数时,可以在控制台的fork节点日志中看到错误提示信息:错误信息提示输入正确的构造函数部署合约,可以在控制台中看到在合约代码中console.log输出的日志信息:日志输出5. 使用VSCode + 脚本编译和部署合约编译合约代码可以使用如下指令:$ yarn hardhat compile 使用本地fork节点部署合约:yarn hardhat run --network localhost scripts/deploy.js 这里的deploy.js是hardhat自带的实例代码,可根据自己需要任意修改。在fork节点的控制台窗口中可以看到部署成功的合约地址日志信息。 仿照示例代码编写一个withdraw.js,并使用如下指令执行:const hre = require("hardhat"); async function main() { const Lock = await hre.ethers.getContractFactory("Lock"); const lock = await Lock.attach("0xcbbe2a5c3a22be749d5ddf24e9534f98951983e2") const tx = await lock.withdraw(); console.log(tx); } // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. main().catch((error) => { console.error(error); process.exitCode = 1; }); yarn hardhat run --network localhost scripts/withdraw.js 如果执行成功,可以看到执行结果输出,如果执行失败,可以看到失败的具体原因显示。如果有多层级的函数调用,在失败时,可以看到call-stack调用堆栈,方便定位问题所在位置。(注意:调用堆栈功能在remix中不可用)call-stack显示6. 详细参数配置通过修改hardhat.config.js可以对编译参数进行详细配置,包括但不限于网络信息、solidity版本与优化信息、部署账户信息等。module.exports = { defaultNetwork: "rinkeby", networks: { hardhat: { }, rinkeby: { url: "https://eth-rinkeby.alchemyapi.io/v2/123abc123abc123abc123abc123abcde", accounts: [privateKey1, privateKey2, ...] } }, solidity: { version: "0.5.15", settings: { optimizer: { enabled: true, runs: 200 } } }, paths: { sources: "./contracts", tests: "./test", cache: "./cache", artifacts: "./artifacts" }, mocha: { timeout: 40000 } } 参考链接https://hardhat.org/hardhat-network/docs/overview https://hardhat.org/hardhat-runner/docs/getting-started#overview ## Publication Information - [lolieatapple](https://paragraph.com/@lolieatapple/): Publication homepage - [All Posts](https://paragraph.com/@lolieatapple/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@lolieatapple): Subscribe to updates