# ERC-20 **Published by:** [Bob](https://paragraph.com/@bob-25/) **Published on:** 2024-11-24 **URL:** https://paragraph.com/@bob-25/erc-20 ## Content 什么是 ERC-20?ERC-20 提出了一个同质化代币的标准,换句话说,它们具有一种属性,使得每个代币都与另一个代币(在类型和价值上)完全相同。 例如,一个 ERC-20 代币就像以太币一样,意味着一个代币会并永远会与其他代币一样。(From: 《ERC-20 代币标准》)方法(Method)function name() public view returns (string) // 返回令牌的名称 - 例如 "MyToken" // 可选 - 此方法可用于提高可用性,但接口和其他协定不得期望存在这些值。 function symbol() public view returns (string) // 返回令牌的 symbol。例如“HIX”。 // 可选 - 此方法可用于提高可用性,但接口和其他协定不得期望存在这些值。 function decimals() public view returns (uint8) // 返回代币使用的小数位数 - 例如 8,表示将代币数量除以 100000000 以获得其用户表示。 // 可选 - 此方法可用于提高可用性,但接口和其他协定不得期望存在这些值。 function totalSupply() public view returns (uint256) // 返回总代币供应量。 function balanceOf(address _owner) public view returns (uint256 balance) // 返回地址为 _owner 的另一个账户的账户余额。 function transfer(address _to, uint256 _value) public returns (bool success) // 将 _value 数量的代币转移到 _to,并且必须触发 Transfer 事件。如果消息调用者的账户余额没有足够的代币可供花费,则函数应该throw。 // 注意值为 0 的传输必须被视为正常传输,并触发 Transfer 事件。 function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) // 将 _value数量的代币从地址 _from 转移到地址 _to,并且必须触发 Transfer 事件。 // transferFrom 方法用于提现工作流程,允许合约代表您转移代币。例如,这可用于允许合约代表您转移代币和/或以子货币收取费用。除非 _from 账户通过某种机制故意授权了消息的发送者,否则该函数应该throw。 function approve(address _spender, uint256 _value) public returns (bool success) // 允许_spender多次从您的账户提款,最高可达_value金额。如果再次调用此函数,它将用 _value 覆盖当前限额。 // 注意:客户端应该确保在创建用户界面时,先将限额设置为 0,然后再为同一花费者将其设置为另一个值。尽管 Contract 本身不应该强制执行它,以允许向后兼容之前部署的 Contract function allowance(address _owner, address _spender) public view returns (uint256 remaining) // 返回 _spender 仍允许从 _owner 中提取的金额。 事件(Event)event Transfer(address indexed _from, address indexed _to, uint256 _value) // 必须在代币转移时触发,包括零价值转移。 // 创建新代币的代币合约应该在创建代币时触发 Transfer 事件,并将 _from 地址设置为 0x0。 event Approval(address indexed _owner, address indexed _spender, uint256 _value) // 必须在成功调用 approve(address _spender, uint256 _value) 时触发。 实现简单示例// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract MyToken { string public constant name = "Bob's Token"; string public constant symbol = "BBK"; uint8 public constant decimals = 18; uint16 private constant increase = 1000; uint256 public constant totalLimit = 27000000 * (10 ** decimals); uint256 public totalSupply = 0; address private owner; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); modifier checkAddress(address _addr) { require(address(_addr) != address(0), "Invalid address."); _; } modifier checkBalanceOf(address _addr, uint256 _value) { require(balanceOf[_addr] >= _value, "Insufficient balance"); _; } modifier checkOwner() { require(msg.sender == owner, "Not owner."); _; } constructor() { owner = msg.sender; } function mint(address _to) public checkOwner returns (uint256) { uint256 mintValue = increase * (10 ** decimals); require(totalLimit < (totalSupply + mintValue), "Out of limit."); totalSupply += mintValue; balanceOf[_to] += mintValue; return balanceOf[_to]; } function transfer(address _to, uint256 _value) public checkAddress(_to) checkBalanceOf(msg.sender, _value) returns (bool success){ balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; emit Transfer(msg.sender, _to, _value); return true; } function transferFrom(address _from, address _to, uint256 _value) public checkAddress(_to) checkBalanceOf(_from, _value) returns (bool success) { require(allowance[_from][msg.sender] >= _value, "No enough approve value."); allowance[_from][msg.sender] -= _value; balanceOf[_from] -= _value; balanceOf[_to] += _value; emit Transfer(_from, _to, _value); return true; } function approve(address _spender, uint256 _value) public returns (bool success){ allowance[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } } 注意事项由于本合约的编译版本为0.8.0,此版本具备整数溢出检查,所以可以不使用safeMath。快速示例使用Open zeppelin快速创建ERC-20合约// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract GLDToken is ERC20 { constructor(uint256 initialSupply) ERC20("Gold", "GLD") { _mint(msg.sender, initialSupply); } } 我们的合约通常通过[继承](https://solidity.readthedocs.io/en/latest/contracts.html#inheritance)来使用,在这里我们将 `ERC20` 重新用于基本标准实现以及 `name`、`symbol` 和 `decimals` 可选扩展。此外,我们正在创建一个代币的 `initialSupply`,该代币将被分配给部署合约的地址。(From: 《[ERC-20]()》) ## Publication Information - [Bob](https://paragraph.com/@bob-25/): Publication homepage - [All Posts](https://paragraph.com/@bob-25/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@bob-25): Subscribe to updates