用于测试的极简ERC20合约:寻求适合教学的轻量实现
极简ERC20代币实现方案(教学专用)
OpenZeppelin的ERC20合约包含大量扩展功能(如安全校验、授权机制额外防护等),合约体积冗余,不利于学生聚焦理解ERC20核心逻辑。以下提供仅保留标准核心逻辑的极简实现,帮助学习者掌握基础机制。
ERC20标准核心接口(中文注释版)
interface IERC20 { // 转账事件:代币从from地址转到to地址时触发,value为转账数量 event Transfer(address indexed from, address indexed to, uint256 value); // 授权事件:owner授权spender使用其value数量代币时触发 event Approval(address indexed owner, address indexed spender, uint256 value); // 返回代币总供应量 function totalSupply() external view returns (uint256); // 返回指定account地址的代币余额 function balanceOf(address account) external view returns (uint256); // 调用者向to地址转账amount数量代币,返回执行结果 function transfer(address to, uint256 amount) external returns (bool); // 返回owner地址授权给spender地址的代币可用额度 function allowance(address owner, address spender) external view returns (uint256); // 调用者授权spender地址使用自身amount数量代币,返回执行结果 function approve(address spender, uint256 amount) external returns (bool); // 从from地址向to地址转账amount数量代币(需from地址已授权调用者),返回执行结果 function transferFrom(address from, address to, uint256 amount) external returns (bool); }
极简ERC20实现合约
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SimpleERC20 is IERC20 { // 代币总供应量 uint256 private _totalSupply; // 地址到余额的映射 mapping(address => uint256) private _balances; // 所有者地址到授权地址的额度映射 mapping(address => mapping(address => uint256)) private _allowances; // 代币名称、符号、小数位(符合常规习惯,非标准强制要求) string public name = "SimpleERC20"; string public symbol = "SE20"; uint8 public decimals = 18; // 构造函数:部署时初始化总供应量,全部分配给部署者 constructor(uint256 initialSupply) { _totalSupply = initialSupply * (10 ** uint256(decimals)); _balances[msg.sender] = _totalSupply; emit Transfer(address(0), msg.sender, _totalSupply); } // 返回总供应量 function totalSupply() external view override returns (uint256) { return _totalSupply; } // 返回指定地址余额 function balanceOf(address account) external view override returns (uint256) { return _balances[account]; } // 转账核心逻辑:校验余额、更新余额、触发事件 function transfer(address to, uint256 amount) external override returns (bool) { require(_balances[msg.sender] >= amount, "余额不足"); _balances[msg.sender] -= amount; _balances[to] += amount; emit Transfer(msg.sender, to, amount); return true; } // 返回授权额度 function allowance(address owner, address spender) external view override returns (uint256) { return _allowances[owner][spender]; } // 授权核心逻辑:更新授权额度、触发事件 function approve(address spender, uint256 amount) external override returns (bool) { _allowances[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } // 授权转账核心逻辑:校验授权额度与余额、更新数据、触发事件 function transferFrom(address from, address to, uint256 amount) external override returns (bool) { require(_allowances[from][msg.sender] >= amount, "授权额度不足"); require(_balances[from] >= amount, "余额不足"); _allowances[from][msg.sender] -= amount; _balances[from] -= amount; _balances[to] += amount; emit Transfer(from, to, amount); return true; } }
核心设计说明
- 状态极简:仅保留
_totalSupply、_balances、_allowances三个核心状态变量,无额外冗余逻辑。 - 功能聚焦:每个函数仅实现ERC20标准强制要求的核心逻辑,去掉所有非必要的安全扩展(如地址非零校验、授权覆盖提醒等,可作为后续扩展知识点单独讲解)。
- 标准合规:严格按照ERC20规范触发
Transfer和Approval事件,保证合约符合标准交互要求。
内容的提问来源于stack exchange,提问作者Petr Tripolsky
相关产品推荐
相关产品推荐

