Alert Source Discuss

EIP-: ```markdown

Authors

---
eip: 4906
title: EIP-721 元数据更新扩展
description: 向 EIP-721 添加 MetadataUpdate 事件。
author: Anders (@0xanders), Lance (@LanceSnow), Shrug <shrug@emojidao.org>, Nathan <nathan.gang@gemini.com>
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
---

## 摘要

本标准是 [EIP-721](/docs/eips/EIPS/eip-721/) 的一个扩展。它向 EIP-721 token 添加了一个 `MetadataUpdate` 事件。

## 动机

许多 [EIP-721](/docs/eips/EIPS/eip-721/) 合约会在其 token 之一的元数据发生更改时发出一个事件。虽然可以基于这些不同的事件来跟踪更改,但这对于第三方平台(如 NFT 市场)来说,需要额外的工作来为每个 NFT 集合构建个性化的解决方案。

拥有一个标准的 `MetadataUpdate` 事件将使第三方平台能够及时更新许多 NFT 的元数据。

## 规范

本文档中使用的关键词“MUST”,“MUST NOT”,“REQUIRED”,“SHALL”,“SHALL NOT”,“SHOULD”,“SHOULD NOT”,“RECOMMENDED”,“MAY”和“OPTIONAL”应按照 RFC 2119 中的描述进行解释。

**元数据更新扩展**对于 EIP-721 合约是 OPTIONAL 的。

```solidity
/// @title EIP-721 元数据更新扩展
interface IERC4906 is IERC165, IERC721 {
    /// @dev 当 token 的元数据发生更改时,会发出此事件。
    /// 这样第三方平台(如 NFT 市场)可以
    /// 及时更新 NFT 的图像和相关属性。
    event MetadataUpdate(uint256 _tokenId);

    /// @dev 当一系列 token 的元数据发生更改时,会发出此事件。
    /// 这样第三方平台(如 NFT 市场)可以
    /// 及时更新 NFT 的图像和相关属性。    
    event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}

当 token 或连续范围的 token 的 JSON 元数据发生更改时,必须发出 MetadataUpdateBatchMetadataUpdate 事件。

建议在铸造 token 时不发出 MetadataUpdate 事件。

建议在销毁 token 时不发出 MetadataUpdate 事件。

建议在 tokenURI 更改但 JSON 元数据未更改时不发出 MetadataUpdate 事件。

当使用 0x49064906 调用 supportsInterface 方法时,必须返回 true

原理

不同的 NFT 具有不同的元数据,并且元数据通常具有多个字段。bytes data 可以用来表示元数据的修改值。第三方平台难以识别各种类型的 bytes data,因此为了避免不必要的复杂性,MetadataUpdate 事件中不包含任意元数据。

捕获 MetadataUpdate 事件后,第三方可以使用 EIP-721 的 tokenURI(uint256 _tokenId) 返回的信息更新元数据。当指定一系列 token id 时,第三方可以单独查询每个 token URI。

向后兼容性

没有发现向后兼容性问题

参考实现

// 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);
    }
}

安全注意事项

如果存在元数据的链下修改,则可以添加一个触发 MetadataUpdate 的方法,但要确保该功能的权限控制是正确的。

版权

通过 CC0 放弃版权和相关权利。 ```

Citation

Please cite this document as:

, "EIP-: ```markdown," Ethereum Improvement Proposals, no. , . [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-.