7.区块链系列之hardhat框架部署合约

先前讲解的本地部署只能合约的方式编码较多,现在我们介绍目前比较流行的智能合约框架hardhat

1. 环境准备

yarn init
yarn add --dev hardhat
yarn hardhat
npm install --save-dev @nomicfoundation/hardhat-toolbox

2. 新建并编译SimpleStorage.sol

  • 在hardhat框架conracts目录下新建SimpleStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.8;

contract SimpleStorage {
    uint256 favoriteNumber;

    struct People {
        uint256 favoriteNumber;
        string name;
    }

    // uint256[] public anArray;
    People[] public people;

    mapping(string => uint256) public nameToFavoriteNumber;

    function store(uint256 _favoriteNumber) public {
        favoriteNumber = _favoriteNumber;
    }

    function retrieve() public view returns (uint256) {
        return favoriteNumber;
    }

    function addPerson(string memory _name, uint256 _favoriteNumber) public {
        people.push(People(_favoriteNumber, _name));
        nameToFavoriteNumber[_name] = _favoriteNumber;
    }
}
  • 修改配置文件solidity版本为0.8.8
module.exports = {
  solidity: "0.8.8"
};
  • 开始编译yarn hardhat compile
(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat compile
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat compile
Downloading compiler 0.8.8
Compiled 1 Solidity file successfully
Done in 5.70s.
  • 安装代码美化依赖
yarn add --dev prettier prettier-plugin-solidity

新建.prettierrc文件

{
  "tabWidth": 4,
  "useTabs": false,
  "semi": false,
  "singleQuote": false
}

新建.prettierignore文件

node_modules
package.json
img
artifacts
cache
coverage
.env
.*
README.md
coverage.json

3.修改deploy.js并部署

将以下代码覆盖deploy.js内容

// imports
const { ethers, run, network } = require("hardhat")

// async main
async function main() {
  const SimpleStorageFactory = await ethers.getContractFactory("SimpleStorage")
  console.log("Deploying contract...")
  const simpleStorage = await SimpleStorageFactory.deploy()
  await simpleStorage.deployed()
  console.log(`Deployed contract to: ${simpleStorage.address}`)
}

// main
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error)
    process.exit(1)
})

执行 yarn hardhat run scripts/deploy.js部署合约

(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat run scripts/deploy.js
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat run scripts/deploy.js
Deploying contract...
Deployed contract to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Done in 3.67s.

在hardhat.config.js中,我们添加defaultNetwork: "hardhat",这是未指定网络时默认的配置

module.exports = {
  defaultNetwork: "hardhat",
  ...
};

指定具体网络为hardhat

(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat run scripts/deploy.js --network hardhat
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat run scripts/deploy.js --network hardhat
Deploying contract...
Deployed contract to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Done in 3.51s.

4. 部署至GOERLI测试网络

  • 新建.env文件

配置如下内容为测试网信息,详见之前文章

GOERLI_RPC_URL=XXXXX
PRIVATE_KEY=XXXXXXX

覆盖deploy.js内容如下

require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config()

const GOERLI_RPC_URL = process.env.GOERLI_RPC_URL
const PRIVATE_KEY = process.env.PRIVATE_KEY

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  defaultNetwork: "hardhat",
  networks: {
    hardhat: {},
    goerli: {
      url: GOERLI_RPC_URL,
      accounts: [PRIVATE_KEY],
      // https://chainlist.org/zh
      chainId: 5
    }
  },
  solidity: "0.8.8"
};
// 安装依赖
npm install dotenv --save
(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat run scripts/deploy.js --network goerli
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat run scripts/deploy.js --network goerli
Deploying contract...
Deployed contract to: 0x4fC6FAe2C80adFd7beF5F6AeF2d8E59F2f3e1265
Done in 30.15s.

访问该地址发现部署成功https://goerli.etherscan.io/address/0x4fC6FAe2C80adFd7beF5F6AeF2d8E59F2f3e1265

1
欢迎关注公众号算法小生获取完整代码

现在我们来实践hardhat部署合约中的其他更多技术要点

5. 代码方式验证合约

  • 注册https://etherscan.io/, 如下图添加拷贝API_KEY

1

  • 在.env文件中新增ETHERSCAN_API_KEY
ETHERSCAN_API_KEY=API_KEY【刚才注册的key】
  • hardhat.config.js中新增配置
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY

module.exports = {
  etherscan: {
    apiKey: ETHERSCAN_API_KEY
  }
};
  • 覆盖deploy.js
// imports
const { ethers, run, network } = require("hardhat")

// async main
async function main() {
  const SimpleStorageFactory = await ethers.getContractFactory("SimpleStorage")
  console.log("Deploying contract...")
  const simpleStorage = await SimpleStorageFactory.deploy()
  await simpleStorage.deployed()
  console.log(`Deployed contract to: ${simpleStorage.address}`)
   if (network.config.chainId === 5 && process.env.ETHERSCAN_API_KEY) {
    console.log("Waiting for block confirmations...")
    await simpleStorage.deployTransaction.wait(6)
    await verify(simpleStorage.address, [])
  }
}

const verify = async (contractAddress, args) => {
  console.log("Verifying contract...")
  try {
    await run("verify:verify", {
      address: contractAddress,
      constructorArguments: args,
    })
  } catch (e) {
    if (e.message.toLowerCase().includes("already verified")) {
      console.log("Already Verified!")
    } else {
      console.log(e)
    }
  }
}

// main
main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error)
    process.exit(1)
})
  • 验证合约

如果用的使用了clash代理的话开启Tun模式,否则可能会报Connect Timeout Error

yarn hardhat run scripts/deploy.js --network goerli
或
yarn hardhat verify --network goerli 0x2e3C64c769DAbAC7587dEa70cA23164EEE3d9596 --show-stack-traces

yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat verify --network goerli 0x2e3C64c769DAbAC7587dEa70cA23164EEE3d9596 --show-stack-traces
Nothing to compile
Successfully submitted source code for contract
contracts/SimpleStorage.sol:SimpleStorage at 0x2e3C64c769DAbAC7587dEa70cA23164EEE3d9596
for verification on the block explorer. Waiting for verification result...

Successfully verified contract SimpleStorage on Etherscan.
https://goerli.etherscan.io/address/0x2e3C64c769DAbAC7587dEa70cA23164EEE3d9596#code
Done in 30.38s.

6. 通过hardhat与合约交互

在deploy.js的main方法中新增如下代码

async function main() {
  ......
  const currentValue = await simpleStorage.retrieve()
  console.log(`Current Value is: ${currentValue}`)

  // Update the current value
  const transactionResponse = await simpleStorage.store(7)
  await transactionResponse.wait(1)
  const updatedValue = await simpleStorage.retrieve()
  console.log(`Updated Value is: ${updatedValue}`)
}

运行及结果展示:

(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat run scripts/deploy.js                          
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat run scripts/deploy.js
Deploying contract...
Deployed contract to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Current Value is: 0
Updated Value is: 7
Done in 3.62s.

7. 自定义hardhat任务

  • 新建tasks/block-number.js
const { task } = require("hardhat/config")

task("block-number", "Prints the current block number").setAction(
  async (taskArgs, hre) => {
    const blockNumber = await hre.ethers.provider.getBlockNumber()
    console.log(`Current block number: ${blockNumber}`)
  }
)

module.exports = {}
  • 在hardhat.config.js中新增配置
require("./tasks/block-number")
  • 运行yarn hardhat命令
// 可以看到出现了任务
AVAILABLE TASKS:
  block-number          Prints the current block number
  • 运行yarn hardhat block-number --network goerli查看最新区块号
(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat block-number --network goerli
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat block-number --network goerli
Current block number: 7779125
Done in 14.01s.

8. hardhat本地节点

  • 运行yarn hardhat node查看本地节点信息
(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat node
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat node
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/

Accounts
========

WARNING: These accounts, and their private keys, are publicly known.
Any funds sent to them on Mainnet or any other live network WILL BE LOST.

Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH)
Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

Account #1: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000 ETH)
Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d
  • 在hardhat.config.js中新增网络配置
module.exports = {
  networks: {
    localhost: {
      url: "http://127.0.0.1:8545/",
      chainId: 31337
    }
  }
};
  • 新启动shell窗口并运行yarn hardhat run scripts/deploy.js --network localhost
(base) PS D:\blockchain\blockchain\hardhat-simple-storage-fcc> yarn hardhat run scripts/deploy.js --network localhost       
yarn run v1.22.19
$ D:\blockchain\blockchain\hardhat-simple-storage-fcc\node_modules\.bin\hardhat run scripts/deploy.js --network localhost
Deploying contract...
Deployed contract to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
Current Value is: 0
Updated Value is: 7
  • 切换到node窗口可看到本地交易信息

2

  • 在新启动的shell窗口中运行yarn hardhat console --network localhost我们即可在控制台与合约交互

3

欢迎关注公众号算法小生或沈健的技术博客shenjian.online

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小生Đ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值