php eth erc20,【Ethereum】以太坊ERC20 Token标准完整说明
什么是ERC20 token
市面上出現(xiàn)了大量的用ETH做的代幣,他們都遵守REC20協(xié)議,那么我們需要知道什么是REC20協(xié)議。
概述
token代表數(shù)字資產(chǎn),具有價值,但是并不是都符合特定的規(guī)范。
基于ERC20的貨幣更容易互換,并且能夠在Dapps上相同的工作。
新的標準可以讓token更兼容,允許其他功能,包括投票標記化。操作更像一個投票操作
Token的持有人可以完全控制資產(chǎn),遵守ERC20的token可以跟蹤任何人在任何時間擁有多少token.基于eth合約的子貨幣,所以容易實施。只能自己去轉(zhuǎn)讓。
標準化非常有利,也就意味著這些資產(chǎn)可以用于不同的平臺和項目,否則只能用在特定的場合。
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
總結(jié)
token的接口標準
抽象
以下標準允許在智能合約中實施標記的標記API。 該標準提供了轉(zhuǎn)移token的基本功能,并允許token被批準,以便他們可以由另一個在線第三方使用。
動機
標準接口可以讓Ethereum上的任何令牌被其他應用程序重新使用:從錢包到分散式交換。
規(guī)則
Token
方法
注意:調(diào)用者必須處理返回false的returns (bool success).調(diào)用者絕對不能假設返回false的情況不存在。
name
返回這個令牌的名字,比如"MyToken".
可選 - 這種方法可以用來提高可用性,但接口和其他契約不能指望這些值存在。
function name() constant returns (string name)
symbol
返回令牌的符號,比如HIX.
可選 - 這種方法可以用來提高可用性,但接口和其他契約不能指望這些值存在。
function symbol() constant returns (string symbol)
decimals
返回token使用的小數(shù)點后幾位, 比如?8,表示分配token數(shù)量為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
轉(zhuǎn)移_value的token數(shù)量到的地址_to,并且必須觸發(fā)Transfer事件。 如果_from帳戶余額沒有足夠的令牌來支出,該函數(shù)應該被throw。
創(chuàng)建新令牌的令牌合同應該在創(chuàng)建令牌時將_from地址設置為0x0觸發(fā)傳輸事件。
注意?0值的傳輸必須被視為正常傳輸并觸發(fā)傳輸事件。
function transfer(address _to, uint256 _value) returns (bool success)
transferFrom
從地址_from發(fā)送數(shù)量為_value的token到地址_to,必須觸發(fā)Transfer事件。
transferFrom方法用于提取工作流,允許合同代您轉(zhuǎn)移token。這可以用于例如允許合約代您轉(zhuǎn)讓代幣和/或以子貨幣收取費用。除了_from帳戶已經(jīng)通過某種機制故意地授權(quán)消息的發(fā)送者之外,該函數(shù)**應該**throw。
注意?0值的傳輸必須被視為正常傳輸并觸發(fā)傳輸事件。
function transferFrom(address _from, address _to, uint256 _value) returns (bool success)
approve
允許_spender多次取回您的帳戶,最高達_value金額。 如果再次調(diào)用此函數(shù),它將以_value覆蓋當前的余量。
注意:為了阻止向量攻擊,客戶端需要確認以這樣的方式創(chuàng)建用戶接口,即將它們設置為0,然后將其設置為同一個花費者的另一個值。雖然合同本身不應該強制執(zhí)行,允許向后兼容以前部署的合同兼容性
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被轉(zhuǎn)移(包括0值),必須被觸發(fā)。
event Transfer(address indexed _from, address indexed _to, uint256 _value)
Approval
當任何成功調(diào)用approve(address _spender, uint256 _value)后,必須被觸發(fā)。
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
實施
在Ethereum網(wǎng)絡上部署了大量符合ERC20標準的令牌。 具有不同權(quán)衡的各種團隊已經(jīng)編寫了不同的實施方案:從節(jié)省gas到提高安全性。
示例實現(xiàn)可在
在調(diào)用之前添加力0的實施“批準”了
ERC20 Token標準接口
以下是一個接口合同,聲明所需的功能和事件以符合ERC20標準:
// https://github.com/ethereum/EIPs/issues/20
contract 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;
// 帳戶的所有者批準將金額轉(zhuǎn)入另一個帳戶
mapping(address => mapping (address => uint256)) allowed;
// 特定帳戶的余額是多少?
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner]; //從數(shù)組中取值
}
// 將余額從所有者帳戶轉(zhuǎn)移到另一個帳戶
function transfer(address _to, uint256 _amount) returns (bool success) {
//判斷條件 發(fā)送者余額>=要發(fā)送的值 發(fā)送的值>0 接收者余額+發(fā)送的值>接收者的余額
if (balances[msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[msg.sender] -= _amount; //發(fā)送者的余額減少
balances[_to] += _amount; //接收者的余額增加
return true;
} else {
return false;
}
}
// 發(fā)送 _value 數(shù)量的token從地址 _from 到 地址 _to
// transferFrom方法用于提取工作流程,允許合同以您的名義發(fā)送令牌,例如“存入”到合同地址和/或以子貨幣收取費用; 該命令應該失敗,除非_from帳戶通過某種機制故意地授權(quán)消息的發(fā)送者; 我們提出這些標準化的API來批準:
function transferFrom(
address _from,
address _to,
uint256 _amount
) returns (bool success) {
//和上面一樣的校驗規(guī)則
if (balances[_from] >= _amount
&& allowed[_from][msg.sender] >= _amount
&& _amount > 0
&& balances[_to] + _amount > balances[_to]) {
balances[_from] -= _amount;
allowed[_from][msg.sender] -= _amount; //減少發(fā)送者的批準量
balances[_to] += _amount;
return true;
} else {
return false;
}
}
// 允許_spender多次退出您的帳戶,直到_value金額。 如果再次調(diào)用此函數(shù),它將以_value覆蓋當前的余量。
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount; //覆蓋當前余量
return true;
}
}
token余額
假設token合約內(nèi)有兩個持有者
0x1111111111111111111111111111111111111111有100個單位
0x2222222222222222222222222222222222222222有200個單位
那么這個合約的balances結(jié)構(gòu)就會存儲下面的內(nèi)容
balances[0x1111111111111111111111111111111111111111] = 100
balances[0x2222222222222222222222222222222222222222] = 200
那么,balanceOf(...)就會返回下面的結(jié)果
tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 將會返回 100
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 將會返回 200
轉(zhuǎn)移token的余額
如果0x1111111111111111111111111111111111111111想要轉(zhuǎn)移10個單位給0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111會執(zhí)行下面的函數(shù)
tokenContract.transfer(0x2222222222222222222222222222222222222222, 10)
token合約的transfer(...)方法將會改變balances結(jié)構(gòu)中的信息
balances[0x1111111111111111111111111111111111111111] = 90
balances[0x2222222222222222222222222222222222222222] = 210
balanceOf(...)調(diào)用就會返回下面的信息
tokenContract.balanceOf(0x1111111111111111111111111111111111111111) 將會返回 90
tokenContract.balanceOf(0x2222222222222222222222222222222222222222) 將會返回 210
從token余額批準和轉(zhuǎn)移
如果0x1111111111111111111111111111111111111111想要批準0x2222222222222222222222222222222222222222傳輸一些token到0x2222222222222222222222222222222222222222,那么0x1111111111111111111111111111111111111111會執(zhí)行下面的函數(shù)
tokenContract.approve(0x2222222222222222222222222222222222222222, 30)
然后allowed(這里官方文檔寫的是approve,很明顯是錯的)結(jié)構(gòu)就會存儲下面的內(nèi)容
tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 30
如果0x2222222222222222222222222222222222222222想要晚點轉(zhuǎn)移token從0x1111111111111111111111111111111111111111到他自己,0x2222222222222222222222222222222222222222將要執(zhí)行transferFrom(...)函數(shù)
tokenContract.transferFrom(0x1111111111111111111111111111111111111111, 20)
balances的信息就會變成下面的
tokenContract.balances[0x1111111111111111111111111111111111111111] = 70
tokenContract.balances[0x2222222222222222222222222222222222222222] = 230
然后allowed就會變成下面的內(nèi)容
tokenContract.allowed[0x1111111111111111111111111111111111111111][0x2222222222222222222222222222222222222222] = 10
0x2222222222222222222222222222222222222222仍然可以從0x1111111111111111111111111111111111111111轉(zhuǎn)移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/20
contract ERC20Interface {
// 獲取總的支持量
function totalSupply() constant returns (uint256 totalSupply);
// 獲取其他地址的余額
function balanceOf(address _owner) constant returns (uint256 balance);
// 向其他地址發(fā)送token
function transfer(address _to, uint256 _value) returns (bool success);
// 從一個地址想另一個地址發(fā)送余額
function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
//允許_spender從你的賬戶轉(zhuǎn)出_value的余額,調(diào)用多次會覆蓋可用量。某些DEX功能需要此功能
function approve(address _spender, uint256 _value) returns (bool success);
// 返回_spender仍然允許從_owner退出的余額數(shù)量
function allowance(address _owner, address _spender) constant returns (uint256 remaining);
// token轉(zhuǎn)移完成后出發(fā)
event Transfer(address indexed _from, address indexed _to, uint256 _value);
// approve(address _spender, uint256 _value)調(diào)用后觸發(fā)
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; //小數(shù)點后的位數(shù)
uint256 _totalSupply = 1000000; //發(fā)行總量
// 智能合約的所有者
address public owner;
// 每個賬戶的余額
mapping(address => uint256) balances;
// 帳戶的所有者批準將金額轉(zhuǎn)入另一個帳戶。從上面的說明我們可以得知allowed[被轉(zhuǎn)移的賬戶][轉(zhuǎn)移錢的賬戶]
mapping(address => mapping (address => uint256)) allowed;
// 只能通過智能合約的所有者才能調(diào)用的方法
modifier onlyOwner() {
if (msg.sender != owner) {
throw;
}
_;
}
// 構(gòu)造函數(shù)
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];
}
// 轉(zhuǎn)移余額到其他賬戶
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;
}
}
//從一個賬戶轉(zhuǎn)移到另一個賬戶,前提是需要有允許轉(zhuǎn)移的余額
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;
}
}
//允許賬戶從當前用戶轉(zhuǎn)移余額到那個賬戶,多次調(diào)用會覆蓋
function approve(address _spender, uint256 _amount) returns (bool success) {
allowed[msg.sender][_spender] = _amount;
Approval(msg.sender, _spender, _amount);
return true;
}
//返回被允許轉(zhuǎn)移的余額數(shù)量
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
}
注意的是,最后的例子中allowed限定的第二維的參數(shù)是調(diào)用者的轉(zhuǎn)移數(shù)量,而開始的例子是接收者的數(shù)量。
參考資料
總結(jié)
以上是生活随笔為你收集整理的php eth erc20,【Ethereum】以太坊ERC20 Token标准完整说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。