スクリーンショット_2019-12-23_18

ERC1155を読む

この記事は VALU Advent Calendar 2019の23日目の記事です。

こんにちは。VALU社で色々やっている菊池です。
今日はブロックチェーン人材です。ERC1155の話をします。

ERC1155 - Multi Token Standard

Ethereum上でトークンを表現するための規格としては、ERC20やERC223、ERC721が有名ではありますが、近頃ERC1155という規格がFinalizeされました。(ちなみにERC223はまだDraftです)

https://github.com/ethereum/eips/issues/1155
提案の内容

https://github.com/enjin/erc-1155
提案者によるリファレンス実装

ざっくりした説明としては、提案のAbstractを読むに、1つのコントラクトで複数種類のFungible TokenとNon Fungible Tokenをどっちも扱えるよ、といった感じでしょうか。それだけだとナンノコッチャ、という感じですね。ブロックチェーン難しい。


ソースコードを読む

そこで我々プログラマーとしては、とりあえずソースコードがあれば読んでみるのが早いですよね。そして、トークンの規格って何よってのは、つまるところインタフェースの定義なので、そちらを見てみましょう。 まずは、リファレンス実装のソースコード内で一番それっぽいファイル名の contracts/IERC1155.sol からいきましょう。

このファイルには、全部で5つのインタフェースメソッドが定義されています。1つ1つ見ていきましょう!

safeTransferFrom

    /**
       @param _from    Source address
       @param _to      Target address
       @param _id      ID of the token type
       @param _value   Transfer amount
       @param _data    Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
   */
   function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;

送信元アドレス から 送信先アドレス にトークンを送付するメソッドのようです。
送信元、送信先情報や送信数量に加えて、トークンIDや任意の追加情報を指定して送る機能ですね。ERC1155では、このトークンIDが大事そうです。

safeBatchTransferFrom

    /**
       @param _from    Source address
       @param _to      Target address
       @param _ids     IDs of each token type (order and length must match _values array)
       @param _values  Transfer amounts per token type (order and length must match _ids array)
       @param _data    Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
   */
   function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;

こちらは、ほぼ safeTransferFrom と同じです。違いといえば、渡せるトークンIDが複数になっていること、そして同じくvalueも複数指定可能になっているくらいですね。BatchTransferという名前の通り、複数種類のトークンを同時に送信できるメソッドのようです。

balanceOf

    /**
       @notice Get the balance of an account's Tokens.
       @param _owner  The address of the token holder
       @param _id     ID of the Token
       @return        The _owner's balance of the Token type requested
    */
   function balanceOf(address _owner, uint256 _id) external view returns (uint256);

残高取得です。任意のaddressの、任意のIDに対応するトークンの残高を取得します。

balanceOfBatch

    /**
       @notice Get the balance of multiple account/token pairs
       @param _owners The addresses of the token holders
       @param _ids    ID of the Tokens
       @return        The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
    */
   function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);

前述のbalanceOfの複数トークンID指定版

setApprovalForAll

    /**
       @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
       @dev MUST emit the ApprovalForAll event on success.
       @param _operator  Address to add to the set of authorized operators
       @param _approved  True if the operator is approved, false to revoke approval
   */
   function setApprovalForAll(address _operator, bool _approved) external;

特定のアドレスに対して、自分のトークンの変更を許可するためのメソッドですね。
OAuthみたいな感じで、3rd-partyアプリケーションに自分のトークンのTransferを許可するみたいなやつですね。

isApprovedForAll

    /**
       @notice Queries the approval status of an operator for a given owner.
       @param _owner     The owner of the Tokens
       @param _operator  Address of authorized operator
       @return           True if the operator is approved, false if not
   */
   function isApprovedForAll(address _owner, address _operator) external view returns (bool);

こちらは approvedForAll の getter ですね。 owner が operator に操作を許可しているかどうかがわかります。


続いて、IERC1155Metadata_URLに定義されているメソッドです

uri

    /**
       @notice A distinct Uniform Resource Identifier (URI) for a given token.
       @dev URIs are defined in RFC 3986.
       The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema".        
       @return URI string
   */
   function uri(uint256 _id) external view returns (string memory);

トークンのメタデータを取得するためのURIを返却するメソッドです。そんなURIの指し示す先は何かというと、

The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema".

と書いてあるように、ERC-1155 Metadata URI JSON Scheme に準拠したJSONだそうです。そしてこのJSONスキーマでは、

・name: アセット名
・decimals: 小数点以下桁数
・description: アセットの説明
・image: アセットの画像
・properties: 追加情報(好きに使えそう)

上記5つのプロパティが利用可能です。ERC20やERC721ではコントラクトごとに持たせていたプロパティが、ERC1155ではコントラクト内のトークンIDごとに定義できるようです。


ERC1155大体わかった

なるほど、ここまでで、大体ERC1155の大枠はわかってきました。
ERC20で表現できるのは、1コントラクトにつき1トークンでしたし、ERC721でも、1コントラクトにつき(表現が難しいけれど)1セットのNFTの集合を表現してきました。

スクリーンショット 2019-12-23 18.34.55

各コントラクトに各トークンやアセットの集合が
定義されているイメージ(伝われ)


一方でERC1155では、1つのコントラクトに、複数種類のトークンを定義できるようです。そしてそれは、fungible-tokenとnon-fungible-tokenといった異なる特性のトークンであっても同居可能です。

スクリーンショット 2019-12-23 18.45.33

1つのコントラクトに複数の種別のトークンが同居できるイメージ(伝われ)


IERC1155TokenReceiver

さてもう大体わかったのでそろそろオシマイにしたいのですが、実はもう1個インターフェースが記述されているファイルが残っていました。IERC1155TokenReceiver.sol です。さらっと解説できればと思ったのですが、意外と分量が多そうなので、またの機会に勉強して解説できればと思っています。


まとめ

ERC1155規格について、solidityコードで記述されたinterfaceを読み取ることで、ざっくりどんな規格なのかを学びました。

複数のトークンを扱うようなサービスを考えるにあたっては、ERC1155で提案されているような、1コントラクトに複数トークンが同居できるような仕組みはとても有用そうだなーと思いました。

一方で、ERC1155は2019/12/23現在はまだMetaMaskも未対応ですし、その他のウォレットアプリでも対応状況は芳しくないです。これからERC1155がどんどん使われていって、多くのアプリケーションが対応していって、名実ともにトークン規格のデファクトになると嬉しいな、ワクワクしますね。


この記事が気に入ったらサポートをしてみませんか?