[ERC4906] NFTのメタデータの変更をログに残すインターフェースの仕組みを理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、**ERC721**規格のNFTのメタデータが更新された時に、その変更を通知するイベントを発行する提案である**ERC4906**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-4906

# 概要

この標準は、**EIP721**の拡張版です。
**EIP721**トークンに`MetadataUpdate`イベントを追加します。

:::note info
**ERC721**については以下を参考にしてください。
:::

https://chaldene.net/erc721

# 動機
多くの**EIP721**コントラクトは、トークンのメタデータが変更されるとイベントを発行します。
通常、**EIP721**トークンのメタデータが変更されると、それぞれのNFTコレクションごとに異なるイベントが発生します。
これにより、NFTマーケットプレイスなどのサードパーティプラットフォームが、各コレクションごとに異なる方法でメタデータ変更を追跡しなければならない状況が生じます。
これは手間と時間がかかり、効率的ではありません。

しかし、新しい標準である`MetadataUpdate`イベントを採用することで、トークンのメタデータが変更された際に統一されたイベントが発生します。
つまり、どのNFTコレクションでも同じ方法でメタデータの変更を追跡できるようになります。
これにより、サードパーティプラットフォームは個々のNFTコレクションごとにカスタムソリューションを作る必要がなくなります。
代わりに、統一されたイベントをサポートするだけで、多くのNFTのメタデータを効率的に管理し、タイムリーに更新することが容易になります。

# 仕様

**MetadataUpdate**拡張は、**EIP721**コントラクトではオプションとなる機能です。

```javascript
/// @title EIP-721 Metadata Update Extension
interface IERC4906 is IERC165, IERC721 {
    /// @dev This event emits when the metadata of a token is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFT.
    event MetadataUpdate(uint256 _tokenId);

    /// @dev This event emits when the metadata of a range of tokens is changed.
    /// So that the third-party platforms such as NFT market could
    /// timely update the images and related attributes of the NFTs.    
    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}
```

トークンのJSONメタデータが変更されると、`MetadataUpdate`イベントまたは`BatchMetadataUpdate`イベントを発行します。

トークンが新たに発行（`mint`）される場合、`MetadataUpdate`イベントを発行しないことが推奨されています。

また、トークンが破棄（`burn`）される場合も、`MetadataUpdate`イベントを発行しないことが推奨されています。

同じく`tokenURI`（トークンのURI）が変更されるがJSONメタデータ自体は変更されない場合も、`MetadataUpdate`イベントを発行しないことが推奨されています。

さらに、`supportsInterface`メソッドは、`0x49064906`を引数として呼び出された場合に`true`を返す必要があります。

これにより、トークンのメタデータが変更される状況に応じて、適切なイベントを発行することが求められています。
また、特定のインターフェースをサポートするかどうかも判定できるようになっています。

# 補足

NFT（ノンファンジブルトークン）ごとに異なるメタデータがあり、メタデータには複数のフィールドが含まれています。
変更されたメタデータの値を表すために、バイトデータが使用されることがあります。
しかし、さまざまな種類のバイトデータをサードパーティプラットフォームが正しく識別することは難しいため、複雑さを避けるために、`MetadataUpdate`イベントには任意のメタデータが含まれていないことがあります。

`MetadataUpdate`イベントを受け取った後、サードパーティは**EIP721**の`tokenURI(uint256 _tokenId)`から返された情報を使用して、メタデータを更新できます。
複数のトークンIDが指定された場合、サードパーティは各トークンのURIを個別にクエリできます。

これにより、異なるNFTごとに変更されたメタデータの値を効果的に処理し、必要な情報を元にメタデータを更新する手段が提供されます。

# 後方互換性

特に問題なし。

# 参考実装

以下に実装コードを置いています。

https://github.com/cardene777/base-code/tree/develop/contract/contracts/ERC4906

引用: https://eips.ethereum.org/EIPS/eip-4906

# セキュリティ考慮事項

セキュリティに関する考慮事項として、オフチェーンでメタデータが変更される場合、`MetadataUpdate`をトリガーするメソッドを追加することができますが、その際に関数の権限制御に脆弱性がないか確認する必要があります。

:::note info
不正なアクセスや操作を防ぐために、誰がこのメソッドを呼び出すことができるかを適切に管理する必要があります。
:::

# 引用

Anders (@0xanders), Lance (@LanceSnow), Shrug <shrug@emojidao.org>, Nathan <nathan.gang@gemini.com>, "ERC-4906: EIP-721 Metadata Update Extension," Ethereum Improvement Proposals, no. 4906, March 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4906.

# 最後に

今回は「**ERC721**規格のNFTのメタデータが更新された時に、その変更を通知するイベントを発行する提案である**ERC4906**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)