メインコンテンツへスキップ
Change page

ERC-223 トークン標準

はじめに

ERC-223とは?

ERC-223は、ERC-20標準と同様の代替性トークンのための標準です。主な違いは、ERC-223がトークンのAPIだけでなく、送信者から受信者へトークンを送金するロジックも定義している点です。これにより、トークンの送金を受信者側で処理できる通信モデルが導入されています。

ERC-20との違い

ERC-223はERC-20のいくつかの制限に対処し、トークンコントラクトとトークンを受信する可能性のあるコントラクトとの間の新しい相互作用の方法を導入しています。ERC-20では不可能ですが、ERC-223では可能ないくつかの点があります。

  • 受信者側でのトークン送金処理: 受信者は、ERC-223トークンが入金されていることを検知できます。
  • 不適切に送信されたトークンの拒否: ユーザーがトークンを受信することを想定していないコントラクトにERC-223トークンを送信した場合、コントラクトはトランザクションを拒否し、トークンの喪失を防ぐことができます。
  • 送金時のメタデータ: ERC-223トークンにはメタデータを含めることができ、トークンのトランザクションに任意の情報を添付できます。

前提知識

本文

ERC-223は、スマート・コントラクト内のトークン用APIを実装するトークン標準です。また、ERC-223トークンを受信することを想定したコントラクト用のAPIも宣言しています。ERC-223 Receiver APIをサポートしていないコントラクトはERC-223トークンを受信できないため、ユーザーのエラーを防ぐことができます。

スマート・コントラクトが以下のメソッドとイベントを実装している場合、それはERC-223互換のトークンコントラクトと呼ぶことができます。デプロイされると、イーサリアム上で作成されたトークンを追跡する役割を担います。

コントラクトはこれらの関数のみを持つ義務はなく、開発者は他のトークン標準から任意の機能を追加することができます。例えば、approvetransferFrom関数はERC-223標準の一部ではありませんが、必要であればこれらの関数を実装することができます。

EIP-223 (opens in a new tab)より:

メソッド

ERC-223トークンは以下のメソッドを実装する必要があります。

function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success)

ERC-223トークンを受信することを想定しているコントラクトは、以下のメソッドを実装する必要があります。

function tokenReceived(address _from, uint _value, bytes calldata _data)

ERC-223トークンがtokenReceived(..)関数を実装していないコントラクトに送信された場合、送金は失敗し、送信者の残高からトークンが移動してはなりません。

イベント

event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data)

ERC-223トークンのAPIはERC-20のAPIと似ているため、UI開発の観点からは違いはありません。唯一の例外は、ERC-223トークンにはapproveおよびtransferFrom関数がない場合があることです。これらはこの標準ではオプションであるためです。

Solidityの例

以下の例は、基本的なERC-223トークンコントラクトがどのように動作するかを示しています。

次に、tokenAがERC-223トークンであると仮定して、別のコントラクトがtokenAの入金を受け付けるようにします。このコントラクトはtokenAのみを受け付け、他のトークンは拒否しなければなりません。コントラクトがtokenAを受け取ったとき、Deposit()イベントを発行し、内部のdeposits変数の値を増加させる必要があります。

コードは以下の通りです。

よくある質問

コントラクトにtokenBを送信するとどうなりますか?

トランザクションは失敗し、トークンの送金は行われません。トークンは送信者のアドレスに返還されます。

このコントラクトにどうやって入金できますか?

RecipientContractのアドレスを指定して、ERC-223トークンのtransfer(address,uint256)またはtransfer(address,uint256,bytes)関数を呼び出します。

このコントラクトにERC-20トークンを送金するとどうなりますか?

ERC-20トークンがRecipientContractに送信された場合、トークンは送金されますが、その送金は認識されません(Deposit()イベントは発行されず、入金値も変更されません)。望まないERC-20の入金をフィルタリングしたり防いだりすることはできません。

トークンの入金完了後に何らかの関数を実行したい場合はどうすればよいですか?

これを行うには複数の方法があります。この例では、ERC-223の送金をイーサの送金と同じにする方法に従います。

RecipientContractがERC-223トークンを受け取ると、コントラクトはトークントランザクションの_dataパラメータとしてエンコードされた関数を実行します。これは、イーサのトランザクションが関数呼び出しをトランザクションのdataとしてエンコードするのと同じです。詳細については、データフィールドをお読みください。

上記の例では、ERC-223トークンはtransfer(address,uin256,bytes calldata _data)関数を使用してRecipientContractのアドレスに送金される必要があります。データパラメータが0xc2985578foo()関数の署名)である場合、トークンの入金を受け取った後にfoo()関数が呼び出され、Foo()イベントが発行されます。

パラメータはトークン送金のdataにエンコードすることもできます。例えば、_someNumberに12345の値を指定してbar()関数を呼び出すことができます。この場合、data0x0423a13200000000000000000000000000000000000000000000000000000000000004d2でなければなりません。ここで、0x0423a132bar(uint256)関数の署名であり、00000000000000000000000000000000000000000000000000000000000004d2はuint256としての12345です。

制限事項

ERC-223はERC-20標準に見られるいくつかの問題に対処していますが、独自の制限がないわけではありません。

  • 普及と互換性: ERC-223はまだ広く普及していないため、既存のツールやプラットフォームとの互換性が制限される可能性があります。
  • 下位互換性: ERC-223はERC-20との下位互換性がありません。つまり、既存のERC-20コントラクトやツールは、変更を加えない限りERC-223トークンでは機能しません。
  • ガス代: ERC-223の送金における追加のチェックや機能により、ERC-20のトランザクションと比較してガス代が高くなる可能性があります。

参考文献