智能合约开发测试部署验证一条龙

前面提到,我最近在看 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,538评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,800评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,329评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,725评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,089评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,449评论 1 212
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,758评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,448评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,152评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,432评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,933评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,289评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,921评论 3 234
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,023评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,781评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,477评论 2 270
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,381评论 2 263

推荐阅读更多精彩内容