ERC-1155 マルチトークン規格
はじめに
複数のトークンタイプを管理するコントラクトの標準インターフェースです。デプロイされた単一のコントラクトには、代替可能トークン、非代替性トークン (NFT)、またはその他の構成 (半代替可能トークンなど) の任意の組み合わせを含めることができます。
マルチトークン規格とは何ですか?
そのアイデアはシンプルで、任意の数の代替可能トークンおよび非代替性トークンのタイプを表現し、制御できるスマート・コントラクトのインターフェースを作成することを目指しています。これにより、ERC-1155トークンはERC-20およびERC-721トークンと同じ機能を果たすことができ、さらに両方を同時に機能させることも可能です。ERC-20およびERC-721規格の両方の機能を向上させ、より効率的にし、明らかな実装エラーを修正します。
ERC-1155トークンの詳細は、EIP-1155 (opens in a new tab)で完全に説明されています。
前提条件
このページをよりよく理解するために、まずはトークン規格、ERC-20、およびERC-721について読むことをお勧めします。
ERC-1155の機能と特徴:
- 一括送金 (Batch Transfer): 1回の呼び出しで複数の資産を送金します。
- 一括残高照会 (Batch Balance): 1回の呼び出しで複数の資産の残高を取得します。
- 一括承認 (Batch Approval): あるアドレスに対してすべてのトークンを承認します。
- フック (Hooks): トークン受信時のフックです。
- NFTサポート: 供給量が1の場合、NFTとして扱います。
- 安全な送金ルール (Safe Transfer Rules): 安全な送金のためのルールセットです。
一括送金
一括送金は、通常のERC-20の送金と非常によく似た働きをします。通常のERC-20のtransferFrom関数を見てみましょう。
// ERC-20
function transferFrom(address from, address to, uint256 value) external returns (bool);
// ERC-1155
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external;
ERC-1155における唯一の違いは、値を配列として渡し、さらにIDの配列も渡すことです。たとえば、ids=[3, 6, 13]およびvalues=[100, 200, 5]が与えられた場合、結果として以下の送金が行われます。
_fromから_toへ、IDが3のトークンを100個送金する。_fromから_toへ、IDが6のトークンを200個送金する。_fromから_toへ、IDが13のトークンを5個送金する。
ERC-1155にはtransferFromのみが存在し、transferはありません。通常のtransferのように使用するには、fromアドレスを関数を呼び出しているアドレスに設定するだけです。
一括残高照会
対応するERC-20のbalanceOf呼び出しにも同様に、一括処理をサポートするパートナー関数があります。参考までに、以下はERC-20のバージョンです。
// ERC-20
function balanceOf(address owner) external view returns (uint256);
// ERC-1155
function balanceOfBatch(
address[] calldata _owners,
uint256[] calldata _ids
) external view returns (uint256[] memory);
残高照会はさらにシンプルで、1回の呼び出しで複数の残高を取得できます。所有者の配列を渡し、その後にトークンIDの配列を渡します。
たとえば、_ids=[3, 6, 13]および_owners=[0xbeef..., 0x1337..., 0x1111...]が与えられた場合、戻り値は以下のようになります。
[
balanceOf(0xbeef...),
balanceOf(0x1337...),
balanceOf(0x1111...)
]
一括承認
// ERC-1155
function setApprovalForAll(
address _operator,
bool _approved
) external;
function isApprovedForAll(
address _owner,
address _operator
) external view returns (bool);
承認はERC-20とは少し異なります。特定の金額を承認するのではなく、setApprovalForAllを介してオペレーターを承認済みまたは未承認に設定します。
現在のステータスの読み取りは、isApprovedForAllを介して行うことができます。お分かりのように、これは「すべてかゼロか」の操作です。承認するトークンの数や、どのトークンクラスを承認するかを定義することはできません。
これはシンプルさを念頭に置いて意図的に設計されています。1つのアドレスに対してすべてを承認することしかできません。
受信フック
function onERC1155BatchReceived(
address _operator,
address _from,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external returns(bytes4);
EIP-165 (opens in a new tab)のサポートにより、ERC-1155はスマート・コントラクトに対してのみ受信フックをサポートします。フック関数は、以下のように事前に定義されたマジックbytes4値を返す必要があります。
bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))
受信側のコントラクトがこの値を返した場合、そのコントラクトは送金を受け入れ、ERC-1155トークンの処理方法を知っていると見なされます。これで、コントラクト内にトークンが閉じ込められることはなくなります!
NFTサポート
供給量が1つだけの場合、そのトークンは実質的に非代替性トークン (NFT) となります。そして、ERC-721の標準と同様に、メタデータのURLを定義できます。このURLはクライアントによって読み取りおよび変更が可能です。詳細はこちら (opens in a new tab)をご覧ください。
安全な送金ルール
これまでの説明で、すでにいくつかの安全な送金ルールに触れてきました。しかし、その中で最も重要なルールを見てみましょう。
- 呼び出し元は、
_fromアドレスのトークンを使用することを承認されているか、呼び出し元が_fromと等しくなければなりません。 - 以下の場合、送金の呼び出しはリバートしなければなりません。
_toアドレスが0である。_idsの長さが_valuesの長さと同じではない。_ids内のトークンの保有者の残高のいずれかが、受信者に送られる_values内のそれぞれの金額よりも少ない。- その他のエラーが発生した。
注: フックを含むすべての一括処理関数には、一括処理を行わないバージョンも存在します。これは、1つの資産のみを送金することが依然として最も一般的に使用される方法である可能性が高いことを考慮し、ガス効率を高めるために行われています。安全な送金ルールを含め、説明をシンプルにするためにこれらは省略しています。名前は同一で、「Batch」を削除するだけです。