這篇文章假設大家使用 hardhat 來進行智能合約開發。關於 hardhat 我有時間再詳細寫一寫懶人教學 😅。
大家如果常去 Etherscan 上查看智能合約 Smart Contract, 大概會看到兩種情況,第一種是如下這樣,在 Contract 下面看到是一堆「亂碼」,這堆「亂碼」其實是編譯過後的智能合約 ByteCode (字節碼),這明顯不是給人類閱讀的。
另一種則是如下圖所示,在 Contract Tab 旁邊能夠看到一個綠色的✓,下面能夠看到智能合約的原始代碼,並且可以直接在 Etherscan 上讀取,調用智能合約的 function。
明顯第二種合約給人的感覺會自信很多, 因為所有人都能夠清楚看到智能合約具體的運行邏輯,一切公開透明,不怕「黑箱作業」。
那麼如何做到在 Etherscan 上「開放原始碼」呢?
一種方法是手動在 Etherscan 上提交原始碼,透過提交智能合約的地址,選擇編譯器版本,上載智能合約的原始碼等等一系列步驟之後便可以做到。
但這種方法的壞處是非常麻煩,要確保選對編譯器版本,上載所有需要上載的檔案,包括一些第三方的 library。一旦上載的原始碼檔案出現錯漏,則無法完成認證。
有沒有更好的方法呢?
隆重介紹 @nomiclabs/hardhat-etherscan
使用 @nomiclabs/hardhat-etherscan 這個 npm package,能夠超級簡單的完成智能合約認證。這個 package 集成了 Etherscan 的 API,透過 API 的形式自動完成原始碼認證,免去了繁瑣的手動步驟。
第一步
首先我們需要在 Etherscan 上有一個賬戶,然後免費申請一個 API key。 按此前往。
在上述頁面中按下「ADD」即可申請一個全新的 API Key。得到這個 API Key 之後,將它放入你的 .env 檔案中。(假設你用 .env 檔案來保存環境變數)
API_URL = xxx
PUBLIC_KEY = xxx
PRIVATE_KEY = xxx
ETHERSCAN_API_KEY = 這裡填上你上面得到的 API Key
第二步
安裝 @nomiclabs/hardhat-etherscan
, 使用 npm 或者 yarn 的方式安裝。這個應該不用多說了吧,是人都會了。
yarn add @nomiclabs/hardhat-etherscan -D
第三步
現在我們需要設定 hardhat.config.js
。
首先,要在 hardhat.config.js
頂部引入這個 package
require("@nomiclabs/hardhat-etherscan");
然後,在 hardhat.config.js
添加如下設定:
module.exports = {
solidity: "0.8.4",
networks: {
rinkeby: { xxx }, // xxx 是省略的意思哦,你應該不會照抄吧 😒
},
etherscan: {
// 下面這個就是 Etherscan 的 API Key 哦
// 和上面第一步中 .env 檔案中的對應
apiKey: process.env.ETHERSCAN_API_KEY
}
};
第四步
在完成智能合約編譯後,透過以下指令即可驗證智能合約原始碼:
npx hardhat verify --network rinkeby <你的已發佈智能合約地址>
舉例:
frank@MacBook demo % hh compile
Compiling 1 files with 0.8.4
Compilation finished successfully
frank@MacBook demo % npx hardhat run --network rinkeby scripts/DeployDemo.js
Deploying demo contract ...
Waiting for 2 confirmations...
Contract deployed to: 0x4451ED9cD559Ac5e552c7AD757a642Af533EbD88
frank@MacBook demo % npx hardhat verify --network rinkeby 0x4451ED9cD559Ac5e552c7AD757a642Af533EbD88
Nothing to compile
Compiling 1 file with 0.8.4
Successfully submitted source code for contract
contracts/Demo.sol:Demo at 0x4451ED9cD559Ac5e552c7AD757a642Af533EbD88
for verification on Etherscan. Waiting for verification result...
Successfully verified contract Demo on Etherscan.
https://rinkeby.etherscan.io/address/0x4451ED9cD559Ac5e552c7AD757a642Af533EbD88#code
至此,打開 Etherscan ,就可以看到我們的智能合約已經認證成功啦。
DeployDemo.js 參考:
const { ethers } = require("hardhat")
async function main() {
console.info(`Deploying demo contract ... `)
const Demo = await ethers.getContractFactory("Demo");
const demo = await Demo.deploy();
console.info(`Waiting for 2 confirmations...`)
let transcation = demo.deployTransaction
const receipt = await transcation.wait(2)
const { gasUsed } = receipt
console.log("Contract deployed to: ", demo.address);
console.info(`Gas used : ${gasUsed} `)
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});