以太坊ERC20 Token合约代码分析
之前跟着公众号文章在个人私有链上发布过ERC20 的Token合约,当时稀里糊涂的,代码也没有细看,最近在做Solidity代码相关的复习,上次上完培训课之后都有点遗忘了,借此机会,整理一下ERC20 Token相关的知识点,以备以后使用。
0x0 ERC20 标准
EIPs/eip-20.md at master · ethereum/EIPs · GitHub
标准的内容比较简单,英文不算生僻,此处不再全部翻译,着重记录几个点。
合约代码里至少包含以下方法
name
可选,返回token的名称,例如“TedToken”。function name() view returns (string name)
symbol
可选,返回token的符号,比如“TEC”。function symbol() view returns (string symbol)
decimals
可选,返回token的精确小数点,通用是18。function decimals() view returns (uint8 decimals)
totalSupply
全部供应量,也就是发行量。function totalSupply() view returns (uint256 totalSupply)
balanceOf
查询余额,返回指定address的余额function balanceOf(address _owner) view returns (uint256 balance)
transfer
发送token,发送指定数目的token到指定账户,必须触发Transfer事件。如果余额不足,必须throw异常。另外,即使转账0个token,也必须向非0转账那样触发Transfer事件。
一般是owner向其他人发送代币。function transfer(address _to, uint256 _value) returns (bool success)
transferFrom
交易token,从一个地址向另外一个地址转账指定额度的token,必须触发Transfer事件,这个方法可以理解为一个收款流程,允许合约来代表token持有者发送代币。比如,合约可以帮助你向另外一个人发送token或者索要token。前提是token拥有者必须要通过某些机制对这个请求进行确认,比如通过MetaMask进行confirm。否则,执行将失败。
跟transfer一样,即使发送0代币,也要触发Transfer事件。function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
approve
批准额度,允许一个账户最多能从你的账户你取现指定额度。重复调用时,以最后一次的额度为主。为了防止攻击,最开始这个额度必须设置为0。function approve(address _spender, uint256 _value) returns (bool success)
allowance
跟approve对应,获得指定用户的批准额度。function allowance(address _owner, address _spender) view returns (uint256 remaining)
合约代码里至少包含以下事件
Transfer
任何token发送发生时,必须触发该事件,即使是0额度。
当一个token合约创建时,应该触发一个Transfer事件,token的发送方是0x0,也就是说凭空而来的token,简称空气币。event Transfer(address indexed _from, address indexed _to, uint256 _value)
Approval
当approve被调用时,需要触发该事件。event Approval(address indexed _owner, address indexed _spender, uint256 _value)
0x1 Token示例源码一
官方源码:Tokens/EIP20.sol at master · ConsenSys/Tokens · GitHub 我的源码:GitHub - xiongwei-git/Tokens: One EIP-20 Token Sample
这个示例源码比较简单,包含三个sol文件,分别是接口定义EIP20Interface,Token实现EIP20和Token管理类EIP20Factory。
- 首先看EIP20Interface,都是上文提到的标准接口和一些事件。
1 | contract EIP20Interface { |
- 着重需要看的是EIP20的代码实现,我通过一些注释来解释我对代码的理解,如下:
1 | import "./EIP20Interface.sol"; |
- 而Token管理类的源码比较简单,通过对EIP20的进一步封装,实现了创建Token的接口,并且对EIP20的合约代码做了保存,可以对一个合约是不是EIP20标准做检测。顺便说一句,这个管理类的几个方法对gas的消耗那不是一般的高啊。
1 | import "./EIP20.sol"; |
0x2 Token示例源码二
openzeppelin-solidity/contracts/token/ERC20 at master · OpenZeppelin/openzeppelin-solidity · GitHub