在 Etherscan 上提交智能合約原始碼認證

  • FrankFrank
  • /
  • 10 分鐘閱讀
  • /
  • Nov 20, 2021
  • /
  • - views

這篇文章假設大家使用 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);
  });