Home | 简体中文 | 繁体中文 | 杂文 | 知乎专栏 | Github | OSChina 博客 | 云社区 | 云栖社区 | Facebook | Linkedin | 视频教程 | 打赏(Donations) | About
知乎专栏多维度架构微信号 netkiller-ebook | QQ群:128659835 请注明“读者”

13.2. ERC20 Token Solidity 0.4.24

https://theethereum.wiki/w/index.php/ERC20_Token_Standard

ERC20 “描述了实现代币合约的标准功能”,ERC20 是各个代币的标准接口。ERC20 代币仅仅是以太坊代币的子集。为了充分兼容 ERC20,开发者需要将一组特定的函数集成到他们的智能合约中,以便在高层面能够执行以下操作:

ERC20 提供的方法

13.2.1. 构造方法

原合约

			
pragma solidity ^0.4.21;

contract NetkillerToken {
  address public owner;
  string public name;
  string public symbol;
  uint public decimals;
  uint256 public totalSupply;

  event Transfer(address indexed from, address indexed to, uint256 value);

  /* This creates an array with all balances */
  mapping (address => uint256) public balanceOf;

  function NetkillerToken(uint256 initialSupply, string tokenName, string tokenSymbol, uint decimalUnits) public {
    owner = msg.sender;
    name = tokenName;
    symbol = tokenSymbol;
    decimals = decimalUnits;
    totalSupply = initialSupply * 10 ** uint256(decimals);
    balanceOf[msg.sender] = totalSupply;
  }

  /* Send coins */
  function transfer(address _to, uint256 _value) public {
    /* Check if the sender has balance and for overflows */
    require(balanceOf[msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to]);

    /* Add and subtract new balances */
    balanceOf[msg.sender] -= _value;
    balanceOf[_to] += _value;

    /* Notify anyone listening that this transfer took place */
    emit Transfer(msg.sender, _to, _value);
  }
}
			
			

新版合约

			
pragma solidity ^0.4.24;

contract NetkillerToken {
  address public owner;
  string public name;
  string public symbol;
  uint public decimals;
  uint256 public totalSupply;

  event Transfer(address indexed from, address indexed to, uint256 value);

  /* This creates an array with all balances */
  mapping (address => uint256) public balanceOf;

  constructor(uint256 initialSupply, string tokenName, string tokenSymbol, uint decimalUnits) public {
    owner = msg.sender;
    name = tokenName;
    symbol = tokenSymbol;
    decimals = decimalUnits;
    totalSupply = initialSupply * 10 ** uint256(decimals);
    balanceOf[msg.sender] = totalSupply;
  }

  /* Send coins */
  function transfer(address _to, uint256 _value) public {
    /* Check if the sender has balance and for overflows */
    require(balanceOf[msg.sender] >= _value && balanceOf[_to] + _value >= balanceOf[_to]);

    /* Add and subtract new balances */
    balanceOf[msg.sender] -= _value;
    balanceOf[_to] += _value;

    /* Notify anyone listening that this transfer took place */
    emit Transfer(msg.sender, _to, _value);
  }
}
			
			

13.2.2. 官方规定 Method 方法

所有的ERC20代币都是按照下面这些方法来定义的。下面我们讲解一下每个方法的作用。

13.2.2.1. name

function name() view public returns (string name)

返回string类型的ERC20代币的名字,例如:Netkiller Reader Coin

13.2.2.2. symbol

function symbol() view public returns (string symbol)

返回string类型的ERC20代币的符号,也就是代币的简称,例如:NRC。

13.2.2.3. decimals

function decimals() view public returns (uint decimals)

支持几位小数点后几位。如果设置为3。也就是支持0.001表示。

13.2.2.4. totalSupply

function totalSupply() view public returns (uint256 totalSupply)

发行代币的总量,可以通过这个函数来获取。所有智能合约发行的代币总量是一定的,totalSupply必须设置初始值。

13.2.2.5. balanceOf

function balanceOf(address _owner) public returns (uint256 balance)

输入地址,可以获取该地址代币的余额。

13.2.2.6. transfer

function transfer(address _to, uint256 _value) public returns (bool success)

调用transfer函数将自己的token转账给_to地址,_value为转账金额

13.2.2.7. approve

function approve(address _spender, uint256 _value) public returns (bool success)

批准_spender账户从自己的账户转移_value个token。可以分多次转移。

13.2.2.8. transferFrom

function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)

与approve搭配使用,approve批准之后,调用transferFrom函数来转移token。

13.2.2.9. allowance

function allowance(address _owner, address _spender) public returns (uint256 remaining)

返回_spender还能提取token的个数。

approve、transferFrom及allowance解释:账户A有1000个代币,想允许B账户随意调用100个代币。A账户按照以下形式调用approve函数approve(B,100)。当B账户想用这100个代币中的10个代币给C账户时,则调用transferFrom(A, C, 10)。这时调用allowance(A, B)可以查看B账户还能够调用A账户多少个token。

13.2.3. 事件

13.2.3.1. Transfer

event Transfer(address indexed _from, address indexed _to, uint256 _value)

当成功转移token时,一定要触发Transfer事件

13.2.3.2. Approval

event Approval(address indexed _owner, address indexed _spender, uint256 _value)

当调用approval函数成功时,一定要触发Approval事件