Decert.me 要連載教程了, 《Solidity 開發教程》 力求系統、深入的介紹 Solidity 開發, 同時這是一套互動式教程,你可以實時的修改教程里的合約代碼并運行,
本教程來自貢獻者 @Tiny熊,讓我們正式開始學習吧,
如果你已經是 Hardhat 的使用者,可以直接跳到文末,參與挑戰領取技能認證 NFT,
Hardhat 提供了一個靈活且易于使用的環境,可以輕松地撰寫、測驗和部署智能合約,類似的開發工具或框架還有: Remix IDE, Truffle , Foundry, 目前最受歡迎的是 Hardhat 與 Foundry,
Hardhat 使用 Node 進行包管理,如果你熟悉 Node 及 Javascript, Hardhat 將非常簡單上手,
Hardhat還內置了Hardhat 網路(Hardhat Node),它是為開發而設計的本地以太坊網路, 用來部署合約,運行測驗和除錯代碼,
在本文中,我們將介紹:
- 創建及配置Hardhat專案
- 撰寫智能合約
- Hardhat 編譯合約
- 使用 Ethers.js 和為合約撰寫自動化測驗
- 使用
console.log()
除錯 Solidity - 使用 Hardhat 部署合約
- 使用 Hardhat Etherscan 進行開源驗證,
- Hardhat 插件的使用
本文對應的代碼在:https://github.com/xilibi2003/training_camp_2/tree/main/w1_hardhat
創建及配置Hardhat專案
Hardhat 構建在Node.js之上, 使用 Hardhat 要求我們在電腦先安裝好Node.js (>= 16.0), 環境準備可以參考這里,
先創建專案目錄:
mkdir hardhat-tutorial
cd hardhat-tutorial
初始化 Node 專案:
npm init
安裝 Hardhat :
npm install --save-dev hardhat
在安裝Hardhat的目錄下運行:
npx hardhat
使用鍵盤選擇"創建一個新的hardhat.config.js(Create a JavaScript project
)" ,然后回車,
$ npx hardhat
888 888 888 888 888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888
?? Welcome to Hardhat v2.13.0 ???
? What do you want to do? …
? Create a JavaScript project
Create a TypeScript project
Create an empty hardhat.config.js
Quit
這個 JavaScript Hardhat 工程會默認下載 hardhat-toolbox 插件
及一些常規設定:
創建好的Hardhat工程包含檔案有:
contracts
:智能合約目錄scripts
:部署腳本檔案test
:智能合約測驗用例檔案夾,hardhat.config.js
:組態檔,配置hardhat連接的網路及編譯選項,
撰寫合約
合約開發推薦使用 VSCode 編輯器 + solidity 插件,在contracts
下新建一個合約檔案 Counter.sol
(*.sol
是 Solidity 合約檔案的后綴名), 復制如下代碼:
//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;
}
}
接下來就可以編譯這個合約了,
使用OpenZepplin 等第三方庫
在撰寫合約時,盡量不要重復造輪子,基于優質開源的第三方庫,不僅可以提交效率,還可以讓我們的合約代碼更安全,例如要開發一個 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 編譯器配置:
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.18",
};
因此我們直接編譯合約即可,在終端中運行 npx hardhat compile
, compile
任務是內置任務之一,
$ npx hardhat compile
Compiling 1 file with 0.8.18
Compilation finished successfully
合約已成功編譯了,
成功編譯后,會在 artifacts/contracts/
目錄下生成Counter.json
和 build-info, Counter.json
包含了智能合約的 ABI 、位元組碼(Bytecode)等,
:::tip
智能合約的 ABI(Application Binary Interface)資訊,其中包括了合約的函式、事件等介面資訊,這個檔案通常會在與其他合約互動時使用,因為它可以被其他合約和 DApp 使用,
Bytecode
是部署合約所需的位元組碼(也稱為創建時位元組碼),部署合約時,就是把該位元組碼作為交易的輸入資料發送鏈上,:::
:::
撰寫測驗用例
為智能合約撰寫自動化測驗至關重要,因為事關用戶資金,
在我們的測驗中,使用 Harhdat 內置的網路,使用ethers.js與前面的合約進行互動,并使用 Mocha 作為測驗運行器,
在專案 test
下,并創建一個名為Counter.js
的新檔案:
const { ethers } = require("hardhat");
const { expect } = require("chai");
let counter;
describe("Counter", function () {
async function init() {
const [owner, otherAccount] = await ethers.getSigners();
const Counter = await ethers.getContractFactory("Counter");
counter = await Counter.deploy();
await counter.deployed();
console.log("counter:" + counter.address);
}
before(async function () {
await init();
});
//
it("init equal 0", async function () {
expect(await counter.get()).to.equal(0);
});
it("add 1 equal 1", async function () {
let tx = await counter.count();
await tx.wait();
expect(await counter.get()).to.equal(1);
});
});
在終端上運行npx hardhat test
, 你應該看到以下輸出:
> npx hardhat test
Counter
counter:0x5FbDB2315678afecb367f032d93F642f64180aa3
? init equal 0
? add 1 equal 1
2 passing (1s)
這意味著測驗通過了, 現在我們解釋主要代碼:
const Counter = await ethers.getContractFactory("Counter");
ethers.js中的ContractFactory
是用于部署新智能合約的抽象,因此此處的Counter
是用來實體合約的工廠,
counter = await Counter.deploy();
在ContractFactory
上呼叫deploy()
將啟動部署,并回傳決議為Contract
的Promise
, 該物件包含了智能合約所有函式的方法,
let tx = await counter.count();
await tx.wait();
在counter
上呼叫合約方法, 并等待交易執行完畢,
注意,默認情況下, ContractFactory
和Contract
實體連接到第一個簽名者(Singer),
若需要使用其他的簽名這, 可以使用合約實體connect 到另一個簽名者, 如 counter.connect(otherAccount)
expect(await counter.get()).to.equal(0);
判斷相等,我們使用Chai,這是一個斷言庫, 這些斷言函式稱為“匹配器”,在此實際上使用的“匹配器”來自Hardhat Chai Matchers,
使用 Console.log 除錯合約
在**Hardhat Node **節點上運行合約和測驗時,你可以在Solidity代碼中呼叫console.log()
列印日志資訊和合約變數,可以方便我們除錯代碼,
在合約代碼中匯入**Hardhat **的console.log
就可以使用它,
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract Counter {
uint public counter;
constructor(uint x) {
counter = x;
}
function count() public {
counter = counter + 1;
console.log("counter is %s ", counter);
}
}
就像在JavaScript中使用一樣, 將一些console.log
添加函式中,運行測驗時,將輸出日志記錄:
> npx hardhat test
Counter
counter:0x5FbDB2315678afecb367f032d93F642f64180aa3
? init equal 0
counter is 1
? add 1 equal 1 (38ms)
2 passing (1s)
可以在這里了解更多 console.log ,
部署合約
其實我們在測驗時, 合約已經部署到了Hardhat 內置的網路上,部署合約我們需要撰寫一個部署腳本,
在scripts
檔案夾,新建一個deploy.js
用來寫部署腳本,部署腳本其實和前面測驗時 init
函式類似:
const { ethers } = require("hardhat");
async function main() {
const Counter = await ethers.getContractFactory("Counter");
const counter = await Counter.deploy();
await counter.deployed();
console.log("Counter address:", counter.address);
}
main();
運行 npx hardhat run scripts/deploy.js
時, 可以合約會部署到Hardhat 內置網路上,
> npx hardhat run scripts/deploy.js
Counter address: 0x5FbDB2315678afecb367f032d93F642f64180aa3
為了在運行任何任務時指示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();
一個私鑰對應一個Singer,助記詞則對應無數個 Singer , 為每個專案生成一個獨立的賬號是比較推薦的做法,使用 ChainTool 開源工具 可以生成賬號,
:::tip
助記詞可以推匯出無數了私鑰,可參考:BIP39
:::
另外要注意, 在 Goerli 上進行部署,需要將Goerli-ETH發送到將要進行部署的地址中, 可以從水龍頭免費或一些測驗幣,這是Goerli的一個水龍頭:
- Alchemy Goerli Faucet
最后運行:
npx hardhat run scripts/deploy.js --network goerli
如果一切順利,你應該看到已部署的合約地址,
代碼開源驗證
智能代碼開源會增加了合約的透明度和可靠性,是專案建立信任很重要的一個步驟,
在 hardhat-toolbox
工具箱里,包含了 hardhat-etherscan 插件用于驗證已經部署到區塊鏈網路上的智能合約代碼與源代碼是否匹配,在完成驗證后在區塊鏈瀏覽器中合約標簽上會出現?, 如圖:
在部署智能合約時,合約位元組碼會被寫入到區塊鏈中,這意味著其他人無法檢查合約的源代碼,代碼驗證的程序是將已部署合約的位元組碼與原始Solidity代碼再次編譯后與部署的位元組碼進行比較,確保它們是一致的,
相比在區塊鏈瀏覽器上上傳代碼驗證, hardhat-etherscan 有很多優點,否則會自動使用 hardhat config 值設定的編譯器選項,并且當代碼中參考的第三方庫或合約, hardhat-etherscan 能自動探測并處理,
開源驗證的步驟是:
-
安裝
hardhat-toolbox
或hardhat-etherscan
, 這一步我們這里已經完成,因為在初始化專案的時候安裝了hardhat-toolbox
, 如果沒有安裝,可以使用以下命令安裝npm install --save-dev @nomiclabs/hardhat-etherscan
-
在
hardhat.config.js
中配置您的 Etherscan API 密鑰和網路設定,例如:
require("@nomicfoundation/hardhat-toolbox");
或
// require("@nomiclabs/hardhat-etherscan");
etherscan: {
apiKey: ""
},
如何獲取 Etherscan API 密鑰?
- 訪問部署網路對應主網的 Etherscan 網站,并注冊一個賬號(如果還沒有賬號的話),
- 登錄你的賬號并進入 Etherscan 的「我的帳戶」頁面,
- 點擊頁面左側的「API-KEYs」標簽頁,
- 在頁面上方的「Create New API KEY」部分,輸入 API 密鑰的名稱和描述,然后選擇需要訪問的 API 權限,
- 點擊「Generate」按鈕來生成 API 密鑰,
-
執行驗證命令:
npx hardhat verify <deployed-contract-address> "引數(若有)" --network <network-name>
例如,要在 goerli 網路上驗證合約,可以運行以下命令:
npx hardhat verify 0x..... --network goerli
該命令會為我們上傳合約代碼并驗證其源代碼,如果一切順利(網路順暢的話),在 Etherscan 上看到的合約被成功驗證,
Hardhat 插件(Plugin)的使用
上面代碼開源驗證時,使用了hardhat-etherscan
插件,其實也可以使用 hardhat-verify 插件,
在 https://hardhat.org/hardhat-runner/plugins 鏈接可以找到當前使用較多的插件,例如:hardhat-gas-reporter 可以對部署合約及函式執行的Gas消耗給出報告;solidity-coverage 可以對測驗覆寫率給出報告,
要使用一個插件通常要:
-
用 Node.js 包管理先安裝相應的插件
-
在 hardhat.config.js 檔案中引入插件,以便Hardhat 能加載上對應的插件,
參考檔案
示例非常簡單, 更多使用方法,可參考檔案:
-
Hardhat 官方檔案:https://hardhat.org/getting-started/
-
Hardhat 中文檔案:https://learnblockchain.cn/docs/hardhat/getting-started/
-
Harhdat 入門教程:https://learnblockchain.cn/docs/hardhat/tutorial/
-
Ethers.js 檔案:https://learnblockchain.cn/ethers_v5/
小結
本文介紹了 Hardhat 開發框架的一些基本概念和使用方法,了解了如何使用 Hardhat 進行合約編譯、部署、除錯及測驗,在開發中要經常查看檔案,了解更多Hardhat 用法,
Hardhat 的使用你掌握了嗎?來這里挑戰一下看看,挑戰完成你就可以領取到一枚技能認證 NFT,
原教程鏈接:https://decert.me/tutorial/solidity/tools/hardhat
Decert.me -- 碼一個未來
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/552221.html
標籤:區塊鏈
上一篇:波場(Tron) 網頁版錢包開源
下一篇:返回列表