Ethereum 智能合约开发工具之 RPC 服务和 Hardhat 的简单使用介绍

Ethereum 智能合约开发工具之 RPC 服务和 Hardhat 的简单使用介绍

一.主流的 RPC 服务商

  • Alchemy: https://www.alchemy.com/
  • Quicknode: https://www.quicknode.com/
  • Ankr: https://www.ankr.com/
  • Infura: https://www.infura.io/zh
  • GetBlock: https://getblock.io/

Chainlist 也可以找到 RPC 节点

  • ChainList: https://chainlist.org/

二. Hardhat 使用介绍

hardhat 是一个用于构建、测试、部署和维护以太坊智能合约的开发环境。它提供了一系列工具和插件,使开发人员可以更高效地工作。

1.Hardhat 初体验

1.1.安装与初始化

npm install --save-dev hardhat

1.2.初始化项目

npx hardhat
或者
npx hardhat init
  • 输出如下
What do you want to do? …
❯ Create a JavaScript project
  Create a TypeScript project
  Create a TypeScript project (with Viem)
  Create an empty hardhat.config.js
  Quit

选择你喜欢的方式往下执行, 执行之后你后得到下面目录结构的代码

图像

  • Contract: 存放合约代码的目录
  • Ignition/modules: 部署脚本目录
  • Test: 测试脚本目录
  • hardhat.config.js:配置文件,网络和其他配置

若是 Ts 的方式生成,还有很多 ts 的配置文件

1.3.hardhat 测试部署合约

  • 测试合约
npx hardhat test

1.3.1.本地部署合约

  • 启动本地节点,以便部署和测试智能合约:
npx hardhat node
  • 部署智能合约: 在终端中运行部署脚本
npx hardhat ignition deploy ignition/modules/xxx.js --network localhost

1.3.2. Sepolia 网络部署和验证合约

npx hardhat ignition deploy ignition/modules/xxx.js --network sepolia --verify

该--verify标志是可选的,但它告诉 Hardhat Ignition 在成功部署后验证合同。

如果您有现有部署并想要验证它,您也可以verify通过传递部署 ID 直接运行任务:

npx hardhat ignition verify chain-11155111

1.3.3. 参数执行部署

要使用参数执行部署,您需要使用参数--parameters,如下所示:

可以调用一个示例文件./ignition/parameters.json并包含以下内容:

{"Apollo": {"name": "Saturn V"}}

这使得模块name的参数Apollo为"Saturn V"。

npx hardhat ignition deploy ignition/modules/Apollo.js --parameters ignition/parameters.json

1.3.4.检查现有部署

  • ignition deployments 返回对应的部署 ID
npx hardhat ignition deployments
  • 输出
chain-31337
  • ignition status 返回信息部署信息
npx hardhat ignition status chain-31337
  • 输出
Deployment chain-31337 (chainId: 31337) was successful

Deployed Addresses

TheWebThree#TheWebThree - 0x5FbDB2315678afecb367f032d93F642f64180aa3

1.3.5.可视化你的模块

npx hardhat ignition visualize ./ignition/modules/TheWebThree.js
  • 执行完命令之后会生成一个 html, 里面展示了你 js 的所有函数调用情况

1.3.6.清除先前的执行

npx hardhat ignition wipe deploymentId futureId

1.3.7. 使用 reset 清除现有的部署

npx hardhat ignition deploy ignition/modules/Apollo.ts --network localhost --reset

1.3.8.使用 create2 部署

npx hardhat ignition deploy ignition/modules/Apollo.js --network sepolia --strategy create2

2.使用 Hardhat 开发一个 ERC20 代币合约

2.1.创建目录

mkdir erc20
npx hardhat init

2.2.项目初始化完成之后改造代码得到以下结构

图像

  • TheWebThree.sol 是核心合约,代码如下
// contracts/MyTokenV1.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract TheWebThree is Initializable, ERC20Upgradeable {
     address payable public owner;

    function initialize(uint256 initialSupply) external initializer {
        __ERC20_init("TheWebThree", "TWT");
        _mint(msg.sender, initialSupply);

        owner = payable(msg.sender);
    }
}
  • ignition/modules 下面的 TheWebThree.js 是部署脚本
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");


module.exports = buildModule("TheWebThree", (m) => {
    const InitialSupply = 1_000_000_000;
    const theWeb3Contract = m.contract("TheWebThree");

    m.call(theWeb3Contract, "initialize", [InitialSupply], { after: [theWeb3Contract] });

    return { theWeb3Contract };
});
  • test 目录下 TheWebThree.js 的是测试脚本
const {
    time,
    loadFixture,
} = require("@nomicfoundation/hardhat-toolbox/network-helpers");
const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs");
const { expect } = require("chai");
const BigNumber = require("bignumber.js");


describe("TheWebThree", function () {
    async function deployTheWebThree() {
        const initialSupply = 10000000000

        // const initialSupply = new BigNumber(amount).times(new BigNumber(10).pow(10e18));

        const [owner, otherAccount] = await ethers.getSigners();
        console.log(owner.address)
        console.log(otherAccount.address)

        const TheWebThree = await ethers.getContractFactory("TheWebThree");
        const theWebThree = await TheWebThree.deploy();

        await theWebThree.initialize(initialSupply)

        await theWebThree.transfer(owner, initialSupply);

        return { theWebThree, owner, otherAccount, initialSupply};
    }


    describe("Deployment", function () {
        it("Should set the right symbol", async function () {
            const { theWebThree, owner, otherAccount,initialSupply  } = await loadFixture(deployTheWebThree);
            expect(await theWebThree.symbol()).to.equal("TWT");
            expect(await theWebThree.name()).to.equal("TheWebThree");
            console.log("decimals==", await theWebThree.decimals())
        });

        it("Should set the right owner", async function () {
            const { theWebThree, owner, otherAccount, initialSupply } = await loadFixture(deployTheWebThree);
            expect(await theWebThree.owner()).to.equal(owner.address);
        });

        it("Should receive right balance", async function () {
            const { theWebThree, owner, otherAccount,initialSupply  } = await loadFixture(deployTheWebThree);
            const balanceOf = await ethers.provider.getBalance(await theWebThree.owner())
            console.log(balanceOf)
            // expect(balanceOf).to.equal(initialSupply);
        });

    });


});
  • hardhat.config.js 网络配置相关的代码
require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: {
    version: "0.8.24",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      }
    }
  },
  networks: {
    sepolia: {
      url: "https://sepolia.infura.io/v3/apiKey",
      accounts: ["privateKey"]
    },
    bsctest: {
      url: `https://data-seed-prebsc-1-s1.binance.org:8545/`,
      accounts: ["privateKey"]
    },
  },
  etherscan: {
    apiKey: "apiKey",
  }
};

3.执行测试与部署

3.1.测试

  • 执行测试命令
npx hardhat test
  • 输出结果
TheWebThree
    Deployment
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
0x70997970C51812dc3A010C7d01b50e0d17dc79C8
decimals== 18n
      ✔ Should set the right symbol (402ms)
      ✔ Should set the right owner
9999998340779823021046n
      ✔ Should receive right balance


  3 passing (410ms)

3.2.本地部署

  • 启动节点命令
npx 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
  • 本地部署合约命令
npx hardhat ignition deploy ignition/modules/TheWebThree.js --network localhost
  • 输出结果
Hardhat Ignition 🚀

Deploying [ TheWebThree ]

Batch #1
  Executed TheWebThree#TheWebThree

Batch #2
  Executed TheWebThree#TheWebThree.initialize

[ TheWebThree ] successfully deployed 🚀

Deployed Addresses

TheWebThree#TheWebThree - 0x5FbDB2315678afecb367f032d93F642f64180aa3

3.3. Sepolia 部署

  • 部署命令
npx hardhat ignition deploy ignition/modules/TheWebThree.js --network sepolia --verify
  • 输出结果
✔ Confirm deploy to network sepolia (11155111)? … yes

Hardhat Ignition 🚀

Deploying [ TheWebThree ]

Batch #1
  Executed TheWebThree#TheWebThree

Batch #2
  Executed TheWebThree#TheWebThree.initialize

[ TheWebThree ] successfully deployed 🚀

Deployed Addresses

TheWebThree#TheWebThree - 0x3bBb5B55A0054c10a176C932B8b9d7775CE22419

Verifying deployed contracts

Verifying contract "contracts/TheWebThree.sol:TheWebThree" for network sepolia...

上面的其他的命令就不在这里再做过多赘述,比较简单的,课程中咱们详解讲解,

全部评论(0)