【Ethereum】以太坊ERC20 Token标准完整说明
什么是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
方法
注意:调用者必须处理返回false
的returns (bool success)
.调用者绝对不能假设返回false
的情况不存在。
name
返回这个令牌的名字,比如"MyToken"
.
可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。
function name() constant returns (string name)
symbol
返回令牌的符号,比如HIX
.
可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。
function symbol() constant returns (string symbol)
decimals
返回token使用的小数点后几位, 比如 8
,表示分配token数量为100000000
可选 - 这种方法可以用来提高可用性,但接口和其他契约不能指望这些值存在。
function decimals() constant returns (uint8 decimals)
totalSupply
返回token的总供应量。
function totalSupply() constant returns (uint256 totalSupply)
balanceOf
返回地址是_owner
的账户的账户余额。
function balanceOf(address _owner) constant returns (uint256 balance)
transfer
转移_value
的token数量到的地址_to
,并且必须触发Transfer
事件。 如果_from
帐户余额没有足够的令牌来支出,该函数应该被throw
。
创建新令牌的令牌合同应该在创建令牌时将_from
地址设置为0x0
触发传输事件。
注意 0值的传输必须被视为正常传输并触发传输事件。
function transfer(address _to, uint256 _value) returns (bool success)
transferFrom
从地址_from
发送数量为_value
的token到地址_to
,必须触发Transfer
事件。
transferFrom方法用于提取工作流,允许合同代您转移token。这可以用于例如允许合约代您转让代币和/或以子货币收取费用。除了_from帐户已经通过某种机制故意地授权消息的发送者之外,该函数**应该**throw。
注意 0值的传输必须被视为正常传输并触发传输事件。
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
approve
允许_spender
多次取回您的帐户,最高达_value
金额。 如果再次调用此函数,它将以_value
覆盖当前的余量。
注意:为了阻止向量攻击,客户端需要确认以这样的方式创建用户接口,即将它们设置为0,然后将其设置为同一个花费者的另一个值。虽然合同本身不应该强制执行,允许向后兼容以前部署的合同兼容性
function approve(address _spender, uint256 _value) returns (bool success)
allowance
返回_spender
仍然被允许从_owner
提取的金额。
function allowance(address _owner, address _spender) constant returns (uint256 remaining)
Events
Transfer
当token被转移(包括0值),必须被触发。
event Transfer(address indexed _from, address indexed _to, uint256 _value)
Approval
当任何成功调用approve(address _spender, uint256 _value)
后,必须被触发。
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
实施
在Ethereum网络上部署了大量符合ERC20标准的令牌。 具有不同权衡的各种团队已经编写了不同的实施方案:从节省gas到提高安全性。
示例实现可在
- https://github.com/ConsenSys/Tokens/blob/master/contracts/StandardToken.sol
- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol
在调用之前添加力0的实施“批准”了
- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol
ERC20 Token标准接口
以下是一个接口合同,声明所需的功能和事件以符合ERC20标准:
// https://github.com/ethereum/EIPs/issues/20contract ERC20 {function totalSupply() constant returns (uint totalSupply);function balanceOf(address _owner) constant returns (uint balance);function transfer(address _to, uint _value) returns (bool success);function transferFrom(address _from, address _to, uint _value) returns (bool success);function approve(address _spender, uint _value) returns (bool success);function allowance(address _owner, address _spender) constant returns (uint remaining);event Transfer(address indexed _from, address indexed _to, uint _value);event Approval(address indexed _owner, address indexed _spender, uint _value);}
大部分Ethereum主要标记符合ERC20标准。
一些令牌包括描述令牌合同的进一步信息:
string public constant name = "Token Name";
string public constant symbol = "SYM";
uint8 public constant decimals = 18; // 大部分都是18
如何工作?
以下是令牌合约的一个片段,用于演示令牌合约如何维护Ethereum帐户的令牌余额
contract TokenContractFragment {// Balances 保存地址的余额mapping(address => uint256) balances;// 帐户的所有者批准将金额转入另一个帐户mapping(address => mapping (address => uint256)) allowed;// 特定帐户的余额是多少?function balanceOf(address _owner) constant returns (uint256 balance) {return balances[_owner]; //从数组中取值}// 将余额从所有者帐户转移到另一个帐户function transfer(address _to, uint256 _amount) returns (bool success) {//判断条件 发送者余额>=要发送的值 发送的值>0 接收者余额+发送的值>接收者的余额if (balances[msg.sender] >= _amount && _amount > 0&& balances[_to] + _amount > balances[_to]) {balances[msg.sender] -= _amount; //发送者的余额减少balances[_to] += _amount; //接收者的余额增加return true;} else {return false;}}// 发送 _value 数量的token从地址 _from 到 地址 _to// transferFrom方法用于提取工作流程,允许合同以您的名义发送令牌,例如“存入”到合同地址和/或以子货币收取费用; 该命令应该失败,除非_from帐户通过某种机制故意地授权消息的发送者; 我们提出这些标准化的API来批准:function transferFrom(address _from,address _to,uint256 _amount) returns (bool success) {//和上面一样的校验规则if (balances[_from] >= _amount&& allowed[_from][msg.sender] >= _amount&& _amount > 0&& balances[_to] + _amount > balances[_to]) {balances[_from] -= _amount;allowed[_from][msg.sender] -= _amount; //减少发送者的批准量balances[_to] += _amount;return true;} else {return false;}}// 允许_spender多次退出您的帐户,直到_value金额。 如果再次调用此函数,它将以_value覆盖当前的余量。function approve(address _spender, uint256 _amount) returns (bool success) {allowed[msg.sender][_spender] = _amount; //覆盖当前余量return true;}}
token余额
假设token合约内有两个持有者
0x1111111111111111111111111111111111111111
有100个单位0x2222222222222222222222222222222222222222
有200个单位
那么这个合约的balances
结构就会存储下面的内容
balances[0x1111111111111111111111111111111111111111] = 100
balances[0x2222222222222222222222222222222222222222] = 200
那么,balanceOf(...)
就会返回下面的结果
tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 100
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 200
转移token的余额
如果0x1111111111111111111111111111111111111111
想要转移10个单位给0x2222222222222222222222222222222222222222
,那么0x1111111111111111111111111111111111111111
会执行下面的函数
tokenContract.transfer(0x2222222222222222222222222222222222222222, 10)
token合约的transfer(...)
方法将会改变balances
结构中的信息
balances[0x1111111111111111111111111111111111111111] = 90
balances[0x2222222222222222222222222222222222222222] = 210
balanceOf(...)
调用就会返回下面的信息
tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 将会返回 90
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 将会返回 210
从token余额批准和转移
如果0x1111111111111111111111111111111111111111
想要批准0x2222222222222222222222222222222222222222
传输一些token到0x2222222222222222222222222222222222222222
,那么0x1111111111111111111111111111111111111111
会执行下面的函数
tokenContract.approve(0x2222222222222222222222222222222222222222, 30)
然后allowed
(这里官方文档写的是approve,很明显是错的)结构就会存储下面的内容
tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 30
如果0x2222222222222222222222222222222222222222
想要晚点转移token从0x1111111111111111111111111111111111111111
到他自己,0x2222222222222222222222222222222222222222
将要执行transferFrom(...)
函数
tokenContract.transferFrom(0x1111111111111111111111111111111111111111, 20)
balances
的信息就会变成下面的
tokenContract.balances[0x1111111111111111111111111111111111111111] = 70
tokenContract.balances[0x2222222222222222222222222222222222222222] = 230
然后allowed
就会变成下面的内容
tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 10
0x2222222222222222222222222222222222222222
仍然可以从0x1111111111111111111111111111111111111111
转移10个单位。
tokenContract.balanceOf(0x1111111111111111111111111111111111111111) will return 70
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) will return 230
简单修复的token合约
以下是一个样本令牌合同,固定供应量为1000000单位,最初分配给合同所有者:
pragma solidity ^0.4.8;// ----------------------------------------------------------------------------------------------// Sample fixed supply token contract// Enjoy. (c) BokkyPooBah 2017. The MIT Licence.// ----------------------------------------------------------------------------------------------// ERC Token Standard #20 Interface// https://github.com/ethereum/EIPs/issues/20contract ERC20Interface {// 获取总的支持量function totalSupply() constant returns (uint256 totalSupply);// 获取其他地址的余额function balanceOf(address _owner) constant returns (uint256 balance);// 向其他地址发送tokenfunction transfer(address _to, uint256 _value) returns (bool success);// 从一个地址想另一个地址发送余额function transferFrom(address _from, address _to, uint256 _value) returns (bool success);//允许_spender从你的账户转出_value的余额,调用多次会覆盖可用量。某些DEX功能需要此功能function approve(address _spender, uint256 _value) returns (bool success);// 返回_spender仍然允许从_owner退出的余额数量function allowance(address _owner, address _spender) constant returns (uint256 remaining);// token转移完成后出发event Transfer(address indexed _from, address indexed _to, uint256 _value);// approve(address _spender, uint256 _value)调用后触发event Approval(address indexed _owner, address indexed _spender, uint256 _value);}//继承接口后的实例contract FixedSupplyToken is ERC20Interface {string public constant symbol = "FIXED"; //单位string public constant name = "Example Fixed Supply Token"; //名称uint8 public constant decimals = 18; //小数点后的位数uint256 _totalSupply = 1000000; //发行总量// 智能合约的所有者address public owner;// 每个账户的余额mapping(address => uint256) balances;// 帐户的所有者批准将金额转入另一个帐户。从上面的说明我们可以得知allowed[被转移的账户][转移钱的账户]mapping(address => mapping (address => uint256)) allowed;// 只能通过智能合约的所有者才能调用的方法modifier onlyOwner() {if (msg.sender != owner) {throw;}_;}// 构造函数function FixedSupplyToken() {owner = msg.sender;balances[owner] = _totalSupply;}function totalSupply() constant returns (uint256 totalSupply) {totalSupply = _totalSupply;}// 特定账户的余额function balanceOf(address _owner) constant returns (uint256 balance) {return balances[_owner];}// 转移余额到其他账户function transfer(address _to, uint256 _amount) returns (bool success) {if (balances[msg.sender] >= _amount && _amount > 0&& balances[_to] + _amount > balances[_to]) {balances[msg.sender] -= _amount;balances[_to] += _amount;Transfer(msg.sender, _to, _amount);return true;} else {return false;}}//从一个账户转移到另一个账户,前提是需要有允许转移的余额function transferFrom(address _from,address _to,uint256 _amount) returns (bool success) {if (balances[_from] >= _amount&& allowed[_from][msg.sender] >= _amount&& _amount > 0&& balances[_to] + _amount > balances[_to]) {balances[_from] -= _amount;allowed[_from][msg.sender] -= _amount;balances[_to] += _amount;Transfer(_from, _to, _amount);return true;} else {return false;}}//允许账户从当前用户转移余额到那个账户,多次调用会覆盖function approve(address _spender, uint256 _amount) returns (bool success) {allowed[msg.sender][_spender] = _amount;Approval(msg.sender, _spender, _amount);return true;}//返回被允许转移的余额数量function allowance(address _owner, address _spender) constant returns (uint256 remaining) {return allowed[_owner][_spender];}}
注意的是,最后的例子中allowed限定的第二维的参数是调用者的转移数量,而开始的例子是接收者的数量。
参考资料
- http://themerkle.com/what-is-the-erc20-ethereum-token-standard/
- https://github.com/ethereum/EIPs/pull/610
- https://github.com/ethereum/EIPs/issues/20
- https://theethereum.wiki/w/index.php/ERC20_Token_Standard
- https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
- https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.m9fhqynw2xvt
【Ethereum】以太坊ERC20 Token标准完整说明相关推荐
- php eth erc20,【Ethereum】以太坊ERC20 Token标准完整说明
什么是ERC20 token 市面上出现了大量的用ETH做的代币,他们都遵守REC20协议,那么我们需要知道什么是REC20协议. 概述 token代表数字资产,具有价值,但是并不是都符合特定的规范. ...
- 手把手教你发行自己的以太坊ERC20 Token 并进行转账
代币Token 如果不那么追求精确的定义,代币就是数字货币,比特币.以太币就是一个代币. 利用以太坊的智能合约可以轻松编写出属于自己的代币,代币可以代表任何可以交易的东西,如:积分.财产.证书等等. ...
- 以太坊发token教程
以太坊发token教程 如果需要币的话,请留下联系方式!!! 在发Token前,你先的确定一下几点: Token的名称 Token的标识 Token的小数位 Token发型量 我的选择是: 名称:My ...
- 关于以太坊ERC-20通证智能合约协议
文章目录 ERC-20协议是什么意思? 取值函数 totalSupply balanceOf allowance 操作函数 transfer approve transferFrom 事件 Trans ...
- erc20钱包下载_以太坊ERC20代币数据集【1000+】
Erc20Tokens数据集包含超过1000种主流的以太坊ERC20代币的描述数据清单和图标,可用于钱包等区块链应用的开发,支持使用Java.Python.Php.NodeJs.C#等各种开发语言查询 ...
- CentOS 7 从零开始安装ethereum/以太坊
CentOS 7 从零开始安装ethereum/以太坊 本人也是第一次接触linux,在安装的过程中遇到了很多问题,查找发现没有很全面的一个安装以太坊的教程,这里总结一下我的方法,有问题的话希望各位大 ...
- 什么是Ethereum以太坊(ETH)?以及以太坊的一些基础知识
Ethereum以太坊(ETH)是由Vitalik Buterin所创建,一种允许智能合约和去中心化应用程序(dapps)在其网络上运行的加密货币. 以太坊是仅次于比特币的第二大加密货币,它是一个基于 ...
- 以太坊代币标准: ERC20、ERC223的介绍与比较
代币(Token)是区块链中定义价值的方式,用于标定金融或数字资产.在以太坊上,代币使用相同的标准,这样代币之间的兑换和DAPP支持就会变得容易. 什么是ERC20标准 ERC-20 标准是在2015 ...
- 【前沿解读】斯坦福研究员论文-以太坊可逆交易标准ERC20/721R的机制、创新与局限
区块链交易的不可逆特性,一度被形容为是唯一的人类对上帝'时间'的低劣仿制品,然而也正是因为不可逆,导致大量黑客攻击资金被盗无处解决,也被趣称为web2向web3最成功的转型:黑客. 而斯坦福大学研究员 ...
最新文章
- 普通大学生和大厂的距离有多长?
- android 中处理崩溃异常并重启程序
- 【转】CAD2012打开自动关闭解决方法
- 配置maven nenux仓库
- spring jmx_JMX和Spring –第3部分
- python 文件状态_Python:如何访问文件的状态
- 调用百度人脸识别API进行人脸对比 C语言
- Java基础学习总结(74)——Java常见笔试题及答案汇总
- 1782: [Usaco2010 Feb]slowdown 慢慢游
- LOJ2361「NOIP2016」组合数问题
- Ubuntu18.04卸载QQ
- 基于PHP的汉服文化交流平台 毕业设计-附源码240903
- 计算机视觉各种需要了解的知识大杂烩
- USB接口WiFi驱动浅析
- WSL ubuntu ‘Permission denied’的解决方法
- 人脸识别简单总结(一) 生物特征识别的前世今生
- ​微信公众号素材图片去哪找?
- 以太坊宠物商店 - 记录第一个Dapp
- 强化学习 马尔科夫决策过程(MDP)
- NOIP模拟17.10.12
热门文章
- html css3d效果,html,css的3D变形
- INADDR_ANY 最好的解释
- python写个礼物送人_送你个情人节礼物:Python版抖音同款表白神器
- suse linux用户界面,suse linux开户图形化界面
- jqgrid 单元格绑定点击事件_自定义事件带参数的触发过程
- matlab-绘图-直角坐标系
- vivado中ILA核的使用
- 【 MATLAB 】DFT性质讨论(一)线性、循环反转、共轭与实序列的对称性
- 【 MATLAB 】ndgrid 和 meshgrid 对比理解以及应用
- Yii2 HOW-TO(2):最佳实践(1)