ERC20
テンプレートのループを検出しました: テンプレート:#
Ethereum [スマートコントラクト|スマートコントラクト]にはEthereumトークン標準( 'ERC20' )が使用されています。 2015年に開発されたERC-20は、Ethereumトークンが実装しなければならないルールの共通リストを定義しています。開発者に、新しいトークンがEthereumエコシステム内でどのように機能するかをプログラムする能力を与える。このトークンプロトコルは、 Initial Coin Offering(ICO)を通じてクラウドファンディング企業に人気がありました。
Mercury Protocolのグローバル・メッセージング・トークンは、ERC20トークンに基づくアプリケーションの例です。
ERC20トークン標準は、Ethereumトークン契約が実装しなければならない機能とイベントを記述します。
目次
ERC20トークン標準インタフェース[編集]
以下は、ERC20規格を満たすために必要な機能とイベントを宣言するインタフェース契約です。
<syntaxhighlight lang = "javascript" line = 'line'> // ------------------------------------------------ ---------------------------- // ERCトークン標準#20インタフェース // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md // ------------------------------------------------ ---------------------------- 契約ERC20Interface { function totalSupply()public定数が返す値(uint)です。 function balanceOf(address tokenOwner)public定数が返されます(uintバランス)。 function allowance(アドレスtokenOwner、address spender)public定数は(uintの残りの部分)を返します。 関数呼び出し(アドレスto、uintトークン)public return(bool success); 機能は承認されます(払い戻し、uintトークン)public return(bool success); function transferFrom(アドレス、アドレス、uintトークンからのアドレス)public returns(bool success);
イベント転送(uintトークンにインデックス付けされたアドレス、uintトークンにインデックス付けされたアドレス)。 イベント承認(アドレス指定されたtokenOwner、住所付き出費、uintトークン)。 } </ syntaxhighlight>
Ethereumブロックチェーンの主要なトークンのほとんどはERC20に準拠しています。 allowance(..)</ code>、<code> allowance(..)</ code>を実装していないため、GNT Golem Network Tokenは、 code>および<code> transferFrom(...)</ code>関数、および<code> Approval(...)</ code>イベントを生成します。
トークンの一部には、トークン契約を説明する追加情報が含まれています。
<syntaxhighlight lang = "javascript" line = 'line'> 文字列public constant name = "トークン名"; 文字列public constant symbol = "SYM"; uint8 public定数decimals = 18; // 18は最も一般的な小数点以下の桁数です </ syntaxhighlight>
トークン契約はどのように機能するのですか?[編集]
以下は、トークン契約がEthereumアカウントのトークンバランスをどのように維持するかを示すためのトークン契約の断片です:
<syntaxhighlight lang = "javascript" line = 'line'> 契約TokenContractFragment { //各口座の残高 マッピング(アドレス=> uint256)のバランス。 //所有者が金額を別の口座に振り替えることを承認する マッピング(アドレス=>マッピング(アドレス=> uint256))は許可されています。 //アカウント `tokenOwner`のトークン残高を取得する 関数balanceOf(address tokenOwner)public定数が返す(uint balance){ リターンバランス[tokenOwner]; } //所有者のアカウントから別のアカウントに残高を転送する 関数の転送(アドレスto、uintトークン)public returns(bool success){ バランス[msg.sender] =バランス[msg.sender] .sub(トークン); バランス[to] =バランス[to] .add(tokens); 転送(msg.sender、to、tokens); 真を返します。 } //「from」から「to」にトークン量のトークンを送る // transferFromメソッドは、引き出しワークフローに使用され、契約の送信を許可します //あなたの代理として、たとえば契約アドレスに「入金する」、および/または請求するためのトークン //副通貨での手数料。 _fromアカウントが持っていない限りコマンドは失敗するはずです //意図的にメッセージの送信者を何らかのメカニズムで承認しました。私達は提案します //承認のためのこれらの標準化されたAPI: function transferFrom(アドレス、アドレス、uintトークンからのアドレス)public returns(bool success){ バランス[from] =バランス[from] .sub(tokens); 許可[from] [msg.sender] =許可[from] [msg.sender] .sub(tokens); バランス[to] =バランス[to] .add(tokens); 転送(from、to、トークン)。 真を返します。 } //あなたの口座から `spender 'が` tokens`金額まで何回も引き出すことを許可します。 //この関数をもう一度呼び出すと、現在の余裕が_valueで上書きされます。 関数は承認されます(出産者、住所トークン)public returns(bool success){ [msg.sender] [spender] =トークンを許可しました。 承認(msg.sender、spender、tokens); 真を返します。 } } </ syntaxhighlight>
トークンバランス[編集]
たとえば、このトークンコントラクトに2つのトークンホルダがあるとします。
- <code> 0x1111111111111111111111111111111111111111 </ code>の残高は100単位です
- <code> 0x2222222222222222222222222222222222222222 </ code>、残高は200単位
トークンコントラクトの<code> balance </ code>データ構造には、次の情報が含まれます。 残高[0x1111111111111111111111111111111111111111] = 100 残高[0x2222222222222222222222222222222222222222] = 200
<code> balanceOf(...)</ code>関数は、次の値を返します。 tokenContract.balanceOf(0x1111111111111111111111111111111111111111)は100を返します。 tokenContract.balanceOf(0x222222222222222222222222222222222222222222)は200を返します
転送トークンバランス[編集]
<code> 0x1111111111111111111111111111111111111111 </ code>が10個のトークンを<code> 0x2222222222222222222222222222222222222222 </ code>に転送したい場合、<code> 0x1111111111111111111111111111111111111111 </ code> tokenContract.transfer(0x222222222222222222222222222222222222222222,10)
トークン契約の<code> transfer(...)</ code>関数は、<code> balance </ code>データ構造を変更して次の情報を格納します。 残高[0x1111111111111111111111111111111111111111] = 90 残高[0x2222222222222222222222222222222222222222] = 210
<code> balanceOf(...)</ code>関数は次の値を返します。 tokenContract.balanceOf(0x1111111111111111111111111111111111111111)は90を返します tokenContract.balanceOf(0x222222222222222222222222222222222222222222)は210を返します
トークンバランスを承認してから転送する[編集]
<code> 0x1111111111111111111111111111111111111111 </ code>が<code> 0x22222222222222222222222222222222222222 </ code>にいくつかのトークンを<code> 0x2222222222222222222222222222222222222222222222222222 </ code>に転送することを許可したい場合、<code> 0x1111111111111111111111111111111111111111 </ code> tokenContract.approve(0x222222222222222222222222222222222222222222,30)
<code>承認</ code>データ構造に次の情報が含まれるようになりました。 tokenContract.allowed [0x1111111111111111111111111111111111111111] [0x22222222222222222222222222222222222222] = 30
<code> 0x2222222222222222222222222222222222222222 </ code>が後で<code> 0x1111111111111111111111111111111111111111 </ code>からそれ自身にいくつかのトークンを転送したい場合、<code> 0x22222222222222222222222222222222222222 </ code>は<code> transferFrom(...)</ code>関数: tokenContract.transferFrom(0x1111111111111111111111111111111111111111,0x2222222222222222222222222222222222222222,20)
<code> balance </ code>データ構造は、次の情報を含むように変更されます。 tokenContract.balances [0x1111111111111111111111111111111111111111] = 70 tokenContract.balances [0x2222222222222222222222222222222222222222] = 230
また、<code>承認</ code>データ構造には次の情報が含まれます: tokenContract.allowed [0x1111111111111111111111111111111111111111] [0x2222222222222222222222222222222222222222] = 10 <code> 0x2222222222222222222222222222222222222222 </ code>は、<code> 0x1111111111111111111111111111111111111111 </ code>から10トークンを引き続き使用できます。
<code> balanceOf(...)</ code>関数は次の値を返します。 tokenContract.balanceOf(0x1111111111111111111111111111111111111111)は70を返します tokenContract.balanceOf(0x222222222222222222222222222222222222222222)は230を返します。
サンプル固定供給トークン契約[編集]
以下は、最初に契約の所有者に割り当てられた1,000,000単位の固定供給でのサンプル[1]契約です。このトークンの小数点以下は18桁です。
<syntaxhighlight lang = "javascript" line = 'line'> プラグマ硬度^ 0.4.18;
// ------------------------------------------------ ---------------------------- // 'FIXED' 'Example Fixed Supply Token'トークン契約 // //シンボル:FIXED // Name:固定サプライトークンの例 //合計供給:1,000,000.000000000000000000 //小数点以下:18 // // 楽しい。 // //(c)BokkyPooBah / Bok Consulting Pty Ltd 2017. MITライセンス。 // ------------------------------------------------ ---------------------------- // ---------------------------------------------------------------------------- //安全な数学 // ------------------------------------------------ ---------------------------- ライブラリSafeMath { 関数add(uint a、uint b)内部純戻り(uint c){ c = a + b; require(c> = a); } 関数sub(uint a、uint b)内部純戻り値(uint c){ require(b <= a); c = a-b; } 関数mul(uint a、uint b)内部純粋な戻り値(uint c){ c = a * b; require(a == 0 || c / a == b); } 関数div(uint a、uint b)内部純戻り値(uint c){ require(b> 0); c = a / b; } }
// ------------------------------------------------ ----------------------------
// ERCトークン標準#20インタフェース
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
// ------------------------------------------------ ----------------------------
契約ERC20Interface {
function totalSupply()public定数が返す値(uint)です。
function balanceOf(address tokenOwner)public定数が返されます(uintバランス)。
function allowance(アドレスtokenOwner、address spender)public定数は(uintの残りの部分)を返します。
関数呼び出し(アドレスto、uintトークン)public return(bool success);
機能は承認されます(払い戻し、uintトークン)public return(bool success);
function transferFrom(アドレス、アドレス、uintトークンからのアドレス)public returns(bool success);
イベント転送(uintトークンにインデックス付けされたアドレス、uintトークンにインデックス付けされたアドレス)。 イベント承認(アドレス指定されたtokenOwner、住所付き出費、uintトークン)。 }
// ------------------------------------------------ ----------------------------
// 1回の呼び出しで承認を受け取り、関数を実行するための契約関数
//
// MiniMeTokenから借用
// ------------------------------------------------ ----------------------------
契約ApproveAndCallFallBack {
関数receiveApproval(uint256トークンからのアドレス、アドレストークン、バイトデータ)public;
}
// ------------------------------------------------ ----------------------------
//所有契約
// ------------------------------------------------ ----------------------------
契約所有者{
公的所有者に対処する。
アドレスpublic newOwner;
イベントOwnershipTransferred(アドレス指定されたアドレス_from、アドレス指定されたアドレス_to)。
関数Owned()public { owner = msg.sender; }
修飾子onlyOwner { require(msg.sender == owner); _; }
関数transferOwnership(アドレス_newOwner)public onlyOwner { newOwner = _newOwner; } 関数acceptOwnership()public { require(msg.sender == newOwner); OwnershipTransferred(owner、newOwner); オーナー= newOwner; newOwner =アドレス(0); } }
// ------------------------------------------------ ----------------------------
// ERC20トークン。シンボル、名前、および小数点を追加します。
//最初の固定供給
// ------------------------------------------------ ----------------------------
契約FixedSupplyTokenはERC20Interface、Owned {
uintにはSafeMathを使用します。
文字列public symbol; 文字列public name; uint8 public decimals; uint public _totalSupply;
マッピング(アドレス=> uint)のバランス。 マッピング(アドレス=>マッピング(アドレス=> uint))。
// ------------------------------------------------ ------------------------
//コンストラクタ // ------------------------------------------------ ------------------------ function FixedSupplyToken()public { シンボル= "FIXED"; name = "固定供給トークンの例"; 小数点= 18; _totalSupply = 1000000 * 10 ** uint(小数点以下)。 バランス[所有者] = _totalSupply; 転送(アドレス(0)、所有者、_totalSupply); }
// ------------------------------------------------ ------------------------
//合計供給
// ------------------------------------------------ ------------------------
function totalSupply()public定数が返されます(uint){
return _totalSupply - バランス[住所(0)];
}
// ------------------------------------------------ ------------------------
//アカウント `tokenOwner`のトークン残高を取得する
// ------------------------------------------------ ------------------------
関数balanceOf(address tokenOwner)public定数が返す(uint balance){
リターンバランス[tokenOwner];
}
// ------------------------------------------------ ------------------------
//トークン所有者の口座から残高を `to`口座に振り替えます
// - オーナーのアカウントには、転送に十分な残高が必要です
// - 0の値の転送は許可されます
// ------------------------------------------------ ------------------------
関数の転送(アドレスto、uintトークン)public returns(bool success){
バランス[msg.sender] =バランス[msg.sender] .sub(トークン);
バランス[to] =バランス[to] .add(tokens);
転送(msg.sender、to、tokens);
真を返します。
}
// ------------------------------------------------ ------------------------
//トークンの所有者は、 `spender`が` token 'をtransferFrom(...)することを承認できます
//トークン所有者のアカウントから
//
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
//承認重複攻撃のチェックがないことを推奨します
//これはユーザーインターフェイスで実装する必要があるため
// ------------------------------------------------ ------------------------
関数は承認されます(出産者、住所トークン)public returns(bool success){
[msg.sender] [spender] =トークンを許可しました。
承認(msg.sender、spender、tokens);
真を返します。
}
// ------------------------------------------------ ------------------------
// `to`アカウントから` to`アカウントに `tokens`を転送します
//
//呼び出し元のアカウントには、十分なトークンがすでに承認されている必要があります(...) - d
//「from」アカウントからの支出と
// - 口座から転送に十分な残高がある必要があります
// - Spenderは転送に十分な余裕を持っていなければなりません
// - 0の値の転送は許可されます
// ------------------------------------------------ ------------------------
function transferFrom(アドレス、アドレス、uintトークンからのアドレス)public returns(bool success){
バランス[from] =バランス[from] .sub(tokens);
許可[from] [msg.sender] =許可[from] [msg.sender] .sub(tokens);
バランス[to] =バランス[to] .add(tokens);
転送(from、to、トークン)。
真を返します。
}
// ------------------------------------------------ ------------------------
//所有者が承認したトークンの量を返します。
//振込先の口座に振り込まれる
// ------------------------------------------------ ------------------------
機能許可(アドレスtokenOwner、アドレスspender)public constant returns(uint remaining){
戻り値[tokenOwner] [spender];
}
// ------------------------------------------------ ------------------------
//トークンの所有者は、 `spender`が` token 'をtransferFrom(...)することを承認できます
//トークン所有者のアカウントから取得します。 「浪費」契約機能
// `receiveApproval(...)`が実行されます
// ------------------------------------------------ ------------------------
関数approveAndCall(払い出し、uintトークン、バイトデータ)public returns(bool success){
[msg.sender] [spender] =トークンを許可しました。
承認(msg.sender、spender、tokens);
ApproveAndCallFallBack(spender).receiveApproval(msg.sender、tokens、this、data);
真を返します。
}
// ------------------------------------------------ ------------------------
// ETHを受け付けない // ------------------------------------------------ ------------------------ function()public payable { revert(); }
// ------------------------------------------------ ------------------------
//所有者は、誤って送信されたERC20トークンを転送できます
// ------------------------------------------------ ------------------------
function transferAnyERC20Token(アドレスtokenAddress、uintトークン)public onlyOwnerは(ブール成功)を返します{
ERC20Interface(tokenAddress).transfer(owner、tokens)を返します。
}
}
</ syntaxhighlight>
Ethereumトークンに関する詳細[編集]
- Ethereum.orgトークンページ:https://www.ethereum.org/token。
- 人気のあるトークンのEtherscanトークンの選択:https://etherscan.io/tokens
- EtherScan ERC20トークン検索:https://etherscan.io/token-search
- HumanStandardToken:名前、小数点記号、シンボル、バージョンを公開変数として提供するERC20の特化版で、契約書から読むことができ、設定する必要はありません:https://github.com/ConsenSys/Tokens/ blob / master / Token_Contracts / contracts / HumanStandardToken.sol
トークンファクトリ。これらのトークンを作成できるアプリケーションで、https://tokenfactory.surge.shで遊ぶだけです。
- ライブラリ:
- OpenZeppelin:https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts/token
- クローン自体を許可するMinimeトークンコントラクト。投票のようなものや別のアプリケーションのトークンを分割することもできます:https://github.com/Giveth/minime