在区块链的世界里,以太坊凭借其智能合约平台地位,成为了加密货币和去中心化应用(DApp)开发的“操作系统”,而ERC20(Ethereum Request for Comments 20)作为以太坊上最主流的代币标准,规范了同质化代币(如USDT、USDC等稳定币)的基本功能接口,让代币开发变得标准化、可互操作,本文将带你从零开始,手把手教你使用以太坊开发工具创建一枚属于自己的ERC20代币,涵盖环境搭建、代码编写、测试部署到交互验证的全流程。
ERC20代币标准核心解析
在动手之前,我们先快速理解ERC20的核心逻辑,ERC20标准要求代币合约必须实现以下6个基本接口(函数):
name():返回代币全称,如“Tether USD”。symbol():返回代币符号,如“USDT”,通常2-3个字符。decimals():返回代币精度,即小数位数(如ETH为18,USDT为6)。totalSupply():返回代币总供应量。balanceOf(address _owner):查询指定地址的代币余额。transfer(address _to, uint256 _value):转账函数,将_value数量代币从调用者地址转给_to。
标准还推荐实现approve()、allowance()、transferFrom()三个函数,用于授权第三方(如交易所)转移代币(即“代币授权”功能),这也是代币与交易所、钱包等第三方服务交互的基础。
开发环境准备:工具安装与配置
ERC20代币开发基于以太坊虚拟机(EVM),我们需要以下核心工具:
安装Node.js和npm
Node.js是JavaScript运行时环境,npm是其包管理器,访问Node.js官网下载LTS版本(推荐18.x以上),安装完成后打开终端,输入以下命令验证:
node -v # 查看Node.js版本 npm -v # 查看npm版本
安装Hardhat(以太坊开发框架)
Hardhat是当前最流行的以太坊开发工具之一,支持智能合约编译、测试、部署和调试,插件生态丰富,在终端中执行:
npm init -y # 初始化npm项目(会生成package.json文件) npm install --save-dev hardhat # 安装Hardhat
安装完成后,在项目目录下运行:
npx hardhat # 初始化Hardhat项目
根据提示选择“Create a basic sample project”(创建基础示例项目),默认配置即可,这会生成以下关键文件:
contracts/:存放智能合约源码(示例中有一个Lock.sol)。scripts/:存放部署脚本(示例中有一个deploy.js)。test/:存放测试脚本(示例中有一个test.js)。hardhat.config.js:Hardhat配置文件。
安装OpenZeppelin合约库(ERC20标准实现)
OpenZeppelin是一个开源的智能合约库,提供了经过安全审计的ERC20、ERC721等标准合约实现,避免重复造轮子并降低安全风险,安装:
npm install @openzeppelin/contracts # 安装OpenZeppelin合约库
编写ERC20代币智能合约
创建代币合约文件
在contracts/目录下新建文件,命名为MyToken.sol(或你喜欢的名字),我们基于OpenZeppelin的ERC20合约进行扩展,只需定义代币名称、符号和总供应量。
编写合约代码
打开MyToken.sol,输入以下代码:
// SPDX-License-Identifier: MIT // 指定许可证(必填,推荐MIT)
pragma solidity ^0.8.20; // 指定Solidity版本(需与Hardhat兼容)
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // 导入OpenZeppelin的ERC20合约
contract MyToken is ERC20 { // 继承ERC20合约,实现其所有功能
/**
* @dev 构造函数,初始化代币
* @param _name 代币名称
* @param _symbol 代币符号
* @param _initialSupply 初始供应量(注意:需乘以10^decimals,默认decimals=18)
*/
constructor(
string memory _name,
string memory _symbol,
uint256 _initialSupply
) ERC20(_name, _symbol) { // 调用父类ERC20的构造函数,设置名称和符号
_mint(msg.sender, _initialSupply); // 将_initialSupply数量代币铸造给合约部署者(msg.sender)
}
}