ERC-20トークンのスマートコントラクトを理解する
ERC-20は、イーサリアムで最も重要なスマートコントラクトの1つとして知られており、イーサリアムブロックチェーン上のすべてのスマートコントラクトで代替可能なトークンを実装するために用いられる規格として開発されました。
ERC-20では、すべての代替可能なイーサリアムトークンが順守すべき共通ルールを定義しています。 この規格によって、開発者はイーサリアムの大規模なシステム内で新しいトークンがどのように機能するかを正確に予測できます。 トークンが技術標準のルールに従う限り、すべてのプロジェクトにおいて、新しいトークンがリリースされるたびに最初から開発し直す必要がなくなるため、開発者の負担が軽減されます。
ERC-20で実装しなければならないインターフェイスを以下に提示します。 インターフェイスの詳細については、SolidityのOOPプログラミング(opens in a new tab)についての記事をご覧ください。
1pragma solidity ^0.6.0;23interface IERC20 {45 function totalSupply() external view returns (uint256);6 function balanceOf(address account) external view returns (uint256);7 function allowance(address owner, address spender) external view returns (uint256);89 function transfer(address recipient, uint256 amount) external returns (bool);10 function approve(address spender, uint256 amount) external returns (bool);11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}すべて表示コピー
ここでは、それぞれの関数の役割について説明しています。 その後、ERC-20トークンの簡単な実装をご紹介します。
Getters
1function totalSupply() external view returns (uint256);コピー
存在するトークンの総量を返します。 この関数はgetter関数であり、コントラクトの状態を変更することはありません。 Solidityには浮動小数点が存在しないことに注意してください。 したがって、ほとんどのトークンは18桁で表記され、1トークンに対して10000000000000000となるように総供給量などの結果を返します。 ただし、すべてのトークンが18桁ではないため、トークンを扱うときには注意が必要です。
1function balanceOf(address account) external view returns (uint256);コピー
アドレス(account
)が所有するトークンの量を返します。 この関数はgetter関数であり、コントラクトの状態を変更することはありません。
1function allowance(address owner, address spender) external view returns (uint256);コピー
ERC-20は、あるアドレスが他のアドレスに権限を与え、そのアドレスからトークンを取り戻すことができます。 この関数は、spender
がowner
のために使用可能なトークンの残数を返します。 この関数はgetter関数であり、コントラクトの状態を変更することはありません。したがってデフォルトで0が返ってきます
関数
1function transfer(address recipient, uint256 amount) external returns (bool);コピー
関数を呼び出したアドレス(msg.sender
)から受け取りアドレスにamount
のトークンを送信します。 この関数は、後で定義するTransfer
イベントを発行します。 トークンの送金が可能な場合、trueを返します。
1function approve(address spender, uint256 amount) external returns (bool);コピー
関数を呼び出したアドレス(msg.sender
)の残高からspender
が送金できるallowance
を設定します。 この関数は、承認イベントを発行します。 この関数は、承認が成功したか否かを返します。
1function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);コピー
amount
のトークンをsender
からrecipient
へ承認メカニズムを使って送金します。 関数を呼び出したアドレスから手数料が差し引かれます。 この関数は、Transfer
イベントを発行します。
イベント
1event Transfer(address indexed from, address indexed to, uint256 value);コピー
トークンの量(値)がfrom
アドレスからto
アドレスに送信されると、このイベントが発行されます。
新しいトークンをミントする場合、送金イベントは通常from
0x00...0000アドレスであるのに対し、トークンをバーンする場合はto
0x00...0000となります。
1event Approval(address indexed owner, address indexed spender, uint256 value);コピー
このイベントは、トークンの量(value
)がowner
によって、spender
に使用することが承認されたときに発行されるものです。
ERC-20トークンの基本的な実装
ERC-20トークンのベースとなるシンプルなコードを以下にご紹介します。
1pragma solidity ^0.8.0;23interface IERC20 {45 function totalSupply() external view returns (uint256);6 function balanceOf(address account) external view returns (uint256);7 function allowance(address owner, address spender) external view returns (uint256);89 function transfer(address recipient, uint256 amount) external returns (bool);10 function approve(address spender, uint256 amount) external returns (bool);11 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);121314 event Transfer(address indexed from, address indexed to, uint256 value);15 event Approval(address indexed owner, address indexed spender, uint256 value);16}171819contract ERC20Basic is IERC20 {2021 string public constant name = "ERC20Basic";22 string public constant symbol = "ERC";23 uint8 public constant decimals = 18;242526 mapping(address => uint256) balances;2728 mapping(address => mapping (address => uint256)) allowed;2930 uint256 totalSupply_ = 10 ether;313233 constructor() {34 balances[msg.sender] = totalSupply_;35 }3637 function totalSupply() public override view returns (uint256) {38 return totalSupply_;39 }4041 function balanceOf(address tokenOwner) public override view returns (uint256) {42 return balances[tokenOwner];43 }4445 function transfer(address receiver, uint256 numTokens) public override returns (bool) {46 require(numTokens <= balances[msg.sender]);47 balances[msg.sender] = balances[msg.sender]-numTokens;48 balances[receiver] = balances[receiver]+numTokens;49 emit Transfer(msg.sender, receiver, numTokens);50 return true;51 }5253 function approve(address delegate, uint256 numTokens) public override returns (bool) {54 allowed[msg.sender][delegate] = numTokens;55 emit Approval(msg.sender, delegate, numTokens);56 return true;57 }5859 function allowance(address owner, address delegate) public override view returns (uint) {60 return allowed[owner][delegate];61 }6263 function transferFrom(address owner, address buyer, uint256 numTokens) public override returns (bool) {64 require(numTokens <= balances[owner]);65 require(numTokens <= allowed[owner][msg.sender]);6667 balances[owner] = balances[owner]-numTokens;68 allowed[owner][msg.sender] = allowed[owner][msg.sender]-numTokens;69 balances[buyer] = balances[buyer]+numTokens;70 emit Transfer(owner, buyer, numTokens);71 return true;72 }73}すべて表示コピー
ERC-20トークン規格のもう1つのすばらしい実装として、OpenZeppelin ERC-20実装(opens in a new tab)があります。
最終編集者: @nhsz(opens in a new tab), 2023年8月15日