はじめに
初めまして。 CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です! スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
代表的なゲームはクリプトスペルズというブロックチェーンゲームです。
今回は、EIP20やEIP721、EIP1155などのトークンを生成したり、破棄したりする際の実装を統一する提案をしているEIP5679についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
動機
EIP20やEIP721、EIP1155などのトークンのMint(生成)とBurn(破棄)はよく実行されます。
トークンのMint(生成)とBurn(破棄)の実行を統一した方法で行いベースとなるライフサイクルを提案します。
EIP721やEIP1155のいくつかの実装では、送付(Transfer)関数などを使用してトークンをMint(生成)とBurn(破棄)できます。
ただし、トークンのMint(生成)とBurn(破棄)はトークンの供給量を変更します。
Mint(生成) → トークンの供給量が増える。 Burn(破棄) → トークンの供給量が減る。
また、Mint(生成)とBurn(破棄)のアクセス制御は通常、送付(Transfer)関数とは異なる方法で実装されます。
そのため、統一された標準的な実装を提案してMint(生成)とBurn(破棄)を行うことで、実装を簡素化し、セキュリティエラーを減らすことができます。
仕様
EIP20
この提案による、EIP20に準拠したコントラクトを実装する際は以下のインターフェースを実装する必要があります。
「そもそもインターフェースって何?」という方は以下の記事を参考にしてください!
interface IERC5679Ext20 {
function mint(address _to, uint256 _amount, bytes calldata _data) external;
function burn(address _from, uint256 _amount, bytes calldata _data) external;
}EIP721
この提案による、EIP721に準拠したコントラクトを実装する際は以下のインターフェースを実装する必要があります。
interface IERC5679Ext721 {
function safeMint(address _to, uint256 _id, bytes calldata _data) external;
function burn(address _from, uint256 _id, bytes calldata _data) external;
}EIP1155
この提案による、EIP1155に準拠したコントラクトを実装する際は以下のインターフェースを実装する必要があります。
interface IERC5679Ext1155 {
function safeMint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
function safeMintBatch(address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
function burn(address _from, uint256 _id, uint256 _amount, bytes[] calldata _data) external;
function burnBatch(address _from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata _data) external;
}仕様の補足
- トークンの
Mint(生成)
トークンがMint(生成)される際、EIP20かEIP1155の場合は_amountで指定されたトークン、EIP721かEIP1155の場合は_idで指定されたトークンが0x0(0アドレス)からトークンの受け取りてのアドレス(_toで指定)に送付(Transfer)されたのちTransfer Eventを発行する必要があります。
totalSupply(総供給量)はMint(生成)されたトークン数に応じて増加させます。
- トークンの
Burn(破棄)
トークンがBurn(破棄)される際、EIP20かEIP1155の場合は_amountで指定されたトークン、EIP721かEIP1155の場合は_idで指定されたトークンがトークンの受け取りてのアドレス(_toで指定)から0x0(0アドレス)に送付(Transfer)されたのちTransfer Eventを発行する必要があります。
totalSupply(総供給量)はMint(生成)されたトークン数に応じて減少させます。
- トークンの
safeMint(生成)
safeMintは、EIP721やEIP1155で定義されているsafeTransferFromと同じ受け取りアドレスのチェックを実装する必要があります。
ここでのチェックとは、受け取りてのアドレスがコントラクトの場合にEIP721やEIP1155に対応しているかです。
- EIP165対応
上記を実装するにあたり、EIP165の実装が推奨されます。 実装としては以下のように、ERC5679が対応されているかチェックできるようにします。
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}補足
- インターフェースは統一しない
EIP1155と同じく、EIP20やEIP721、EIP1155のいずれであっても
_amountを常に引数にとるようなインターフェースにすることも可能です。 しかし、各EIPトークンは、元のトークンに実装されている_idと_amountに従って、インターフェースを定義しています。
EIP721規格では、Mint(生成)量が1となっているため、_amountは引数に定義されていません。
-
Eventは既存のトークンの機能を使用 新しいイベントを作成せずに、既存のEIP20やEIP721内の
Transfer Evenetを使用しています。 これは、EIP20やEIP721、EIP1155との互換性を持たせるためです。 -
EIP1155の機能の追加 EIP1155には
safeMintBatchおよびburnBatchメソッドを追加することを選択しましたが、EIP721の方には追加されていません。 これは、EIP721の提案に従ったためです。
EIP777には拡張を追加していません。
理由としては、EIP777は既にMintingとBurningが実装されているためです。
後方互換性
このEIPは、それぞれEIP20やEIP721、EIP1155と互換性があるように設計されています。
セキュリティ
EIP20やEIP721、EIP1155などのコントラクトでは、新しいトークンをMint(生成)できる権限のアクセス制御を注意深く設計する必要があります。
設計にミスがあると、不正にトークンをMint(生成)してtotalSupply(総供給量)の増加が引き起こされる可能性があります。
Burn(破棄)についても、アクセス制御を注意深く設計する必要があります。
通常、以下の2つのロールだけがトークンをBurn(破棄)する権限を持ちます。
- トークン所有者。
- コントラクト内の特権を持つアドレス。
最後に
今回は「EIP20やEIP721、EIP1155などのトークンを生成したり、破棄したりする際の実装を統一する提案をしているEIP5679」についてまとめてきました! いかがだったでしょうか?
実装については今後追記していきます。
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
採用強化中!
CryptoGamesでは一緒に働く仲間を大募集中です。
この記事で書いた自分の経験からもわかるように、裁量権を持って働くことができて一気に成長できる環境です。 「ブロックチェーンやWeb3、NFTに興味がある」、「スマートコントラクトの開発に携わりたい」など、少しでも興味を持っている方はまずはお話ししましょう!