ERC20 标准只包括接口,并非指标准的代码,而是只要满足了ERC20的接口,你接口包含ERC20 所列出的所有的接口,就代表你满足了ERC20的标准。至于合约中的方法是如何实现的并不关心,合约逻辑如何实现没有强制要求。
ERC20标准的核心函数
-
totalSupply()
: token 总量 -
balanceOf(address account)
: 某一个账户的当前余额 -
transfer(address recipient, uint256 amount)
: 把账户的余额,由当前调用者发送到另一个账户中,是一个写入方法,所以会向链外 暴露出一个标准的transfer事件,通过transfer 可以查看token的流转。 -
approve(address spender, uint256 amount)
: 是一个批准,代表着把我账户中数量批准给另一个账户。通过allowance 方法可以查询某一个账户对另一个账户的批准额度有多少。approve 与 transfer 是联合使用的。 -
transferFrom(address sender, address recipient, uint256 amount)
: 我们向另一合约存款的时候,另一个合约必须要调用transferFrom,才能把我们账户中的token拿到他的合约中。 -
allowance(address owner, address spender)
: 查看一个地址被授权的代币额度。
事件
Transfer
: 当代币转移时触发。Approval
: 当调用approve()
授权代币使用时触发。
代码
interface IERC20 {
function totalSupply() external view returns(uint); // 代表当前合约的token总量
function balanceOf(address account) external view returns (uint);// 某一个账户的当前余额
function transfer(address recipient, uint amount) external returns (bool); // 由当前调用者发送到另一个账户中,是一个写入方法
function allowance(address owner, address spender) external view returns (uint);
// 某一个账户对另一个账户的批准额度有多少
function approve(address spender, uint amount) external returns(bool); // 批准,代表把我账户的数量批准给另一个账户
function transferFrom(address sender, address recipient, uint amount) external returns (boll); // 向另一个合约存款时,另一个合约要调用transferFrom,才能把我们账户的token拿到他的合约中
function Transfer(address indexed from, address indexed to, uint amount);
function Approval(address indexed owner, address indexed spender, uint amount);
}
contract ERC20 is IERC20 {
uint public totalSupply; // 代表当前合约的token总量
mapping(address => uint) public balanceOf; // 地址-> 数字,账本
mapping(address => mapping(address => uint)) public allowance; // 批准映射,一个嵌套映射。发送者的地址 -> 被批准地址 -> 数量
string public name = "Test"; // token名称
string public symbol = "TEST"; // token的缩写,符号
uint8 public decimals = 18; // token的精度,会有18个0的小数
// 发送方法
function transfer(address recipient, uint amount) external returns (bool){
balanceOf[msg.sender] -= amount; // 发送者账户 - 数量
balanceOf[recipient] += amount; // 接受者账户 + 数量
emit Transfer(msg.sender, recipient, amount); // 触发事件,触发标准的transfer事件
return true;
}
// 批准方法,修改批准映射
function approve(address spender, uint amount) external returns(bool){
allowance[msg.sender][spender] = amount; // spender被授权账户
emit Approval(msg.sender, spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint amount) external returns (boll){
allowance[sender][msg.sender] -= amount; // 给发送者对应被批准账户(当前的消息调用者) 他的被批准额度的映射中 - 这次要发送的数量
balanceOf[sender] -= amount; // 从发送者的账户中 - 额度
balanceOf[recipient] += amount; // 在接收者账户中 + 额度
emit Transfer(sender, recipient, amount); // 触发事件
return true;
}
function mint(uint amount) external { // 铸币方法, 一般是有权限控制的
balanceOf[msg.sender] += amount; // 消息调用者的账户 + 数量
totalSupply += amount; // 合约的供应总链 + 数量
emit Transfer(address(0), msg.sender, amount);
}
function burn(uint amount) external { // 销毁方法
balanceOf[msg.sender] -= amount; // 消息调用者的账户 - 数量
totalSupply -= amount; // 合约的供应总链 - 数量
emit Transfer(msg.sender, address(0), amount); // 发送0地址,代表销毁事件
}
}