智能合約開發測試部署驗證一條龍

前面提到,我最近在看 Web3,這不記錄下最近看到的好玩的。

忘了在哪里看到的一句話,Web3 這個東西,剛看時讓人摸不到頭腦的點在于,你很難知道要用哪些東西去組裝,去哪里拿數據。

比如都說區塊鏈人人可訪問,我要到哪里看到它?畢竟看得見的東西更讓人心安。

給俺瞧瞧。

我到哪里去看區塊鏈上的數據?不給你 區塊鏈瀏覽器 這個關鍵詞,大概很難知曉。

一個經常會看到的疑問是如何與合約交互,比如,合約里存了一個字符串,我現在要將其展示到頁面上,如何搞?

這玩意是去中心化的呀,沒有一個 API 地址讓你去連呀,于是就迷茫了。。。

。。。
。。。
。。。

其實 Web3 里的很多東西,就是一張紙,沒啥,與智能合約交互其實就是要和節點交互,但維護全節點也太難受了。

那么就換一種方案就是使用別人維護的節點,其實就是連接輕節點提供商,比如 MetaMask 或者 Alchemy,當然了,這里有去中心化的取舍了。

廢話說完了,進入正題。


通過使用 Hardhat Alchemy Solidity 來走一下智能合約開發部署流程。

  • Hardhat 創建項目
  • 實現一個 Hello World 智能合約
  • mocha 來測試合約
  • 如何將合約部署到區塊網絡
  • 如何驗證已經部署的合約

1. 環境搭建

前提條件,前端常用的環境 node 就不多說了。

打開 Hardhat 官網,照著文檔一把梭,把它當成一個幫你創建合約項目的一個腳手架就完了。

https://hardhat.org/

注意,Hardhat 更新很快,一些教程可能不是很準確,沒事看看官網文檔就好了。

npx hardhat

下面是執行時終端輸出:

cemcoe@cemcoe MINGW64 ~/workplace/web3gogogo/contracts (main)
$ npx hardhat
Need to install the following packages:
  hardhat
Ok to proceed? (y) y
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.10.2

? What do you want to do? ...      
> Create a JavaScript project      
  Create a TypeScript project      
  Create an empty hardhat.config.js
  Quit

選擇 Create a JavaScript project,并回車。注意,按照輸出,這里還需要裝點東西:

cemcoe@cemcoe MINGW64 ~/workplace/web3gogogo/contracts (main)
$ npx hardhat
Need to install the following packages:
  hardhat
Ok to proceed? (y) y
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.10.2

√ What do you want to do? · Create a JavaScript project
√ Hardhat project root: · C:\Users\cemcoe\workplace\web3gogogo\contracts
√ Do you want to add a .gitignore? (Y/n) · y

You need to install these dependencies to run the sample project:
  npm install --save-dev "hardhat@^2.10.2" "@nomicfoundation/hardhat-toolbox@^1.0.1"

Project created

See the README.md file for some example tasks you can run

Give Hardhat a star on Github if you're enjoying it!

     https://github.com/NomicFoundation/hardhat

聽話,按照它說的做,把依賴都裝上:

npm install --save-dev "hardhat@^2.10.2" "@nomicfoundation/hardhat-toolbox@^1.0.1"

基本環境就好了,可以開心寫合約玩了。

2. 看下目錄

哦,天呀,小寶貝,打開目錄看一下吧。

目錄結構

國際慣例,寫個 HelloWorld 先。

到 contracts 目錄下按照 Lock.sol 來畫 HelloWorld,這個文件要盡可能簡單,現在的重點在于合約的編譯部署和驗證。
合約大概長這樣:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract HelloWorld {
    string public _string = "Hello, World! My Name is cemcoe!";
}

好了,合約不用管了,畢竟不是本文的重點。

3. 寫個測試

下面為合約寫個測試,不同于前端,合約的安全是重重重重點,畢竟里面存的是資產,測試就不能少了。

https://hardhat.org/hardhat-runner/docs/guides/test-contracts

這里測試是 Chai 和 Mocha 提供的能力,需要注意的是 chai 僅僅是一個assertion library,不是JavaScript test framework。

下面代碼中的 describe 以及 it 并不是由 chai 提供的,所以在 chai 的官網你是找不到這倆貨的,我在 chai 的官網找半天it。。。

到 test 下創建同名文件來測試一下合約,測試寫完那就運行一下。

主要是下面的代碼沒有 mocha 的影子,但其實 Hardhat 的文檔里有提到。

const {
  time,
  loadFixture,
} = require("@nomicfoundation/hardhat-network-helpers");
const { expect } = require("chai");
// chai 僅僅是一個assertion library,不是JavaScript test framework
// 下面describe以及it并不是由chai提供的,所以在chai的官網你是找不到這倆貨的
// https://mochajs.org/
// 比起簡單的語法,上面的認知還是蠻重要的

describe("HelloWorld", function () {
  // We define a fixture to reuse the same setup in every test.
  // We use loadFixture to run this setup once, snapshot that state,
  // and reset Hardhat Network to that snapshot in every test.
  async function deployOneYearLockFixture() {
    // Contracts are deployed using the first signer/account by default
    const [owner] = await ethers.getSigners();

    const CONTRACT = await ethers.getContractFactory("HelloWorld");
    const contract = await CONTRACT.deploy();

    return { contract, owner };
  }

  describe("Deployment", function () {
    it("Should set the right string", async function () {
      const { contract } = await loadFixture(deployOneYearLockFixture);

      expect(await contract._string()).to.equal(
        "Hello, World! My Name is cemcoe!"
      );
    });
  });
});


運行一下測試腳本

$ npx hardhat test ./test/0.HelloWorld.test.js
Compiled 3 Solidity files successfully


  HelloWorld
    Deployment
      ? Should set the right string (3150ms)


  1 passing (3s)

bingo,測試完成。

4. 部署到測試網絡

目前為止,其實一直是關上門稱王稱霸,現在將合約發布到測試網絡吧。

這里要找一個服務商,幫忙上鏈,什么,你不想要中間商,嗯,把握重點吧伙計。

到這里 https://www.alchemy.com/ 注冊一個賬號拿到key,并將相應信息配置到hardhat.config.js 文件中,像下面這樣:

networks: {
  goerli: {
    url: GOERLI_URL,
    accounts: [PRIVATE_KEY],
  },
  polygonMumbai: {
    url: process.env.MUMBAI_URL,
    accounts: [process.env.PRIVATE_KEY],
  },
  optimismGoerli: {
    url: OPTIMISM_GOERLI_URL,
    accounts: [PRIVATE_KEY],
  },
},

當然,我這里用了一下 dotenv 來存敏感信息,為了體驗編譯部署流程可以直接寫死在文件中。

你可以只配置一個網絡,比如 polygonMumbai,其中 MUMBAI_URL 是申請的URL,而 PRIVATE_KEY 是你錢包地址的私鑰,做好自己的風險控制,別把自己存有資產的錢包密鑰泄露。

配置文件搞好以后就來寫一個部署腳本好了。其實很簡單。

const hre = require("hardhat");

async function main() {
  const CONTRACT = await hre.ethers.getContractFactory("HelloWorld");
  const contract = await CONTRACT.deploy();

  await contract.deployed();

  console.log(`contract deployed to ${contract.address}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

核心代碼就三句。。。

配置文件和部署腳本都寫好以后就可以開始部署了。

npx hardhat run scripts/0.HelloWorld.deploy.js --network polygonMumbai
$ npx hardhat run scripts/0.HelloWorld.deploy.js --network polygonMumbai
Compiled 1 Solidity file successfully
contract deployed to 0x8487Ec50f29d1d36Cb422d6f45AA1ef38Cd2bBA2

5. 驗證合約

驗證合約的目的是讓合約代碼在區塊瀏覽器上可讀。

和部署合約類似要先寫一下申請賬號,再配置文件,然后運行腳本,一步一步來。

先到對應的區塊瀏覽器去申請key,這里是 https://mumbai.polygonscan.com/

然后將key配置到hardhat.config.js文件中。

 etherscan: {
    apiKey: {
      goerli: process.env.ETHERSCAN_API_KEY,
      polygonMumbai: process.env.POLYGONSCAN_API_KEY,
      // optimismGoerli 不在默認配置中
      optimismGoerli: "abc",
    },
  },

當然了,仍然是按需配置,需要什么網絡就到對應的區塊瀏覽器去拿key再配置進去。

有了key,配置文件,再加上部署的合約的地址,就可以驗證合約了。

npx hardhat verify --network polygonMumbai 0x8487Ec50f29d1d36Cb422d6f45AA1ef38Cd2bBA2

一條龍完成。


$ npx hardhat verify --network polygonMumbai 0x8487Ec50f29d1d36Cb422d6f45AA1ef38Cd2bBA2
Nothing to compile
Successfully submitted source code for contract
contracts/0.HelloWorld.sol:HelloWorld at 0x8487Ec50f29d1d36Cb422d6f45AA1ef38Cd2bBA2
for verification on the block explorer. Waiting for verification result...

Successfully verified contract HelloWorld on Etherscan.
https://mumbai.polygonscan.com/address/0x8487Ec50f29d1d36Cb422d6f45AA1ef38Cd2bBA2#code
bigo

注意, goerli 或其它網絡驗證合約時,因網絡原因會出現 Error in plugin @nomiclabs/hardhat-etherscan: Failed to send contract verification request. 的情況。

$ npx hardhat verify --network goerli 0x7520A14646eF8d8123e88937DcB39604E8E70CeA
Nothing to compile
Error in plugin @nomiclabs/hardhat-etherscan: Failed to send contract verification request.
Endpoint URL: https://api-goerli.etherscan.io/api
Reason: Connect Timeout Error
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容