什么是ERC20 token

市面上出现了大量的用ETH做的代币,他们都遵守REC20协议,那么我们需要知道什么是REC20协议。

概述

token代表数字资产,具有价值,但是并不是都符合特定的规范。

基于ERC20的货币更容易互换,并且能够在Dapps上相同的工作。

新的标准可以让token更兼容,允许其他功能,包括投票标记化。操作更像一个投票操作

Token的持有人可以完全控制资产,遵守ERC20的token可以跟踪任何人在任何时间拥有多少token.基于eth合约的子货币,所以容易实施。只能自己去转让。

标准化非常有利,也就意味着这些资产可以用于不同的平台和项目,否则只能用在特定的场合。

ERC20 Token标准(Github)

序言

EIP: 20 
Title: ERC-20 Token Standard 
Author: Fabian Vogelsteller fabian@ethereum.org, Vitalik Buterin vitalik.buterin@ethereum.org 
Type: Standard 
Category: ERC 
Status: Accepted 
Created: 2015-11-19

总结

token的接口标准

抽象

以下标准允许在智能合约中实施标记的标记API。 该标准提供了转移token的基本功能,并允许token被批准,以便他们可以由另一个在线第三方使用。

动机

标准接口可以让Ethereum上的任何令牌被其他应用程序重新使用:从钱包到分散式交换。

规则

Token

方法

注意:调用者必须处理返回falsereturns (bool success).调用者绝对不能假设返回false的情况不存在。

name

返回这个令牌的名字,比如"MyToken".

可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

  1. function name() constant returns (string name)

symbol

返回令牌的符号,比如HIX.

可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

  1. function symbol() constant returns (string symbol)

decimals

返回token使用的小数点后几位, 比如 8,表示分配token数量为100000000

可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。

  1. function decimals() constant returns (uint8 decimals)

totalSupply

返回token的总供应量。

  1. function totalSupply() constant returns (uint256 totalSupply)

balanceOf

返回地址是_owner的账户的账户余额。

  1. function balanceOf(address _owner) constant returns (uint256 balance)

transfer

转移_value的token数量到的地址_to,并且必须触发Transfer事件。 如果_from帐户余额没有足够的令牌来支出,该函数应该被throw

创建新令牌的令牌合同应该在创建令牌时将_from地址设置为0x0触发传输事件。

注意 0值的传输必须被视为正常传输并触发传输事件。

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

transferFrom

从地址_from发送数量为_value的token到地址_to,必须触发Transfer事件。

transferFrom方法用于提取工作流,允许合同代您转移token。这可以用于例如允许合约代您转让代币和/或以子货币收取费用。除了_from帐户已经通过某种机制故意地授权消息的发送者之外,该函数**应该**throw。

注意 0值的传输必须被视为正常传输并触发传输事件。

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

approve

允许_spender多次取回您的帐户,最高达_value金额。 如果再次调用此函数,它将以_value覆盖当前的余量。

注意:为了阻止向量攻击,客户端需要确认以这样的方式创建用户接口,即将它们设置为0,然后将其设置为同一个花费者的另一个值。虽然合同本身不应该强制执行,允许向后兼容以前部署的合同兼容性

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

allowance

返回_spender仍然被允许从_owner提取的金额。

  1. function allowance(address _owner, address _spender) constant returns (uint256 remaining)

Events

Transfer

当token被转移(包括0值),必须被触发。

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

Approval

当任何成功调用approve(address _spender, uint256 _value)后,必须被触发。

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

实施

在Ethereum网络上部署了大量符合ERC20标准的令牌。 具有不同权衡的各种团队已经编写了不同的实施方案:从节省gas到提高安全性。

示例实现可在

在调用之前添加力0的实施“批准”了

ERC20 Token标准接口

以下是一个接口合同,声明所需的功能和事件以符合ERC20标准:

  1. // https://github.com/ethereum/EIPs/issues/20
  2. contract ERC20 {
  3. function totalSupply() constant returns (uint totalSupply);
  4. function balanceOf(address _owner) constant returns (uint balance);
  5. function transfer(address _to, uint _value) returns (bool success);
  6. function transferFrom(address _from, address _to, uint _value) returns (bool success);
  7. function approve(address _spender, uint _value) returns (bool success);
  8. function allowance(address _owner, address _spender) constant returns (uint remaining);
  9. event Transfer(address indexed _from, address indexed _to, uint _value);
  10. event Approval(address indexed _owner, address indexed _spender, uint _value);
  11. }

大部分Ethereum主要标记符合ERC20标准。

一些令牌包括描述令牌合同的进一步信息:

  1. string public constant name = "Token Name";
  2. string public constant symbol = "SYM";
  3. uint8 public constant decimals = 18; // 大部分都是18

如何工作?

以下是令牌合约的一个片段,用于演示令牌合约如何维护Ethereum帐户的令牌余额

  1. contract TokenContractFragment {
  2. // Balances 保存地址的余额
  3. mapping(address => uint256) balances;
  4. // 帐户的所有者批准将金额转入另一个帐户
  5. mapping(address => mapping (address => uint256)) allowed;
  6. // 特定帐户的余额是多少?
  7. function balanceOf(address _owner) constant returns (uint256 balance) {
  8. return balances[_owner]; //从数组中取值
  9. }
  10. // 将余额从所有者帐户转移到另一个帐户
  11. function transfer(address _to, uint256 _amount) returns (bool success) {
  12. //判断条件 发送者余额>=要发送的值 发送的值>0 接收者余额+发送的值>接收者的余额
  13. if (balances[msg.sender] >= _amount
  14. && _amount > 0
  15. && balances[_to] + _amount > balances[_to]) {
  16. balances[msg.sender] -= _amount; //发送者的余额减少
  17. balances[_to] += _amount; //接收者的余额增加
  18. return true;
  19. } else {
  20. return false;
  21. }
  22. }
  23. // 发送 _value 数量的token从地址 _from 到 地址 _to
  24. // transferFrom方法用于提取工作流程,允许合同以您的名义发送令牌,例如“存入”到合同地址和/或以子货币收取费用; 该命令应该失败,除非_from帐户通过某种机制故意地授权消息的发送者; 我们提出这些标准化的API来批准:
  25. function transferFrom(
  26. address _from,
  27. address _to,
  28. uint256 _amount
  29. ) returns (bool success) {
  30. //和上面一样的校验规则
  31. if (balances[_from] >= _amount
  32. && allowed[_from][msg.sender] >= _amount
  33. && _amount > 0
  34. && balances[_to] + _amount > balances[_to]) {
  35. balances[_from] -= _amount;
  36. allowed[_from][msg.sender] -= _amount; //减少发送者的批准量
  37. balances[_to] += _amount;
  38. return true;
  39. } else {
  40. return false;
  41. }
  42. }
  43. // 允许_spender多次退出您的帐户,直到_value金额。 如果再次调用此函数,它将以_value覆盖当前的余量。
  44. function approve(address _spender, uint256 _amount) returns (bool success) {
  45. allowed[msg.sender][_spender] = _amount; //覆盖当前余量
  46. return true;
  47. }
  48. }

token余额

假设token合约内有两个持有者

  • 0x1111111111111111111111111111111111111111有100个单位
  • 0x2222222222222222222222222222222222222222有200个单位

那么这个合约的balances结构就会存储下面的内容

  1. balances[0x1111111111111111111111111111111111111111] = 100
  2. balances[0x2222222222222222222222222222222222222222] = 200

那么,balanceOf(...)就会返回下面的结果

  1. tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 100
  2. tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 200

转移token的余额

如果0x1111111111111111111111111111111111111111想要转移10个单位给0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111会执行下面的函数

  1. tokenContract.transfer(0x2222222222222222222222222222222222222222, 10)

token合约的transfer(...)方法将会改变balances结构中的信息

  1. balances[0x1111111111111111111111111111111111111111] = 90
  2. balances[0x2222222222222222222222222222222222222222] = 210

balanceOf(...)调用就会返回下面的信息

  1. tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 90
  2. tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 210

从token余额批准和转移

如果0x1111111111111111111111111111111111111111想要批准0x2222222222222222222222222222222222222222传输一些token到0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111会执行下面的函数

  1. tokenContract.approve(0x2222222222222222222222222222222222222222, 30)

然后allowed(这里官方文档写的是approve,很明显是错的)结构就会存储下面的内容

  1. tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 30

如果0x2222222222222222222222222222222222222222想要晚点转移token从0x1111111111111111111111111111111111111111到他自己,0x2222222222222222222222222222222222222222将要执行transferFrom(...)函数

  1. tokenContract.transferFrom(0x1111111111111111111111111111111111111111, 20)

balances的信息就会变成下面的

  1. tokenContract.balances[0x1111111111111111111111111111111111111111] = 70
  2. tokenContract.balances[0x2222222222222222222222222222222222222222] = 230

然后allowed就会变成下面的内容

  1. tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 10

0x2222222222222222222222222222222222222222仍然可以从0x1111111111111111111111111111111111111111转移10个单位。

  1. tokenContract.balanceOf(0x1111111111111111111111111111111111111111) will return 70
  2. tokenContract.balanceOf(0x2222222222222222222222222222222222222222) will return 230

简单修复的token合约

以下是一个样本令牌合同,固定供应量为1000000单位,最初分配给合同所有者:

  1. pragma solidity ^0.4.8;
  2. // ----------------------------------------------------------------------------------------------
  3. // Sample fixed supply token contract
  4. // Enjoy. (c) BokkyPooBah 2017. The MIT Licence.
  5. // ----------------------------------------------------------------------------------------------
  6. // ERC Token Standard #20 Interface
  7. // https://github.com/ethereum/EIPs/issues/20
  8. contract ERC20Interface {
  9. // 获取总的支持量
  10. function totalSupply() constant returns (uint256 totalSupply);
  11. // 获取其他地址的余额
  12. function balanceOf(address _owner) constant returns (uint256 balance);
  13. // 向其他地址发送token
  14. function transfer(address _to, uint256 _value) returns (bool success);
  15. // 从一个地址想另一个地址发送余额
  16. function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
  17. //允许_spender从你的账户转出_value的余额,调用多次会覆盖可用量。某些DEX功能需要此功能
  18. function approve(address _spender, uint256 _value) returns (bool success);
  19. // 返回_spender仍然允许从_owner退出的余额数量
  20. function allowance(address _owner, address _spender) constant returns (uint256 remaining);
  21. // token转移完成后出发
  22. event Transfer(address indexed _from, address indexed _to, uint256 _value);
  23. // approve(address _spender, uint256 _value)调用后触发
  24. event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  25. }
  26. //继承接口后的实例
  27. contract FixedSupplyToken is ERC20Interface {
  28. string public constant symbol = "FIXED"; //单位
  29. string public constant name = "Example Fixed Supply Token"; //名称
  30. uint8 public constant decimals = 18; //小数点后的位数
  31. uint256 _totalSupply = 1000000; //发行总量
  32. // 智能合约的所有者
  33. address public owner;
  34. // 每个账户的余额
  35. mapping(address => uint256) balances;
  36. // 帐户的所有者批准将金额转入另一个帐户。从上面的说明我们可以得知allowed[被转移的账户][转移钱的账户]
  37. mapping(address => mapping (address => uint256)) allowed;
  38. // 只能通过智能合约的所有者才能调用的方法
  39. modifier onlyOwner() {
  40. if (msg.sender != owner) {
  41. throw;
  42. }
  43. _;
  44. }
  45. // 构造函数
  46. function FixedSupplyToken() {
  47. owner = msg.sender;
  48. balances[owner] = _totalSupply;
  49. }
  50. function totalSupply() constant returns (uint256 totalSupply) {
  51. totalSupply = _totalSupply;
  52. }
  53. // 特定账户的余额
  54. function balanceOf(address _owner) constant returns (uint256 balance) {
  55. return balances[_owner];
  56. }
  57. // 转移余额到其他账户
  58. function transfer(address _to, uint256 _amount) returns (bool success) {
  59. if (balances[msg.sender] >= _amount
  60. && _amount > 0
  61. && balances[_to] + _amount > balances[_to]) {
  62. balances[msg.sender] -= _amount;
  63. balances[_to] += _amount;
  64. Transfer(msg.sender, _to, _amount);
  65. return true;
  66. } else {
  67. return false;
  68. }
  69. }
  70. //从一个账户转移到另一个账户,前提是需要有允许转移的余额
  71. function transferFrom(
  72. address _from,
  73. address _to,
  74. uint256 _amount
  75. ) returns (bool success) {
  76. if (balances[_from] >= _amount
  77. && allowed[_from][msg.sender] >= _amount
  78. && _amount > 0
  79. && balances[_to] + _amount > balances[_to]) {
  80. balances[_from] -= _amount;
  81. allowed[_from][msg.sender] -= _amount;
  82. balances[_to] += _amount;
  83. Transfer(_from, _to, _amount);
  84. return true;
  85. } else {
  86. return false;
  87. }
  88. }
  89. //允许账户从当前用户转移余额到那个账户,多次调用会覆盖
  90. function approve(address _spender, uint256 _amount) returns (bool success) {
  91. allowed[msg.sender][_spender] = _amount;
  92. Approval(msg.sender, _spender, _amount);
  93. return true;
  94. }
  95. //返回被允许转移的余额数量
  96. function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
  97. return allowed[_owner][_spender];
  98. }
  99. }

注意的是,最后的例子中allowed限定的第二维的参数是调用者的转移数量,而开始的例子是接收者的数量。

参考资料

【Ethereum】以太坊ERC20 Token标准完整说明的更多相关文章

  1. 零门槛,包教会。让你在5分钟内使用以太坊ERC20智能合约发行属于自己的空气币

    前言 目前区块链是互联网中最最火的风口,没有之一.我周围的很多朋友也加入了“炒币”行列,但很不幸,几乎都被“割韭菜”了.而经过我的几天研究,发现,如果自己要发行一种空气币,简直太简单了.只需要下面几个 ...

  2. 以太坊 ERC20 与 ERC721 深度解密

    去年11月份的一段时间,Ethereum网络突然变的特别拥堵,原因是兴起了一款以太坊养猫的Dapp游戏,超级可爱的猫形象,再加上配种,繁殖和拍卖等丰富的玩法,风靡了币圈. 一时间币圈大大小小的人都在撸 ...

  3. 以太坊ERC20代币开发

    以太坊ERC20代币开发首先需要对以太坊,代币,ERC20,智能合约等以太坊代币开发中的基本概念有了解.根据我们的示例代码就可以发行自己的以太坊代币. 什么是ERC20 可以把ERC20简单理解成以太 ...

  4. 以太坊erc20转账失败的情况和原因

    以太坊erc20转账失败的情况和原因 eth转账失败有多种情况,除了手续费过低以外(Out of gas),众筹额度满了(Bad instruction)也会失败链上转账有可能失败,转账失败转账的币退 ...

  5. 一键创建以太坊ERC20代币教程

    30秒极速创建以太坊ERC20代币 傻瓜式创建,界面化创建,自动创建代币,简单好用 合约采用新版 5.10 新版合约编译器,合约代码100%安全无任何漏洞 下面是详细的使用和创建教程 1.点击创建ER ...

  6. 以太坊ERC20代币合约案例

    一.ERC20代币合约与web3调用 ERC20代币合约在小白看来觉得很高大上,但其实就是一个代币的定义标准,方便其他dapp统一调用各种代币的方法.如图: 二.ERC20合约标准 [官方链接] co ...

  7. 基于以太坊的Token开发步骤

    Token开发步骤 一.准备工具1.安装以太坊brew tap ethereum/ethereumbrew install ethereum2.node:brew install nodejs3.安装 ...

  8. 10分钟 5步 发布以太坊 ERC20 代币

    1.安装 METAMASK Brings Ethereum to your browser 一个可以浏览器上进行操作的以太坊钱包,推荐 Chrome. Chrome 插件安装地址: https://c ...

  9. ethereum(以太坊)(一)

    从这周开始,开始学习以太坊开发--solidity,开始决定往区块链方向发展,毕竟区块链技术应用广泛.一开始接触solidity开发语言不太习惯,毕竟一直在学习python语法,有很多都不能接受.有难 ...

随机推荐

  1. (C/C++学习笔记) 十一. 数组

    十一. 数组 ● 基本概念 数组:数组是一组在内存中依次连续存放的(数组所有元素在内存中的地址是连续的).具有同一类型的数据变量所组成的集合体.其中的每个变量称为数组元素,它们属于同一种数据类型,数组 ...

  2. DevExpress v17.2新版亮点—Bootstrap篇(一)

    用户界面套包DevExpress v17.2日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了Bootstrap Controls v17.2 的CardView.Charts ...

  3. SharePoint Foundation 搜索-PowerShell

    1. 显示搜索服务信息 Get-SPSearchService 2. 显示搜索服务实例 Get-SPSearchServiceInstance 3. 获取指定搜索服务实例 $ssInstance = ...

  4. REST easy with kbmMW #3 – SSL

    我在前两篇文章中展示了“REST easy with kbmMW”文章,如何使用kbmMW制作REST服务器,以及如何使用该REST服务器轻松地从数据库返回和存储数据,所有这些都在不到30行的真实数据 ...

  5. kbmMW集成JWT

    如果对JWT不熟悉,需要先补下功课:初步理解JWT并实践使用 然后找到开源项目:https://github.com/paolo-rossi/delphi-jose-jwt

  6. myeclipse 与 webstrom 免解析node_modules 的方法

    myeclipse :   1.项目文件夹上:右键  properites  - > 搜索 filter  -->resouce filters 2.  webStrom : File - ...

  7. HDU 1518 Square(DFS)

    Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end ...

  8. vue 之 .$mount()

    $mount():手动挂载 当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中: 假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载.例如: <div id=&quo ...

  9. 学习magento要学哪些知识

    php框架水平,具体点的就是大名鼎鼎的ZF框架.别急,先还是熟悉下OSC吧,主要是热身下商城的那些业务流的知识,基本的数据流程.自己做模板的话CSS2.0水平还不能太低.JS框架JQ吧相对简单点.当然 ...

  10. OK335xS UART device registe hacking

    /************************************************************************* * OK335xS UART device reg ...