代码改变世界

web3hardhat 框架实战-ERC20 - 指南

2025-09-28 12:46  tlnshuju  阅读(6)  评论(0)    收藏  举报


在这里插入图片描述

前言

随着区块链技术的不断发展,Web3 生态正在逐渐从概念走向落地应用。其中,代币经济作为去中心化应用的核心组成部分,ERC20 代币标准因其简单易用和广泛兼容而成为首选。在本篇博客中,我将基于 Hardhat v3 框架,带你从零实现一个功能完整的 ERC20 代币合约,支持 mint(铸造)burn(销毁) 以及 transfer(转账) 功能。
通过这个小型 Demo,你不仅可以掌握 ERC20 的核心逻辑,还能熟悉 Hardhat 的智能合约开发、部署和测试流程,为你在 Web3 世界的进一步探索打下坚实基础。无论你是刚入门的 Solidity 开发者,还是想快速搭建代币实验环境的开发者,这篇教程都将为你提供实用的参考。


一、环境准备

本电脑用的是node22的环境
hardhat3的版本
官网地址
https://hardhat.org/docs/getting-started

二、项目创建

1.创建项目文件夹

mkdir hardhat-example
cd hardhat-example

2.初始化项目框架

npx hardhat --init

选择hardhat版本,
(本教程选择的是最新的版本)
在这里插入图片描述
选择需要的框架语法
(本教程选择的是最新的Runner and Viem)
在这里插入图片描述
下面的都直接回车让他执行完成即可。
在这里插入图片描述
完成后我们会得到如上的一个项目架构。
其中主要的包

  • contracts:就是编写合约代码的地方
  • test:编写测试合约代码的地方
  • ignition:部署合约代码编写的地方
hardhat.config.ts
contracts
├── Counter.sol
└── Counter.t.sol
test
└── Counter.ts
ignition
└── modules
└── Counter.ts
scripts
└── send-op-tx.ts

三、ERC20功能实现

合约代码,主要编写了ERC20的标准功能(balanceOf,transfer,approve

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
// ERC20 提供标准ERC20功能 (balanceOf,transfer,approve)
/// @title MyToken - Simple ERC20 with owner mint + public burn
contract MyToken is ERC20, Ownable {
constructor(string memory name_, string memory symbol_, uint256 initialSupply) ERC20(name_, symbol_) Ownable(msg.sender){
// 初试供应铸给部署者
_mint(msg.sender, initialSupply);
}
// @notice 只有合约owner 可以铸造币
function mint(address to, uint256 amount) external onlyOwner {
_mint(to,amount);
}
// @notice 持有者可以销毁自己的代币
function burn(uint256 amount) external {
_burn(msg.sender, amount);
}
}

编写完成之后执行如下命令,进行合约的编译

npx hardhat compile

在这里插入图片描述
看到这个提示证明合约已经编译成功了

合约测试

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { network } from "hardhat";
describe("MyToken (Hardhat v3 + viem)", async () => {
const { viem } = await network.connect();
const publicClient = await viem.getPublicClient();
const [owner, alice] = await viem.getWalletClients();
it("should deploy with initial supply to owner", async () => {
const initialSupply = 1000n * 10n ** 18n;
const token = await viem.deployContract("MyToken", [
"MyToken",
"MTK",
initialSupply,
]);
const ownerBalance = await token.read.balanceOf([owner.account.address]);
assert.equal(ownerBalance, initialSupply);
});
it("should allow only owner to mint", async () => {
const initialSupply = 1000n * 10n ** 18n;
const token = await viem.deployContract("MyToken", [
"MyToken",
"MTK",
initialSupply,
]);
// owner 给 alice mint
await token.write.mint([alice.account.address, initialSupply]);
const aliceBalance = await token.read.balanceOf([alice.account.address]);
assert.equal(aliceBalance, initialSupply);
// 非 owner mint -> 应该 revert
await assert.rejects(
token.write.mint([alice.account.address, 1n], { account: alice.account }),
);
});
it("should allow holder to burn", async () => {
const initialSupply = 1000n * 10n ** 18n;
const token = await viem.deployContract("MyToken", [
"MyToken",
"MTK",
initialSupply,
]);
// owner 给 alice mint
await token.write.mint([alice.account.address, initialSupply]);
// alice 销毁 10
await token.write.burn([10n], { account: alice.account });
const balanceAfter = await token.read.balanceOf([alice.account.address]);
assert.equal(balanceAfter, initialSupply - 10n);
});
});

执行如下命令进行合约的测试

npx hardhat test

在这里插入图片描述
看到这个证明合约测试成功

合约部署

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("MyTokenModule", (m) => {
// 构造函数参数
const initialSupply = 1000n * 10n ** 18n;
// 部署合约并传入构造参数
const token = m.contract("MyToken", ["MyToken", "MTK", initialSupply]);
// 部署完成后,给一个固定地址 mint 100 个代币(示范用)
// 你可以换成 m.getAccount(1) 来获取测试账户
m.call(token, "mint", ["0x0000000000000000000000000000000000000001", 100n * 10n ** 18n]);
return { token };
});

执行如下命令进行合约的部署

npx hardhat ignition deploy ignition/modules/MyToken.ts

在这里插入图片描述
证明合约部署成功


总结

本文介绍了如何使用Hardhat v3框架从零实现一个功能完整的ERC20代币合约。主要内容包括:1)环境准备,使用Node22和Hardhat3;2)项目创建,通过命令行初始化项目结构;3)ERC20功能实现,编写支持mint、burn和transfer功能的合约代码;4)合约测试,验证代币铸造、销毁和转账功能;5)合约部署,在本地环境部署合约。整个项目展示了ERC20代币的核心逻辑和开发流程,为Web3开发者提供了实用参考。