ERC1155のDEX取引 [PART3]

GAME
GAME
Published in
15 min readMar 27, 2019

今回は、前回軽く触れていたERC1155の規格と、現状のトークンで表現されているゲームアイテム、及びその交換プロトコルをDEX上でどのように実装するのかについて説明する。

MOLDEXのコンセプトについては前回の記事を参考にされたい。

ERC721トークンで表現されたゲームアイテム

Cryptokittiesに始まり、現状のEthereum DappsゲームではERC721規格に沿ったトークンが中心になっている。ERC721 token規格では、Non Fungible(不可換)なトークンのメタデータを定義して、それをゲームアイテムやキャラクターとして利用する。

例をあげると、CryptokittiesではERC721トークンのIdと紐づいたKittyという構造体(struct)を定義し、そこにキャラクターに必要なパラメータを格納していく。

:kitty.sol
struct Kitty {
uint256 gene;
uint64 birthTime;
uint64 cooldownEndBlock;
uint32 matronId;
uint32 sireId;
uint32 siringWithId;
uint16 cooldownIndex;
uint16 generation;
}

Cryptokitteisでは、この構造体に含まれるパラメータによってERC721トークンで表現されるキャラクターのメタデータを管理している。様々なDapps Gameが存在してるが、ERC721に準拠したトークンでは、1つ1つのトークンに振られたidとこのメタデータによってアイテムを区別している。

Dappでゲームアイテムを表現するということ

このようなメタデータによる「ゲームアイテムの抽象化」は、Dapps開発において非常に重要な要素である。CryptoKittiesの例では、メタデータの中には外見を決めるファクターとなるgeneに加え、交配や親、世代に関する情報が含まれている。これらの情報をメタデータに含めることによって、オークション機能や交配機能に対応しているわけだが、一方でそれ以上の機能を今後追加するのは難しいとも言える。

このように、Dappにおいてははじめに定めたデータ構造が、その後のゲームの発展性に大きく影響すると言える。

Etheremonの例も見て見ると、モンスターを表現する構造体として、下のような構造体が定義されている。

:etheremon.sol
struct MonsterObj {
uint64 monsterId;
uint32 classId;
address trainer;
string name;
uint32 exp;
uint8[] statBases;
uint8[] skills;
uint32 createIndex;
uint32 lastClaimIndex;
uint createTime;
}

例えばこのstructでは、statBasesというのが初期のモンスターのパラメータ、skillsというのが追加されていくスキルやパラメータを表現していると想像できる。CryptoKittiesの例でも確認したが、はじめに定めたメターデータの構造によって、その後のゲームの拡張性が大きく変わってしまうのである。

以下では、ERC721トークンがゲームアイテムを適切に表現できているかの考察と、ERC1155トークンの有用性、その実装サンプルを見ていきたいと思う。

ERC721トークンはゲームアイテムを表現できているか

ERC721トークンに準拠したDappsゲームでは、ゲームアイテムはNon-Fungibleなトークンとして、1つ1つ区別できるように表現されている。確かに1つ1つのアイテムが独自の属性を持っていたり、ユーザーが育成することでパラメータが変化していくようなアイテムについてはNon Fungible Tokenでの表現は適切であると言える。

しかしアイテムごとにパラメータが変化しない付属品のようなアイテム(例:「薬草」「剣」「小石」など)に関しては、Fungibleなトークンとして表現される方が適切である。本来Fungibleなトークンに対して個別のメタデータを付与することは、データリソースを節約したいブロックチェーンゲームにおいて無駄が生じる上に、ブロックチェーンゲームの革新性のコアとも言える、ゲームアイテムの流動性を下げる原因にもなってしまう。

例を1つ考えてみようと思う。あるゲーム内で、1つ1つ区別する必要のない「普通の剣」と、1つ1つパラメータの異なる「レアな剣」があったとする。本来前者はFungible、後者はNon Fungibleなトークンとして表現されるのが適切である。しかし全てのアイテムをNon Fungibleなアイテムに分類してしまった場合、「普通の剣10コ」と「レアな剣1コ」を交換したいときに、「普通の剣10コ」を1つ1つ別々の剣として交換する必要がある。
そのため、交換の際に余計なトランザクションコストが発生してしまう。これはトランザクション手数料が大きな課題の一つであるブロックチェーンゲームにおいては大きな損失であると考える。

この点で、ERC721規格に変わる、Non FungibleなトークンとFungibleなトークンの両方を表現できる新たなトークン規格が必要であると考えている。以降は、我々が現在採用を予定しているERC1155Tokenについて解説していきたいと思う。

ERC1155規格の概観

複数のトークンタイプを管理するスマートコントラクトのための標準インタフェース。 単一のERC1155コントラクトには、Fungible token、Non Fungible token、またはその他の構成(たとえば、半代替トークン)の任意の組み合わせを含めることができる。

この規格は、任意の数のFungibleおよびNon-Fungibleトークンタイプを表すことができるスマートコントラクトインターフェイスである。 ERC-20などの既存の規格では、トークンタイプごとに別々のコントラクトをデプロイする必要がある。 ERC-721規格のトークンIDは単一の非代替インデックスであり、これらの非代替グループはコレクション全体の設定を含む単一のコントラクトとしてデプロイされる。 これとは対照的に、ERC-1155マルチトークン規格では、各トークンIDが新しい設定可能なトークンタイプを表すことを可能にしている。このトークンタイプには、独自のメタデータ、サプライ、その他の属性がある。

_idパラメータは各関数のパラメータに含まれており、トランザクション内の特定のトークンまたはトークンタイプを示す。

ERC-20やERC-721などのトークン規格では、トークンの種類ごとに別々のコントラクトをデプロイする必要がある。 これは、Ethereumブロックチェーンに多くの冗長なバイトコードを配置し、各トークンコントラクトをそれ自体の許可されたアドレスに分離するという性質により、特定の機能を制限してしまうことになる。 ブロックチェーンゲームやそれをサポートするプラットフォームの登場により、ゲーム開発者は何千ものトークンタイプを作成している可能性があり、それらをサポートするには新しいタイプのトークン標準が必要となる。 ただし、ERC-1155はゲームに固有のものではないため、他の多くのアプリケーションでもこの柔軟性の恩恵を受けることができる。

この設計では、一度に複数のトークンタイプを転送し、トランザクションコストを節約するなどの新しい機能が可能になる。 複数のトークンの取引(エスクロー/アトミックスワップ)はこの標準の上に構築することができ、それは個々のトークン契約を別々に “承認”する必要性を取り除く。 単一の契約で複数の代替可能または代替不可能なトークンタイプを記述し、混在させることも簡単になる。

ERC1155のspec

以下は、EIP1155を元に、ERC1155Tokenの要件について、特徴的な部分を説明する。

FungibleとNon Fungibleの区別

コントラクトで使用されている_idはuint256で、前半後半を128bitずつ分けることができる。

便宜上、前半部分をTokenId、後半部分をIndexIdと呼ぶことにする。

例えば、ERC1155のmint関数を実行して、FungibleTokenを1回生成し、mintNonFungible関数でNonFungibleTokenを2回生成すると_idは次のようになる。

つまり、次のような特徴がある。

  • FTの先頭は常に0になる
  • FTのIndexId(後半のId)は、常に0000000000000000になる
  • NFTの先頭は常に1になる
  • NFTのIndexId(後半のId))は、mintNonFungible関数が実行されるたびに増えていく。

したがって、ERC1155では、FTとNFTの区別を_idの先頭(0 or 1)で行い、NFTの区別を後半のIndexIdで行なっている。もちろん、FT同士は区別しない。

トークンの移動

:erc1155Spec.sol
// 複数のトークンを移動
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external;
// トークンの移動
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external;

上記のように、ERC1155Tokenには、safeTransferFromの他に、safeBatchTransferFromという関数が用意されている。ここでは、uint256[] _ids, uint256 _valueで、複数トークンのIdと移動する値を指定することができる。

つまり、FungibleなトークンAを10コ、Non FungibleなトークンBを1コ、Non FungibleなToken Cを1コまとめて、1回のトランザクションで交換するというようなことが可能となる。

ERC1155Tokenのメタデータをどう定めるか

はじめに述べたように、ゲームアイテムを定義する際に、メタデータの構造をどのように定めるか、というのは非常に重要な点である。
ERC1155トークンではトークンを後から自由に生成できる一方で、メタデータはあとから自由に設定することはできない。そのためERC1155トークンをゲームアイテムとして利用する際には、はじめにメタデータを注意深く設定する必要がある。

先の例で見たように、CryptoKittiesのメタデータと、Etheremonのメタデータはかなり中身が異なっている。これはCryptoKittiesにはバトルという概念がない一方で、Etheremonにはバトルやスキルの成長、進化と言ったパラメータが存在することにある。実際に拡張性の高いゲームを作ろうと思った際に、例えばNon Fungibleなトークンの例を考えると、バトルをするアイテム(キャラクター)とバトルとは関係ないアイテムの両方を登場させる必要があるだろう(例:モンスターと装備アイテム)。またゲームの進行と共に成長するアイテム(キャラクター)もあれば、初期値のままパラメータが変化しないキャラクターもいるだろう。またFungibleなトークンについても、回復アイテムである「薬草」もあれば、スキルを強化する「剣」や「銃」と言ったアイテムもある。

このような違いを表現できるような、かつ抽象化したメタデータをどう設定するか。ERC1155トークンをゲームアイテムとして使用する際には、この点が非常に難しいポイントになると考えれる。

Non FungibleなERC1155トークンのメタデータとしては、ERC721事例を参考にすると、geneやskillと言ったメタデータを定義し、成長や変化のあるトークンの場合にはこれらの値を適切に変化させていくことで、キャラクターの成長などを表現できるのではないだろうか。

一方Fungibleなトークンでは、既存のERC20トークンにも含まれるtotalSupplyやnameといったパラメータに加え、そのアイテムがもつ特性に関する情報を含むパラメータとして、stringやuint型で、skillsやeffectsと言った配列型のメタデータを与えるなどが考えられるのではないだろうか。

いずれにせよ適切なメタデータを設定することで、既存のDappsゲームに比べて拡張性・流動性の高いゲームを作ることができるようになる。

ERC1155Tokenのメタデータ設定のサンプル

以下では、ERC1155を使ったゲームアイテムの例をあげる。例えば、Non Fungibleなトークンの例として以下を考えてみる。

:nonFungible.sol
struct NonFungibleMetaData {
uint256 id;
uint256 genes;
uint8[] skills;
string name;
uint256 winCount;
uint256 papaId;
uint256 momId;
uint256 saleDuration;
bool isOnSale;
}

この例では、Non Fungibleトークンの名前・能力・外見・交配・オークション等の機能に対応できるように、メタデータを設定した。これは既存のDappキャラクターをイメージしてもらえば、上記の機能で概ね必要十分ではないだろうか。

一方、Fungibleなトークンとして、以下を考える。

:fungible.sol
struct FungibleItems {
string name;
uint256 totalSupply;
uint256 itemPrice;
FungibleItemExecInterface tokenContract;
mapping(address => uint256) balances;
}

ここでは、Fungibleなトークンの名前・総供給量・価格・保有量、アイテムの実行インターフェースを用意している。
FungibleItemExecInterfaceを上手く設定することによって、薬草や武器といったFungibleなアイテムを抽象化し、さらにアイテムの実行まで行うことができる。

以下ではFungibleItemExecInterfaceの例を示す。

:fungibleItemEffect.sol
contract FungibleItemExecInterface {
function modifyGenes(uint256 _gene) external returns(uint256);
function modifySkills(uint8[] _skills) external returns(uint8[]);
}

ここでは、2つの関数を定義している。modifyGenesは、nonFungibleItemのgeneを受け取り、変更したgeneを返す関数。
一方、modifySkillsはnonFungibleItemのskillsを受け取り、変更したskillsを返す関数である。
このようにインターフェースを定義することで、アイテムごとにキャラクターに与える効果を変更することができる。
バトルやガチャのようなゲームごとに独自の機能を実装したい場合、オフチェーンとの連携も含めさらに考慮する問題はあるが、上記のようなメタデータを設定しておくことで、複数のアイテムに柔軟に対応できるのではないだろうか。

ERC1155Token対応のDex

上で説明してきたような説明があるERC1155 Token対応のDexを構築することにより、MOLDEX α版においては、より柔軟なトークンの移転を実現する。
現状のERC721のDexにおいては、Non Fungibleなトークンのみに対応しているが、FungibleなTokenも含むERC1155規格に対応することで、MOLDEXにおいてはNon Fungibleなアイテムやキャラクターだけでなく「10コの薬草を買う」と言ったFungibleなアイテムの購入にも対応する。これにより、ゲーム間の資産移転がより活発になるだけだなく、ERC1155トークンの普及にも貢献し、Dapps Gameが一層発展を遂げることに貢献できれば幸いである。

— — — — — — — — — — — — — — — -
Cosmos Gaming Hub Project(旧MOLD Project)
CEO & Co-Founder

朝野 巧己

全てのゲーム愛好家に最高のエンターテイメントを届けるために

--

--

GAME
GAME
Editor for

Cosmos Gaming Hub is a fair and secure distributed gaming platform which supports the development of new games and simplifies the trading of digital assets.