// SPDX-License-Identifier: MIT pragma solidity ^0.8.19;
interface IERC20 { // 可选函数 function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8);
// 必需函数 function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool);
// 授权相关 function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool);
// 事件 event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); }
contract MyToken is IERC20 { string public constant name = "My Token"; string public constant symbol = "MTK"; uint8 public constant decimals = 18; // 与 ETH 一致
uint256 private _totalSupply; mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances;
constructor(uint256 initialSupply) { _mint(msg.sender, initialSupply); }
function totalSupply() public view override returns (uint256) { return _totalSupply; }
function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
function transfer(address to, uint256 amount) public override returns (bool) { _transfer(msg.sender, to, amount); return true; }
function allowance(address owner, address spender) public view override returns (uint256) { return _allowances[owner][spender]; }
function approve(address spender, uint256 amount) public override returns (bool) { _approve(msg.sender, spender, amount); return true; }
function transferFrom(address from, address to, uint256 amount) public override returns (bool) { uint256 currentAllowance = _allowances[from][msg.sender]; require(currentAllowance >= amount, "ERC20: insufficient allowance");
// 更新 allowance(注意:如果 amount == type(uint256).max,不减少) unchecked { _approve(from, msg.sender, currentAllowance - amount); }
_transfer(from, to, amount); return true; }
// === 内部函数 === function _transfer(address from, address to, uint256 amount) internal { require(from != address(0), "ERC20: transfer from zero address"); require(to != address(0), "ERC20: transfer to zero address"); require(_balances[from] >= amount, "ERC20: insufficient balance");
unchecked { _balances[from] -= amount; _balances[to] += amount; }
emit Transfer(from, to, amount); }
function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from zero address"); require(spender != address(0), "ERC20: approve to zero address");
_allowances[owner][spender] = amount; emit Approval(owner, spender, amount); }
function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to zero address");
_totalSupply += amount; unchecked { _balances[account] += amount; } emit Transfer(address(0), account, amount); }
function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from zero address"); require(_balances[account] >= amount, "ERC20: burn amount exceeds balance");
unchecked { _balances[account] -= amount; _totalSupply -= amount; } emit Transfer(account, address(0), amount); } }
|