资讯专栏INFORMATION COLUMN

以太坊标准令牌系列之同质化令牌ERC20

Little_XM / 2819人阅读

摘要:目前市面上,凡是基于以太坊的令牌,在交易所上线交易的均是令牌,那么今天我们就来聊聊令牌的标准方案吧。

0x00 写在前面

众所周知,以太坊在现阶段最大的应用就是令牌发行,而在以太坊中有很多类型的令牌,最著名的当属ERC20了,但是对于其他几种令牌类型,可能还有一些朋友不知道,所以最近规划了一个系列,就是以太坊标准令牌系列。

目前市面上,凡是基于以太坊的令牌,在交易所上线交易的均是ERC20令牌,那么今天我们就来聊聊ERC20令牌的标准方案吧。

0x01 ERC20标准制定动机

在基于以太坊发行令牌时,如果各个令牌发行方都使用自有标准去发行令牌,那对于钱包开发者以及交易所对接成本是极其高昂了,因为他们需要为每一种令牌去独立进行对接,为了降低钱包开发者以及交易所的对接成本,以太坊社区制定了一个关于令牌的发行标准。

该标准中主要包含了,令牌的转移,地址余额的获取等方法。

0x02 ERC20标准规范

一个令牌的合约,一般需要令牌的发行量,每个地址的余额,令牌的转移等方法, 而ERC20标准就是将这些最常用又是必不可少的方法,对此进行标准化,方便开发者进行令牌合约的开发,也方便钱包开发者以及交易所对接成本降到最低。

其中,定义了三类,方法、属性、事件。

下面介绍这些标准方法:

A. 方法(Method) 1、totalSupply:令牌总量
函数原型

</>复制代码

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

方法 该方法用于获取令牌总发行量

2、balanceOf:获取余额
函数原型

</>复制代码

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

方法 该方法用于获取地址 _owner 的令牌余额

3、transfer:转账
函数原型

</>复制代码

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

方法 该方法用于将调用令牌合约的地址中的_value个令牌转给_to 地址

4、transferFrom:转账
函数原型

</>复制代码

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

方法 该方法用于从_from 地址中发送_value 个令牌给_to地址。

当你希望能够使用其他智能合约控制你的令牌转移,则可以使用transferFrom方法,而使用transferFrom方法有一个前提条件,那就是需要调用者需要得到 _from 地址的授权,才可以进行令牌转移的操作。而如何进行授权,我们接下来会介绍。

5、approve:授权
函数原型

</>复制代码

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

方法 允许 _spender 地址从你的账户中转移 _value 个令牌到任何地方。

当你设置了一个 _value 之后,_spender 地址可以分任何多次将令牌进行转移,直至_value为0.

6、allowance:获取被授权令牌余额
函数原型

</>复制代码

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

方法 获取 _owner 地址授权给 _spender 地址可以转移的令牌的余额。

B. 事件(Event)

事件是EVM内置的日志功能,而且在DAPP中,我们可以通过JS来监听事件的回调。在ERC-20令牌中,定义了以下事件:

1、Transfer:转移令牌
事件定义

</>复制代码

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

当进行令牌转移时,需要触发调用该事件。其中记录了令牌发送者_from,令牌接受者_to ,令牌发送量_value.

2、Approval:授权事件
事件定义

</>复制代码

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

当进行授权时,需要触发调用该事件,其中记录了授权者_owner,被授权者_spender,授权令牌量_value

0x03 ERC20令牌接口

通过以上的标准,我们可以了解到一个遵守ERC20令牌标准的令牌合约需要实现的方法,以下是通过规范实现的一个ERC20令牌的接口。

</>复制代码

  1. contract EIP20Interface {
  2. ///////////////////////////// 方法 ///////////////////////////////////
  3. // 获取令牌发行量
  4. // 注意:constant的修饰符是提示该方法中不能进行变量的修改。
  5. // 但编译器不会强制校验。
  6. // @return uint256 totalSupply 总发行量
  7. function totalSupply() constant returns (uint256 totalSupply)
  8. // 获取指定地址
  9. // @param address _owner 想要获取的地址
  10. // @return uint256 balance 令牌余额
  11. function balanceOf(address _owner) public view returns (uint256 balance);
  12. // 从`msg.sender`中发送`_value`个令牌给`_to`
  13. // @param address _to 接收令牌的地址
  14. // @param uint256 _value 发送的令牌数量
  15. // @return bool success 发送令牌成功状态
  16. function transfer(address _to, uint256 _value) public returns (bool success);
  17. // 从`_from`地址发送`_value`令牌到`_to`地址
  18. // 需要满足条件,需要被`_from`地址授权给`msg.sender`
  19. // @param address _from 发送者地址
  20. // @param address _to 接收者地址
  21. // @param uint256 _value 发送的令牌数量
  22. // @return bool success 发送令牌成功状态
  23. function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
  24. // `msg.sender`授权`_spender`地址可以任意转移`_value`数量的令牌
  25. // @param address _spender 被授权发送令牌的地址
  26. // @param uint256 _value 授权发送令牌的数量
  27. // @return bool success 授权成功状态
  28. function approve(address _spender, uint256 _value) public returns (bool success);
  29. /// @param _owner The address of the account owning tokens
  30. /// @param _spender The address of the account able to transfer the tokens
  31. /// @return Amount of remaining tokens allowed to spent
  32. // 获取被授权限额
  33. // @param address _owner 令牌所有者的账户
  34. // @param address _spender 令牌被授权者账户
  35. // @return uint256 remaining 剩余可发送的令牌数量
  36. function allowance(address _owner, address _spender) public view returns (uint256 remaining);
  37. ///////////////////////////// 事件 ///////////////////////////////////
  38. // 令牌转移事件 当发生令牌的转移时,需要调用该事件
  39. event Transfer(address indexed _from, address indexed _to, uint256 _value);
  40. // 授权转移事件 当进行授权时,需要触发该事件
  41. event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  42. }
0x04 ERC20代码示例

在标准的基础上,有很多代码的实现方法,比如有的在代码中实现空投,有的在实现锁定,有的实现挖矿等等,但是最常规的实现已经有了官方的实现代码,也有很多组织实现了一些范例,如果没有定制化的地方,完全可以直接采用这些代码去创建ERC20令牌。

示例代码:

</>复制代码

  1. pragma solidity ^0.4.18;
  2. contract ERC20 {
  3. // 定义一个mapping 存储各个地址的令牌
  4. mapping (address => uint256) public balances;
  5. // 定义一个mapping 存储授权详情
  6. mapping (address => mapping (address => uint256)) public allowed;
  7. // 以下参数非必须,但是尽量添加,大多数钱包会通过此获取相关信息
  8. // 令牌发行总量
  9. uint256 public totalSupply;
  10. // 令牌名称,如 OmiseGO
  11. string public name;
  12. // 支持的小数位数
  13. // 因为在EVM中对浮点数的支持很差,在令牌的创建中直接采用整数
  14. // 然后通过该字段进行小数的处理
  15. uint8 public decimals;
  16. // 令牌简称,如 OMG
  17. string public symbol;
  18. // 令牌合约的构造函数
  19. // 在solidity中,和合约名称一致的方法为构造函数,在第一次创建合约时,仅执行一次。
  20. function ERC20(
  21. uint256 _totalSupply, // 令牌创建总量
  22. string _name, // 令牌名称
  23. uint8 _decimals, // 支持小数位数
  24. string _symbol // 令牌简称
  25. ) public {
  26. // 给创建者账户初始化令牌
  27. balances[msg.sender] = _totalSupply;
  28. // 设置令牌发行量
  29. totalSupply = _totalSupply;
  30. // 设置令牌名称
  31. name = _name;
  32. // 设置令牌支持小数位数
  33. decimals = _decimals;
  34. // 设置令牌简称
  35. symbol = _symbol;
  36. }
  37. /**
  38. * 获取令牌总发行量
  39. * @return uint256 totalSupply 发行总量
  40. */
  41. function totalSupply() constant returns (uint256 totalSupply) {
  42. return totalSupply;
  43. }
  44. /**
  45. * 转移令牌
  46. * @param address _to 令牌接收者地址
  47. * @param uint256 _value 发送令牌数量
  48. * @return bool success 发送成功状态
  49. */
  50. function transfer(address _to, uint256 _value) public returns (bool success) {
  51. // 判断发送者余额是否充足
  52. require(balances[msg.sender] >= _value);
  53. // 从发送者余额中减去`_value`数量的令牌
  54. balances[msg.sender] -= _value;
  55. // 给接收者账户中添加`_value`数量的令牌
  56. balances[_to] += _value;
  57. // 记录令牌转移的事件
  58. Transfer(msg.sender, _to, _value);
  59. return true;
  60. }
  61. /**
  62. * 转移令牌(授权)
  63. * @param address _from 令牌发送者地址
  64. * @param address _to 令牌接收者地址
  65. * @param uint256 _value 令牌发送数量
  66. * @return bool success 方法执行状态
  67. */
  68. function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
  69. // 其中`msg.sender`是合约方法调用者的地址
  70. // 获取`_from`地址授权给`msg.sender`地址的可转移令牌余额
  71. uint256 allowance = allowed[_from][msg.sender];
  72. // 判断`_from`地址余额是否充足以及授权转移令牌是否充足
  73. require(balances[_from] >= _value && allowance >= _value);
  74. // 从`_from`地址减去`_value`数量的令牌
  75. balances[_from] -= _value;
  76. // 从授权余额中减去`_value`数量的令牌
  77. allowed[_from][msg.sender] -= _value;
  78. // 给`_to`地址添加`_value`数量的令牌
  79. balances[_to] += _value;
  80. // 记录转移令牌的事件
  81. Transfer(_from, _to, _value);
  82. return true;
  83. }
  84. /**
  85. * 获取`_owner`地址的令牌余额
  86. * @param address _owner 要获取余额的地址
  87. * @return uint256 balance 返回`_owner`地址的余额
  88. */
  89. function balanceOf(address _owner) public view returns (uint256 balance) {
  90. return balances[_owner];
  91. }
  92. /**
  93. * 授权令牌转移方法
  94. * @param address _spender 被授权地址
  95. * @param uint256 _value 授权可转移的数量
  96. * @return bool success 方法执行状态
  97. */
  98. function approve(address _spender, uint256 _value) public returns (bool success) {
  99. // `msg.sender`授权`_spender`地址转移`_value`数量的令牌
  100. allowed[msg.sender][_spender] = _value;
  101. // 记录授权事件
  102. Approval(msg.sender, _spender, _value);
  103. return true;
  104. }
  105. /**
  106. * 获取被授权的令牌余额
  107. * @param address _owner 授权地址
  108. * @param address _spender 被授权地址
  109. * @return uint256 remaining 可转移的令牌余额
  110. */
  111. function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
  112. return allowed[_owner][_spender];
  113. }
  114. }
0x05 写在后面

大多数在交易所交易的令牌的合约代码就这么简单,其实每一个方法拆分开来都是最简单的编程代码,而核心的处理都被EVM进行了封装,以太坊在令牌发行方面确实极大的解放了人类,简单几十行代码就可以发行一个令牌。ERC20令牌又被成为同质化令牌,就是每个令牌都是一致的,无法区分,而市场上现在冒出了很多以太猫,以太狗的游戏,而这里面也是使用以太坊的令牌来实现的,但是他们选择的不是ERC20令牌,而是被成为非同质化的令牌,被称为ERC721令牌。

下期,我们一起来聊非同质化令牌ERC721。

</>复制代码

  1. 喜欢,不要说话,扫我~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24010.html

相关文章

  • 区块链技术学习指引

    摘要:引言给迷失在如何学习区块链技术的同学一个指引,区块链技术是随比特币诞生,因此要搞明白区块链技术,应该先了解下比特币。但区块链技术不单应用于比特币,还有非常多的现实应用场景,想做区块链应用开发,可进一步阅读以太坊系列。 本文始发于深入浅出区块链社区, 原文:区块链技术学习指引 原文已更新,请读者前往原文阅读 本章的文章越来越多,本文是一个索引帖,方便找到自己感兴趣的文章,你也可以使用左侧...

    Cristic 评论0 收藏0
  • 关于区块链通证模型,你想知道的都在这

    摘要:在以太坊出现后,进入了第二阶段。以太坊可以被视作区块链世界类似于和的底层操作系统。通证经济的设计方向模式的组织,是天然的生态型组织。区块链时代的生态组织,大致可以分成这几种类型。 简介   区块链最重要的应用就是将实物价值或虚拟资产映射成链上Token,通过资产上链,实现跨地域、低成本的进行资产交易与转移,本质上是权益再分配,核心是提高激励性和效益。  很多人把Token译为代币,我更...

    huangjinnan 评论0 收藏0
  • 区块链开发中使用的最流行的编程语言

    摘要:我们目前正处于一个新兴的区块链开发行业中。,一种在以太坊开发人员中流行的新的简单编程语言,因为它是用于开发以太坊智能合约的语言。它是全球至少万开发人员使用的世界上最流行的编程语言之一。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 我们目前正处于一个新兴的区块链开发行业中。区块链技术处于初期阶段,然而这种颠覆性技术已经成功地风靡全球,并且最近经历了一场与众不同的繁荣。由于许多...

    2shou 评论0 收藏0
  • 剖析非质化代币ERC721-全面解析ERC721标准

    摘要:本文就来剖析下什么是是什么在创建代币一篇,我们讲到过代币,和一样,同样是一个代币标准,官方简要解释是,简写为,多翻译为非同质代币。返回合约代币符号,尽管是可选,但强烈建议实现,即便是返回空字符串。 本文首发于深入浅出区块链社区原文链接:剖析非同质化代币ERC721-全面解析ERC721标准原文已更新,请读者前往原文阅读 什么是ERC-721?现在我们看到的各种加密猫猫狗狗都是基于ERC...

    Sike 评论0 收藏0
  • Java开发区块链的三大sdk库

    摘要:是企业与区块链相遇的地方。的框架旨在成为开发区块链解决方案的支柱。以太坊,主要是针对工程师使用进行区块链以太坊开发的详解。 如果你想将区块链合并到一个Java项目中,现在我们来看看就是这个细分领域中三个最大的OSS玩家。 好的伙计们,我们都听说过比特币,以太坊或其他加密货币,其中有一些时髦的名字围绕着我们常见的新闻,但我们作为Java开发人员知道如何轻松地与这些区块链技术进行交互吗?以...

    iKcamp 评论0 收藏0

发表评论

0条评论

Little_XM

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<