Hardhat 提供了一個靈活且易于使用的開發環境,可以輕松地編寫、測試和部署智能合約。Hardhat還內置了Hardhat 網絡(Hardhat Node),它是為開發而設計的本地以太坊網絡。
下面是hardhat的官方文檔
https://hardhat.org/hardhat-runner/docs/getting-started
一、創建及配置Hardhat項目
Hardhat 構建在 Node.js 之上, 使用 Hardhat 要求我們在電腦先安裝好Node.js (>= 16.0),創建hardhat-tutorial文件夾。
1、初始化Node項目
2、安裝Hardhat?
?3、運行hardhat
用鍵盤選擇create a JavaScript project
生成project后的項目目錄?
二、編寫合約?
合約開發推薦使用 VSCode 編輯器 +?solidity 插件,在VSCode下添加solidity插件
在contracts
?文件夾下新建一個合約文件?Counter.sol
Counter.js代碼如下:?
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract Counter {uint counter;constructor() {counter = 0;}function count() public {counter = counter + 1;}function get() public view returns (uint) {return counter;}
}
?在編寫合約時,盡量不要重復造輪子,基于優質開源的第三方庫,不僅可以提高效率,還可以讓我們的合約代碼更安全,例如要開發一個 Token,可以用npm 安裝OpenZepplin 庫:
npm install @openzeppelin/contracts --save-dev
然后在合約中?import
?相應庫中的合約文件及可。
pragma solidity ^0.8.0;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";contract Token is ERC20 {constructor(uint256 initialSupply) ERC20("Token Name", "Token Symbol") {_mint(msg.sender, initialSupply);}
}
?三、編譯合約
hardhat.config.js
?有默認的Solidity 編譯器配置,因此我們直接編譯合約即可,在終端中運行?npx hardhat compile。
成功編譯后,會在?artifacts/contracts/
?目錄下生成Counter.json
?和 build-info,?Counter.json
包含了智能合約的 ABI 、字節碼(Bytecode)等
智能合約的ABI信息,包括了合約的函數、事件等接口信息。這個文件通常會與其他合約交互時使用,因為它可以被其他合約和DApp使用。
Bytecode是部署合約所需的字節碼,部署合約時候就是把該字節碼作為交易的輸入數據發送鏈上。
?四、編寫測試用例
為智能合約編寫自動化測試至關重要,因為事關用戶資金。
使用 Harhdat 內置的網絡,使用ethers.js與前面的合約進行交互,并使用?Mocha?作為測試運行器。在test文件夾下創建Counter.js文件代碼如下:
// 引入 Hardhat 提供的 ethers 庫,用于部署和交互智能合約
const { ethers } = require("hardhat");// 引入 chai 的斷言函數 expect,用于編寫測試判斷條件
const { expect } = require("chai");// 定義一個全局變量,用于存儲部署后的合約實例
let counter;// 定義測試套件,描述被測試的合約模塊為 "Counter"
describe("Counter", function () {// 初始化函數:部署 Counter 合約并獲取實例async function init() {// 獲取測試賬戶數組,其中 owner 是部署者,otherAccount 可用于后續擴展測試權限等const [owner, otherAccount] = await ethers.getSigners();// 獲取 Counter 合約工廠(ContractFactory),可以用來部署合約const Counter = await ethers.getContractFactory("Counter");// 部署合約并返回實例(此時合約已經部署完成,不需要調用 .deployed())counter = await Counter.deploy();// 打印部署后合約的地址(ethers v6 中使用 .target 屬性獲取地址)console.log("counter:" + counter.target);}// 所有測試用例運行前執行一次初始化操作(部署合約)before(async function () {await init();});// 第一個測試用例:測試合約初始值是否為 0it("init equal 0", async function () {// 調用 counter 合約的 get() 方法,斷言返回值為 0expect(await counter.get()).to.equal(0);});// 第二個測試用例:調用 count() 函數自增,驗證是否變為 1it("add 1 equal 1", async function () {// 調用 count() 方法進行加 1 操作let tx = await counter.count();// 等待交易被打包確認await tx.wait();// 調用 get() 方法獲取當前計數值,斷言為 1expect(await counter.get()).to.equal(1);});
});
運行npx hardhat test之后輸出全部通過,證明測試通過。?
還可以在Solidity代碼中調用console.log()
打印日志信息和合約變量,可以方便我們調試代碼。
在合約代碼中導入Hardhat?的console.log
就可以使用它。
?五、部署合約
部署合約我們需要編寫一個部署腳本。
在項目下新建scripts
文件夾,新建一個deploy.js
?用來寫部署腳本,代碼如下
const { ethers } = require("hardhat");async function main() {// 獲取合約工廠const Counter = await ethers.getContractFactory("Counter");// 部署合約(v6 會自動等待部署完成)const counter = await Counter.deploy();// 輸出部署的合約地址(v6 使用 counter.target)console.log("Counter address:", counter.target);
}main().catch((error) => {console.error(error);process.exitCode = 1;
});
運行?npx hardhat run scripts/deploy.js
?時,合約會部署到 Hardhat 內置網絡上。?
?為了在運行任何任務時指示Hardhat連接到特定的EVM網絡,可以使用--network
參數。
npx hardhat run scripts/deploy.js --network <network-name>
network-name
?需要在?hardhat.config.js
?文件中進行配置:
require("@nomicfoundation/hardhat-toolbox");// 填入自己的私鑰或助記詞,
const PRIVATE_KEY1 = "0x.... YOUR PRIVATE KEY1";
const PRIVATE_KEY2 = "0x.... YOUR PRIVATE KEY1";
const Mnemonic = "YOUR Mnemonic";module.exports = {solidity: "0.8.9", // solidity的編譯版本networks: {goerli: {url: "https://eth-goerli.api.onfinality.io/public",accounts: [PRIVATE_KEY1,PRIVATE_KEY2],chainId: 5,},mumbai: {url: "https://endpoints.omniatech.io/v1/matic/mumbai/public",accounts: {mnemonic: Mnemonic,},chainId: 80001,},}
};
以上配置了兩個網絡,一個是以太坊測試網?goerli
, 一個是 Polygon 測試網mumbai
, 我們可以在?https://chainlist.org?找到每個網絡的節點 URL 及 chainID。
在網絡配置中,需要提供提交交易賬號, 可以通過私鑰或助記詞
?進行配置,這里配置的賬號(需要提前充幣進入到賬號中),在hardhat 腳本中(測試及部署腳本)調用getSigners
?即可獲得:
const [owner, otherAccount] = await ethers.getSigners();
六、代碼開源驗證
智能代碼開源會增加了合約的透明度和可靠性,是項目建立信任很重要的一個步驟。
1、安裝?hardhat-toolbox
?或?hardhat-etherscan
?, 這一步我們這里已經完成,因為在初始化項目的時候安裝了?hardhat-toolbox
?, 如果沒有安裝,可以使用以下命令安裝
npm install --save-dev @nomiclabs/hardhat-etherscan
2、在hardhat.config.js
?中配置您的 Etherscan API 密鑰和網絡設置,例如:?
require("@nomicfoundation/hardhat-toolbox");或// require("@nomiclabs/hardhat-etherscan");etherscan: {apiKey: ""},
?如何獲取 Etherscan API 密鑰?
1. 訪問部署網絡對應主網的 Etherscan 網站,并注冊一個賬號(如果還沒有賬號的話)。
2. 登錄你的賬號并進入 Etherscan 的「我的帳戶」頁面。
3. 點擊頁面左側的「API-KEYs」標簽頁。
4. 在頁面上方的「Create New API KEY」部分,輸入 API 密鑰的名稱和描述,然后選擇需要訪問的 API 權限。
5. 點擊「Generate」按鈕來生成 API 密鑰。
?
3、執行驗證命令:
npx hardhat verify <deployed-contract-address> "參數(若有)" --network <network-name>
該命令會為我們上傳合約代碼并驗證其源代碼。如果一切順利(網絡順暢的話),在 Etherscan 上看到的合約被成功驗證。