WTF-Solidity 极简入门:ERC20 代币标准详解与测试代币发行实战

📅 发布时间:2026/9/15 10:09:15
WTF-Solidity 极简入门:ERC20 代币标准详解与测试代币发行实战
WTF-Solidity 极简入门ERC20 代币标准详解与测试代币发行实战【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-SolidityERC20 是运行在以太坊上的代币标准它通过一套统一的接口规范余额查询、转账、授权、授权转账让代币的发行与互操作变得极其简单。本文基于 WTF-Solidity 仓库第 31 讲的日文教程Languages/ja/31_ERC20_ja/readme.md与配套源码讲解 ERC20 标准的接口定义、完整实现原理并带你用 Remix 从零发行一枚属于自己的测试代币同时结合仓库内的其他合约如水龙头 Faucet说明该标准的实际复用方式。ERC20 是什么ERC20是运行在以太坊上的代币标准起源于 2015 年 11 月提出的 EIP-20由 Vitalik Buterin 等人参与。它规定了代币合约必须实现的基本转账逻辑包括账户余额查询balanceOf()代币转账transfer()授权后的转账transferFrom()授权approve()代币总供给量totalSupply()已授权的额度allowance()代币信息可选代币名称name()、符号symbol()、小数位数decimals()标准化的意义在于任何钱包、交易所、DeFi 协议都可以按照同一套函数签名与 ERC20 代币交互无需为每个代币单独适配。IERC20接口层定义IERC20是 ERC20 代币标准的接口合约它定义了 ERC20 代币应当实现的函数与事件。仓库中日文版接口位于 Languages/ja/31_ERC20_ja/IERC20.sol与中文版 31_ERC20/IERC20.sol 逻辑一致。之所以要把接口单独拆出来是因为「标准」只需规定通用的函数名、输入参数与输出参数而不关心内部实现细节。这样函数就被划分为内外两部分一侧专注实现ERC20.sol另一侧定义外部接口与公共数据IERC20.sol——这正是仓库中同时存在ERC20.sol与IERC20.sol两个文件的原因。事件EventIERC20定义了 2 个事件分别在转账与授权时释放便于链下索引与前端监听/** * dev 释放条件当 value 数量的代币从 (from) 账户转移到 (to) 账户时 */ event Transfer(address indexed from, address indexed to, uint256 value); /** * dev 释放条件当 value 数量的代币由 (owner) 账户授权给另一个账户 (spender) 时 */ event Approval(address indexed owner, address indexed spender, uint256 value);indexed关键字使得事件中的这些地址参数可以被链下高效检索过滤。函数FunctionIERC20定义了 6 个函数提供基本的代币转账能力并允许第三方经授权后动用用户的代币totalSupply()返回代币总供给量。/** * dev 返回代币总供给 */ function totalSupply() external view returns (uint256);balanceOf()返回account账户持有的代币数量。/** * dev 返回 account 所持有的代币数量 */ function balanceOf(address account) external view returns (uint256);transfer()转账代币。/** * dev 将 amount 数量的代币从交易调用者账户转移到 to 账户 * * 如果成功返回 true * * 释放 {Transfer} 事件 */ function transfer(address to, uint256 amount) external returns (bool);allowance()返回已授权的额度。/** * dev 返回 owner 账户授权给 spender 账户的额度默认为 0 * * 当 {approve} 或 {transferFrom} 被调用时allowance 会改变 */ function allowance(address owner, address spender) external view returns (uint256);approve()将一定数量的代币授权给他人。/** * dev 调用者将 amount 数量的代币授权给 spender * * 如果成功返回 true * * 释放 {Approval} 事件 */ function approve(address spender, uint256 amount) external returns (bool);transferFrom()被授权方转移已授权的代币。/** * dev 通过授权机制将 amount 数量的代币从 from 账户转移到 to 账户 * 转移的部分会从调用者的 allowance 中扣除 * * 如果成功返回 true * * 释放 {Transfer} 事件 */ function transferFrom(address from, address to, uint256 amount) external returns (bool);ERC20 实现从接口到完整合约接下来按照教程的思路基于 Languages/ja/31_ERC20_ja/ERC20.sol 逐步实现一个简单的 ERC20完整覆盖IERC20中定义的全部函数。合约编译要求 Solidity^0.8.34仓库根目录 foundry.toml 亦统一配置了solc 0.8.34且通过import ./IERC20.sol引入接口并用is IERC20继承。状态变量合约使用状态变量管理账户余额、授权额度与代币信息。其中balanceOf、allowance、totalSupply是public类型的变量编译器会自动为它们生成同名的getter函数从而自动实现IERC20中定义的balanceOf()、allowance()、totalSupply()。name、symbol、decimals分别表示代币的名称、符号与小数位数。注意带override的public变量会覆盖从父合约接口继承的同名getter函数例如IERC20中的balanceOf()。mapping(address uint256) public override balanceOf; // 账户余额 mapping(address mapping(address uint256)) public override allowance; // 授权额度 uint256 public override totalSupply; // 代币总供给量 string public name; // 名称 string public symbol; // 符号 uint8 public decimals 18; // 小数位数值得关注的是allowance采用了嵌套映射mapping(address mapping(address uint256))结构为「授权方 → 被授权方 → 额度」精确表达了谁授权给谁多少额度的关系。decimals默认设为18与 ETH 的小数位保持一致绝大多数 ERC20 代币如 USDT、UNI 等也采用该值。函数实现构造函数初始化代币名称与符号在合约部署时执行一次。constructor(string memory name_, string memory symbol_) { name name_; symbol symbol_; }transfer()函数实现IERC20的transfer提供代币转账逻辑——从调用者余额中扣除amount给接收者增加amount并释放Transfer事件。注意sh*tcoin空气币常改造此函数偷偷添加税费、分红、抽奖等逻辑这也是为什么「投资前仔细阅读代币合约」至关重要。function transfer(address recipient, uint256 amount) public override returns (bool) { balanceOf[msg.sender] - amount; balanceOf[recipient] amount; emit Transfer(msg.sender, recipient, amount); return true; }approve()函数实现授权逻辑将amount数量的代币授权给spender。spender既可以是 EOA 账户也可以是合约账户——例如在 Uniswap 上交易代币时就需要先向 Uniswap 合约授权代币。function approve(address spender, uint256 amount) public override returns (bool) { allowance[msg.sender][spender] amount; emit Approval(msg.sender, spender, amount); return true; }transferFrom()函数实现授权转账。被授权方msg.sender将授权方sender的amount数量代币转给recipient同时从自己的allowance中扣减相应额度。function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { allowance[sender][msg.sender] - amount; balanceOf[sender] - amount; balanceOf[recipient] amount; emit Transfer(sender, recipient, amount); return true; }mint()函数铸造代币不属于IERC20标准。教程中为了便于演示任何人都可以铸造任意数量的代币真实应用中应有严格的权限控制通常仅owner可以铸造。function mint(uint256 amount) external { balanceOf[msg.sender] amount; totalSupply amount; emit Transfer(address(0), msg.sender, amount); }burn()函数销毁代币同样不属于IERC20标准。销毁会减少代币总供给量。function burn(uint256 amount) external { balanceOf[msg.sender] - amount; totalSupply - amount; emit Transfer(msg.sender, address(0), amount); }值得注意的实现细节mint与burn均以零地址address(0)作为事件中的对端——铸造相当于「从零地址转出」销毁相当于「转入零地址」。这保持了Transfer事件语义的完整统一也使链上数据分析工具可以通过追踪零地址的转账来统计铸造/销毁量。发行自己的 ERC20 测试代币ERC20 标准诞生后在以太坊上发行代币变得非常容易。下面我们在 Remix 中部署上面的合约发行属于自己的测试代币操作细节可对照仓库中的 31-1.png、31-2.png、31-3.png 三张截图。第 1 步编译并部署合约在 Remix 中打开ERC20.sol注意项目里有两个文件编译时需选择正确的合约文件编译通过后切换到「DEPLOY RUN TRANSACTIONS」面板。环境选择JavaScript VM内置测试链合约选择ERC20。在构造函数参数中填写name_和symbol_都设为WTF点击transact按钮部署部署成功后即可在 Deployed Contracts 列表看到我们的WTF代币合约。第 2 步mint 铸造 100 个代币展开已部署的ERC20合约调用mint()函数amount填入100并执行交易。随后点击右侧的Debug按钮查看交易日志其中包含 4 项关键信息事件Transfer铸造来源地址0x0000000000000000000000000000000000000000零地址接收地址当前账户0x5B38Da6a701c568545dCfcB03FcB875f56beddC4铸造数量100第 3 步用 balanceOf 验证余额调用balanceOf()函数并传入当前账户地址返回值应为100说明铸造成功。界面左侧为账户信息右侧为函数执行结果decoded output显示uint256: 100从源码结构看 ERC20 接口的复用价值接口与实现分离的设计让IERC20在整个仓库中被广泛复用这可以从多个合约中看出端倪32_Faucet/Faucet.sol 中的水龙头合约通过IERC20 token IERC20(tokenContract);把任意代币地址转换成IERC20对象即可直接调用transfer等标准函数向领取者发放测试代币33_Airdrop/Airdrop.sol 的空投合约同样依赖标准接口批量执行授权转账后续第 51 讲 ERC4626、第 53 讲 ERC20Permit 等进阶合约也都是在标准 ERC20 基础上扩展而来。可以推断只要项目遵循IERC20标准实现代币任何基于标准接口编写的 DeFi 合约、钱包与浏览器插件都可以直接与之交互——这正是标准化的核心价值也是本讲教程中「接口与实现分离」设计的根本原因。总结本讲我们学习了以太坊上的ERC20标准及其实现方式并成功发行了自己的测试代币。2015 年末被提出的 ERC20 代币标准大幅降低了以太坊上发行代币的门槛开启了 ICO 时代。从实践角度看投资或交互任何代币项目时仔细阅读其代币合约代码尤其是transfer是否被加入了额外逻辑有助于规避投资风险、提高投资成功率。接下来可以继续学习仓库中的 32_Faucet代币水龙头 与 33_Airdrop空投进一步理解 ERC20 在真实场景中的应用。【免费下载链接】WTF-SolidityWTF Solidity 极简入门教程供小白们使用。Now supports English! 官网: https://wtf.academy项目地址: https://gitcode.com/GitHub_Trending/wt/WTF-Solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考