--- eip: 4906 title: EIP-721 Metadata Update Extension description: Add a MetadataUpdate event to EIP-721. author: Anders (@0xanders), Lance (@LanceSnow), Shrug , Nathan discussions-to: https://ethereum-magicians.org/t/eip4906-erc-721-erc-1155-metadata-update-extension/8588 status: Final type: Standards Track category: ERC created: 2022-03-13 requires: 165, 721 --- ## Abstract This standard is an extension of [EIP-721](./eip-721.md). It adds a `MetadataUpdate` event to EIP-721 tokens. ## Motivation Many [EIP-721](./eip-721.md) contracts emit an event when one of its tokens' metadata are changed. While tracking changes based on these different events is possible, it is an extra effort for third-party platforms, such as an NFT marketplace, to build individualized solutions for each NFT collection. Having a standard `MetadataUpdate` event will make it easy for third-party platforms to timely update the metadata of many NFTs. ## Specification The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119. The **metadata update extension** is OPTIONAL for EIP-721 contracts. ```solidity /// @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); } ``` The `MetadataUpdate` or `BatchMetadataUpdate` event MUST be emitted when the JSON metadata of a token, or a consecutive range of tokens, is changed. Not emitting `MetadataUpdate` event is RECOMMENDED when a token is minted. Not emitting `MetadataUpdate` event is RECOMMENDED when a token is burned. Not emitting `MetadataUpdate` event is RECOMMENDED when the tokenURI changes but the JSON metadata does not. The `supportsInterface` method MUST return `true` when called with `0x49064906`. ## Rationale Different NFTs have different metadata, and metadata generally has multiple fields. `bytes data` could be used to represents the modified value of metadata. It is difficult for third-party platforms to identify various types of `bytes data`, so as to avoid unnecessary complexity, arbitrary metadata is not included in the `MetadataUpdate` event. After capturing the `MetadataUpdate` event, a third party can update the metadata with information returned from the `tokenURI(uint256 _tokenId)` of EIP-721. When a range of token ids is specified, the third party can query each token URI individually. ## Backwards Compatibility No backwards compatibility issues were found ## Reference Implementation ```solidity // SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "./IERC4906.sol"; contract ERC4906 is ERC721, IERC4906 { constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) { } /// @dev See {IERC165-supportsInterface}. function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId); } } ``` ## Security Considerations If there is an off-chain modification of metadata, a method that triggers `MetadataUpdate` can be added, but ensure that the function's permission controls are correct. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).