ERC20标准的简述

ERC是Ethereum Request for Comments的缩写,代表以太坊开发者提交的协议提案。ERC20可能是其中最广为人知的标准,协议规定了具有可替代性Token的一组基本接口,包括代币符号、发行量、转账、授权等。

所谓可替代性Token指代币之间无差异,同等数量的两笔代币价值相等。所以类似交易所里的那些代币都是可互换的,使用相同的标准就使得代币之间可以兑换,也以为着这些代币可以用于不同的平台和项目。

ERC20标准规定了哪些内容

ERC20的接口如下:

interface ERC20 {
    // 方法
    function name() view returns (string name);
    function symbol() view returns (string symbol);
    function decimals() view returns (uint8 decimals);

    function totalSupply() view returns (uint256 totalSupply);
    function balanceOf(address _owner) view returns (uint256 balance);
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) view returns (uint256 remaining);
    // 事件
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

totalSupply:规定了代币的总量,外部可以通过调用这个函数来获得代币总量是多少;
balanceOf:获取某地址的代币余额;
transfer:调用transfer函数将自己的token转账给_to地址,_value为转账个数;
approve:批准_spender账户从自己的账户转移_value个token。可以分多次转移;
transferFrom:用于第三方(_spender)从被授权的账户转账到目标账户;
allowance:返回_spender还能提取token的个数;

举个例子,假设账户A有1000个代币:

授权B可以调用其中100个代币 —— approve(B,100);
B从这100个代币中转10个给C —— transferFrom(A,C,10);
看B还能调用A账户代币的剩余个数 —— allowance(A,B);

这种交易模式是用来转让部分代币给另一个合约使用的。

 

ok,知道了这个标准定义了哪些内容,那我们如果要发行自己的token要怎么做?

1、继承这些接口,补充这些接口的具体实现;
2、增加一些其他的必要的方法,实现其他功能,比如销毁token、增发token;

OpenZeppelin的Token中实现了ERC20的一个安全的合约代码,我们在写自己的代币的时候也可以直接继承OpenZeppelin中的合约。我们可以简单看看OpenZeppelin的实现。

contract DetailedERC20 is ERC20 {

  using SafeMath for uint256;
  mapping(address => uint256) balances;
  mapping (address => mapping (address => uint256)) internal allowed;

  string public name;
  string public symbol;
  uint8 public decimals;
  uint256 totalSupply_;

  constructor(string _name, string _symbol, uint8 _decimals) public {
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
  }

  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  function transfer(address _to, uint256 _value) public returns (bool) {
    //做相关的合法验证
    require(_to != address(0));
    require(_value <= balances[msg.sender]);
    // msg.sender余额中减去额度,_to余额加上相应额度
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    //触发Transfer事件
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

  function balanceOf(address _owner) public view returns (uint256) {
    return balances[_owner];
  }

  function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
    // 做合法性检查
    require(_to != address(0));
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    //_from余额减去相应的金额
    //_to余额加上相应的金额
    //msg.sender可以从账户_from中转出的数量减少_value
    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    // 触发Transfer事件
    emit Transfer(_from, _to, _value);
    return true;
  }

  function approve(address _spender, uint256 _value) public returns (bool) {
    //记录msg.sender允许_spender动用的token
    allowed[msg.sender][_spender] = _value;
    //触发Approval事件
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  function allowance(address _owner, address _spender) public view returns (uint256) {
    //允许_spender从_owner中转出的token数
    return allowed[_owner][_spender];
  }
}

上面是对ERC20的相关实现,只是一部分,并不全面。另一方面,OpenZeppelin还有一些其他的方法实现对ERC20进行了补充,比如BurnableToken.sol,MintableToken.sol,TokenTimelock.sol,SafeERC20.sol等,从而实现销毁token,增发token,设置交易锁定期以及安全操作库。

感兴趣的可以去看源码:https://openzeppelin.org/

ERC20 并不完美

1、误用transfer转代币到合约地址,导致代币丢失。转移ERC20 token有两种方式:1) 调用approve授权另一个合约,再调用transferFrom发送代币给该合约 2) 调用transfer发送给钱包地址 。如果对合同地址调用 transfer函数的调用将导致接收方合同内的token丢失,令牌将永远不会被访问。

2、ERC20标准无法通过接收方合同处理传入的交易。缺少对交易的判断和处理最大的弊病是没有办法通过合同处理传入的token交易,也没有办法拒绝任何不支持的token。

为此,一些改进的标准也被提出来,比如ERC233和ERC827。ERC223和ERC827保留了ERC20标准中已经被广泛使用的部分,并在此基础上进行了升级,以提高易用性和可扩展性。

ERC233标准为了避免不符合发送令牌的合同内的意外丢失令牌的可能性,允许用户通过一个函数调用发送到任何地方他们的令牌。收件人是否是合同是没有区别的,没有必要了解令牌合约如何为常规用户发送令牌。另外,ERC233允许合同开发人员处理传入令牌中的交易,合约将尝试在接收方合约中调用tokenFallback函数。如果接收方没有tokenFallback函数,合约事务将失败,tokenFallback函数可用于处理传入事务。
 
ERC-20标准的另一个扩展是ERC827。 它允许转让通证并允许持有人允许第三方使用通证。 以太坊上的通证可以被 其他应用程序重复使用,这其中也包括钱包和交易所。 当需要支持第三方动态消费限额调整时这一点非常有用。

重要的是,这两个改进版本都与ERC20兼容。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值