合约工具:HardHat 学习

812 阅读3分钟

概述

Hardhat 是以太坊软件的开发环境。它是由用于编辑,编译,调试和部署智能合约和dapps的不同组件组成,所有这些组件共同创建一个完整的开发环境。

Hardhat Runner 是您在使用 Hardhat 时与之交互的主要组件。他是一个灵活且可扩展的任务运行器,可帮助管理和自动化开发智能合约和dapp所固有的重复性任务。

开始你的项目

准备工作

1.使用npm初始化项目文件夹

npm init -y

PYV90XX{3@L_5HMO9(595.png

2.下载Hardhat

npm install --save-dev hardhat

(p9-juejin.byteimg.com/tos-cn-i-k3…?)

3.运行hardhat

npx hardhat/*

$U(~HEO(6Q@YH4P9EC9DFWV.png

4.初始化后的目录如下

  • contracts/ 该目录存放智能合约源文件
  • scripts/ 该目录下存放简单的自动化执行脚本
  • test/ 该目录存放测试智能合约代码的文件

P{WR%~MZ)H74SUWFDU$75B5.png

编译合约

  • 编译合约需要使用hardhat内置的compile任务

3Q7@2`3EL%(O0QO}5FCN6CT.png

编译完成后,若没有出现问题,则会生成两个新文件夹:artifacts/ ,cache/
contracts/下的合约文件编译生成的文件保存在artifacts/目录下

  • 配置编译

如果要自定义编译器选项,可以通过hardhat.config.js。设置solidity编译器版本

EOYKZX{STZC_NE@NGSRVP.png

测试合约

hardhat可以使用JavaScript或者typescript两种语言来测试合约,但是官方建议使用TypeScript来获得更好的自动补全,并尽早捕获可能的错误。本指南使用的是TypeScript。

本文以hardhat自动生成的 test/ 目录下的Lock文件讲解

  • 导入配置文件及工具
import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs";
import { expect } from "chai";
import { ethers } from "hardhat";
  • 异步函数

lockedAmount表示锁仓金额

unlockTime是锁仓时间

ethers.getSigners()是以太坊账户的抽象,可用于对消息和交易进行签名,并将已签名的交易发送到以太坊网络以执行状态更改操作。

ethers.getContractFactory("Lock")得到合约工厂对象

Lock.deploy(unlockTime, { value: lockedAmount })用合约工厂对象对合约进行部署,部署的参数是构造函数的参数。

async function deployOneYearLockFixture() {
    const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
    const ONE_GWEI = 1_000_000_000;

    const lockedAmount = ONE_GWEI;
    const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;

    // Contracts are deployed using the first signer/account by default
    const [owner, otherAccount] = await ethers.getSigners();

    const Lock = await ethers.getContractFactory("Lock");
    const lock = await Lock.deploy(unlockTime, { value: lockedAmount });

    return { lock, unlockTime, lockedAmount, owner, otherAccount };
  }
  • 测试方法

Describe 是JavaScript中的一个函数测试框架。它简单地描述了由“it”函数枚举的测试用例套件。 以下是合约代码里可能会存在的错误进行测试如:锁仓时间是否一样,是否是owner调用withdraw()方法

1."Should set the right unlockTime" : 比较合约的unlockTime和我们部署所给的是否一样

2."Should set the right owner": 比较 是否是同一个调用者

3."Should receive and store the funds to lock": 调用者地址上的金额是否和锁在合约里面的金额一致

4."Should fail if the unlockTime is not in the future": 测试unlockTime的值不是在未来值是否会报错

  describe("Depl oyment", function () {
    it("Should set the right unlockTime", async function () {
    // loadFixture是让合约回复到初始状态,不需要重复部署。
      const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
      expect(await lock.unlockTime()).to.equal(unlockTime);
    });

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

    it("Should receive and store the funds to lock", async function () {
      const { lock, lockedAmount } = await loadFixture(deployOneYearLockFixture);
      expect(await ethers.provider.getBalance(lock.address)).to.equal(lockedAmount);
    });

    it("Should fail if the unlockTime is not in the future", async function () {
      // We don't use the fixture here because we want a different deployment
      const latestTime = await time.latest();
      const Lock = await ethers.getContractFactory("Lock");
      await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
        "Unlock time should be in the future"
      );
    });
  });

部署合约

在部署方面,目前还没有为 Hardhat 实现部署系统的官方插件。我们使用部署脚本来部署合约。

  • 开启一个本地节点,便于本地部署

npx hardhat node

  • 重新打开一个终端并在localhost网络中部署合约

npx hardhat run --network localhost scripts/deploy.ts

  • 如果不在本地网络中部署,可以选择市面上主网的测试网进行部署

npx hardhat run --network < you network > scripts/deploy.js