了解ERC-20代币智能合约
ERC-20是以太坊上最重要的智能合约标准之一。它已经成为以太坊区块链上用于可替换代币实现的所有智能合约的技术标准。
ERC-20定义了所有可替换的以太坊代币都应该遵守的通用规则列表。 因此,该代币标准使所有类型的开发者能够准确预测新代币在更大的以太坊系统中将如何工作。 这简化了开发者的任务,因为他们可以继续他们的工作,知道只要代币遵循规则,每次发布新的代币时就不需要重做每个新项目。
这里以接口的形式介绍了ERC-20必须实现的函数。 如果你不知道什么是接口:请查看我们关于使用Solidity进行OOP编程(opens in a new tab)的文章。
1pragma solidity ^0.6.0;23interface IERC20 {45 function totalSupply() external view returns (uint256);6 function balanceOf(address account) external view returns (uint256);7 function allowance(address owner, address spender) external view returns (uint256);89 function transfer(address recipient, uint256 amount) external returns (bool);10 function approve(address spender, uint256 amount) external returns (bool);11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}显示全部复制
下面逐行解释每个函数的用途。 在这之后,我们将展示一个ERC-20代币的简单实现。
取值器
1function totalSupply() external view returns (uint256);复制
返回存在的代币数量。 此函数是一个取值器,不会修改合约的状态。 请记住,Solidity中没有浮点数。 因此,大多数代币都会采用18位小数,并且会返回总供应量和其他结果,如下所示:1个代币100000000000000000。 你需要在处理代币时格外注意,并不是每个代币都有18位小数。
1function balanceOf(address account) external view returns (uint256);复制
返回地址拥有的代币数量(account
)。 此函数是一个取值器,不会修改合约的状态。
1function allowance(address owner, address spender) external view returns (uint256);复制
ERC-20标准使一个地址能够允许另一个地址从中检索代币。 此取值器返回允许spender
代表owner
花费的剩余代币数量。 此函数是一个取值器,不会修改合约的状态,并且默认应返回0。
函数
1function transfer(address recipient, uint256 amount) external returns (bool);复制
将代币的amount
从函数调用者地址(msg.sender
) 移动到接收者地址。 此函数发出稍后定义的Transfer
事件。 如果可进行转账,它将返回true。
1function approve(address spender, uint256 amount) external returns (bool);复制
设置允许spender
从函数调用方(msg.sender
)余额转账的allowance
的数额。 此函数发出Approval事件。 此函数返回是否成功设置了余量。
1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);复制
使用余量机制将代币的amount
从sender
移动到recipient
。 然后从调用者的余量中扣除该数额。 此函数发出Transfer
事件。
事件
1event Transfer(address indexed from, address indexed to, uint256 value);复制
将代币(值)的数量从from
地址发送到to
地址时会发出此事件。
在铸造新代币时,转账通常会在 from
0x00..0000 地址进行,而在销毁代币时,转账会在 to
0x00..0000 地址进行。
1event Approval(address indexed owner, address indexed spender, uint256 value);复制
当owner
批准要由spender
使用的代币数量(value
)时,将发出此事件。
ERC-20代币的基本实现
下面是ERC-20代币的最简单代码:
1pragma solidity ^0.8.0;23interface IERC20 {45 function totalSupply() external view returns (uint256);6 function balanceOf(address account) external view returns (uint256);7 function allowance(address owner, address spender) external view returns (uint256);89 function transfer(address recipient, uint256 amount) external returns (bool);10 function approve(address spender, uint256 amount) external returns (bool);11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}171819contract ERC20Basic is IERC20 {2021 string public constant name = "ERC20Basic";22 string public constant symbol = "ERC";23 uint8 public constant decimals = 18;242526 mapping(address => uint256) balances;2728 mapping(address => mapping (address => uint256)) allowed;2930 uint256 totalSupply_ = 10 ether;313233 constructor() {34 balances[msg.sender] = totalSupply_;35 }3637 function totalSupply() public override view returns (uint256) {38 return totalSupply_;39 }4041 function balanceOf(address tokenOwner) public override view returns (uint256) {42 return balances[tokenOwner];43 }4445 function transfer(address receiver, uint256 numTokens) public override returns (bool) {46 require(numTokens <= balances[msg.sender]);47 balances[msg.sender] = balances[msg.sender]-numTokens;48 balances[receiver] = balances[receiver]+numTokens;49 emit Transfer(msg.sender, receiver, numTokens);50 return true;51 }5253 function approve(address delegate, uint256 numTokens) public override returns (bool) {54 allowed[msg.sender][delegate] = numTokens;55 emit Approval(msg.sender, delegate, numTokens);56 return true;57 }5859 function allowance(address owner, address delegate) public override view returns (uint) {60 return allowed[owner][delegate];61 }6263 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {64 require(numTokens <= balances[owner]);65 require(numTokens <= allowed[owner][msg.sender]);6667 balances[owner] = balances[owner]-numTokens;68 allowed[owner][msg.sender] = allowed[owner][msg.sender]-numTokens;69 balances[buyer] = balances[buyer]+numTokens;70 emit Transfer(owner, buyer, numTokens);71 return true;72 }73}显示全部复制
ERC-20 代币标准的另一个优秀实现是 OpenZepelin ERC-20 实现(opens in a new tab)。
上次修改时间: @nhsz(opens in a new tab), 2023年8月15日