智能合約開(kāi)發(fā)測(cè)試部署驗(yàn)證一條龍

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

忘了在哪里看到的一句話扎筒,Web3 這個(gè)東西,剛看時(shí)讓人摸不到頭腦的點(diǎn)在于涣仿,你很難知道要用哪些東西去組裝勤庐,去哪里拿數(shù)據(jù)。

比如都說(shuō)區(qū)塊鏈人人可訪問(wèn)好港,我要到哪里看到它愉镰?畢竟看得見(jiàn)的東西更讓人心安。

給俺瞧瞧钧汹。

我到哪里去看區(qū)塊鏈上的數(shù)據(jù)凰兑?不給你 區(qū)塊鏈瀏覽器 這個(gè)關(guān)鍵詞寞缝,大概很難知曉。

一個(gè)經(jīng)常會(huì)看到的疑問(wèn)是如何與合約交互,比如桩警,合約里存了一個(gè)字符串,我現(xiàn)在要將其展示到頁(yè)面上哄陶,如何搞琳省?

這玩意是去中心化的呀,沒(méi)有一個(gè) API 地址讓你去連呀嗤形,于是就迷茫了精偿。。。

笔咽。搔预。。
叶组。拯田。。
甩十。船庇。。

其實(shí) Web3 里的很多東西侣监,就是一張紙鸭轮,沒(méi)啥,與智能合約交互其實(shí)就是要和節(jié)點(diǎn)交互橄霉,但維護(hù)全節(jié)點(diǎn)也太難受了窃爷。

那么就換一種方案就是使用別人維護(hù)的節(jié)點(diǎn),其實(shí)就是連接輕節(jié)點(diǎn)提供商姓蜂,比如 MetaMask 或者 Alchemy按厘,當(dāng)然了,這里有去中心化的取舍了钱慢。

廢話說(shuō)完了逮京,進(jìn)入正題。


通過(guò)使用 Hardhat Alchemy Solidity 來(lái)走一下智能合約開(kāi)發(fā)部署流程滩字。

  • Hardhat 創(chuàng)建項(xiàng)目
  • 實(shí)現(xiàn)一個(gè) Hello World 智能合約
  • mocha 來(lái)測(cè)試合約
  • 如何將合約部署到區(qū)塊網(wǎng)絡(luò)
  • 如何驗(yàn)證已經(jīng)部署的合約

1. 環(huán)境搭建

前提條件造虏,前端常用的環(huán)境 node 就不多說(shuō)了。

打開(kāi) Hardhat 官網(wǎng)麦箍,照著文檔一把梭漓藕,把它當(dāng)成一個(gè)幫你創(chuàng)建合約項(xiàng)目的一個(gè)腳手架就完了。

https://hardhat.org/

注意挟裂,Hardhat 更新很快享钞,一些教程可能不是很準(zhǔn)確,沒(méi)事看看官網(wǎng)文檔就好了诀蓉。

npx hardhat

下面是執(zhí)行時(shí)終端輸出:

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栗竖,并回車(chē)。注意渠啤,按照輸出狐肢,這里還需要裝點(diǎn)東西:

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

聽(tīng)話,按照它說(shuō)的做沥曹,把依賴(lài)都裝上:

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

基本環(huán)境就好了份名,可以開(kāi)心寫(xiě)合約玩了碟联。

2. 看下目錄

哦,天呀僵腺,小寶貝鲤孵,打開(kāi)目錄看一下吧。

目錄結(jié)構(gòu)

國(guó)際慣例辰如,寫(xiě)個(gè) HelloWorld 先普监。

到 contracts 目錄下按照 Lock.sol 來(lái)畫(huà) HelloWorld,這個(gè)文件要盡可能簡(jiǎn)單琉兜,現(xiàn)在的重點(diǎn)在于合約的編譯部署和驗(yàn)證凯正。
合約大概長(zhǎng)這樣:

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

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

好了,合約不用管了呕童,畢竟不是本文的重點(diǎn)漆际。

3. 寫(xiě)個(gè)測(cè)試

下面為合約寫(xiě)個(gè)測(cè)試,不同于前端夺饲,合約的安全是重重重重點(diǎn),畢竟里面存的是資產(chǎn)施符,測(cè)試就不能少了往声。

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

這里測(cè)試是 Chai 和 Mocha 提供的能力,需要注意的是 chai 僅僅是一個(gè)assertion library戳吝,不是JavaScript test framework浩销。

下面代碼中的 describe 以及 it 并不是由 chai 提供的,所以在 chai 的官網(wǎng)你是找不到這倆貨的听哭,我在 chai 的官網(wǎng)找半天it慢洋。。陆盘。

到 test 下創(chuàng)建同名文件來(lái)測(cè)試一下合約普筹,測(cè)試寫(xiě)完那就運(yùn)行一下。

主要是下面的代碼沒(méi)有 mocha 的影子隘马,但其實(shí) Hardhat 的文檔里有提到太防。

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

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!"
      );
    });
  });
});


運(yùn)行一下測(cè)試腳本

$ 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,測(cè)試完成幔嗦。

4. 部署到測(cè)試網(wǎng)絡(luò)

目前為止酿愧,其實(shí)一直是關(guān)上門(mén)稱(chēng)王稱(chēng)霸,現(xiàn)在將合約發(fā)布到測(cè)試網(wǎng)絡(luò)吧邀泉。

這里要找一個(gè)服務(wù)商嬉挡,幫忙上鏈钝鸽,什么,你不想要中間商棘伴,嗯寞埠,把握重點(diǎn)吧伙計(jì)。

到這里 https://www.alchemy.com/ 注冊(cè)一個(gè)賬號(hào)拿到key焊夸,并將相應(yīng)信息配置到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],
  },
},

當(dāng)然,我這里用了一下 dotenv 來(lái)存敏感信息阱穗,為了體驗(yàn)編譯部署流程可以直接寫(xiě)死在文件中饭冬。

你可以只配置一個(gè)網(wǎng)絡(luò),比如 polygonMumbai揪阶,其中 MUMBAI_URL 是申請(qǐng)的URL昌抠,而 PRIVATE_KEY 是你錢(qián)包地址的私鑰,做好自己的風(fēng)險(xiǎn)控制鲁僚,別把自己存有資產(chǎn)的錢(qián)包密鑰泄露炊苫。

配置文件搞好以后就來(lái)寫(xiě)一個(gè)部署腳本好了。其實(shí)很簡(jiǎn)單冰沙。

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;
});

核心代碼就三句侨艾。。拓挥。

配置文件和部署腳本都寫(xiě)好以后就可以開(kāi)始部署了唠梨。

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. 驗(yàn)證合約

驗(yàn)證合約的目的是讓合約代碼在區(qū)塊瀏覽器上可讀。

和部署合約類(lèi)似要先寫(xiě)一下申請(qǐng)賬號(hào)侥啤,再配置文件当叭,然后運(yùn)行腳本,一步一步來(lái)盖灸。

先到對(duì)應(yīng)的區(qū)塊瀏覽器去申請(qǐng)key蚁鳖,這里是 https://mumbai.polygonscan.com/

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

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

當(dāng)然了糠雨,仍然是按需配置才睹,需要什么網(wǎng)絡(luò)就到對(duì)應(yīng)的區(qū)塊瀏覽器去拿key再配置進(jìn)去。

有了key甘邀,配置文件琅攘,再加上部署的合約的地址,就可以驗(yàn)證合約了松邪。

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 或其它網(wǎng)絡(luò)驗(yàn)證合約時(shí)逗抑,因網(wǎng)絡(luò)原因會(huì)出現(xiàn) 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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寒亥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子荧关,更是在濱河造成了極大的恐慌溉奕,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忍啤,死亡現(xiàn)場(chǎng)離奇詭異加勤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)同波,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)鳄梅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人未檩,你說(shuō)我怎么就攤上這事戴尸。” “怎么了冤狡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵孙蒙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我悲雳,道長(zhǎng)马篮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任怜奖,我火速辦了婚禮,結(jié)果婚禮上翅阵,老公的妹妹穿的比我還像新娘歪玲。我一直安慰自己,他們只是感情好掷匠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布滥崩。 她就那樣靜靜地躺著,像睡著了一般讹语。 火紅的嫁衣襯著肌膚如雪钙皮。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,954評(píng)論 1 283
  • 那天顽决,我揣著相機(jī)與錄音短条,去河邊找鬼。 笑死才菠,一個(gè)胖子當(dāng)著我的面吹牛茸时,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赋访,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼可都,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缓待!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起渠牲,我...
    開(kāi)封第一講書(shū)人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旋炒,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后签杈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體瘫镇,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年芹壕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汇四。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踢涌,死狀恐怖通孽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睁壁,我是刑警寧澤背苦,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站潘明,受9級(jí)特大地震影響行剂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钳降,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一厚宰、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遂填,春花似錦铲觉、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至礁击,卻和暖如春盐杂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哆窿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工链烈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人更耻。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓测垛,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親秧均。 傳聞我的和親對(duì)象是個(gè)殘疾皇子食侮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容