Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-3569: 密封 NFT 元数据标准

Authors Sean Papanikolas (@pizzarob)
Created 2021-05-07
Discussion Link https://ethereum-magicians.org/t/eip-3569-sealed-nft-metadata-standard/7130

简述

密封 NFT 元数据扩展提供了一种以经济高效的方式永久保存 NFT 元数据的方法。

概要

此标准完成了三件事:它为潜在的收藏家提供了一种验证 NFT 元数据不会更改的方法, 允许创建者一次性永久保存多个代币的元数据, 并允许从一个文件中读取和缓存许多 NFT 的元数据。 创建者可以为一系列一个或多个连续的 NFT 调用 seal 函数。 其中包含一个指向像 IPFS 这样的去中心化存储服务的 URI 作为参数,该 URI 将存储在智能合约中。 该 URI 将返回一个 JSON 对象,其中键是代币 ID,值是字符串(指向存储在去中心化文件系统上的元数据文件的 URI)或每个代币 ID 的原始元数据 JSON。 然后,代币 ID 将在智能合约中标记为已密封,并且不能再次密封。 可以在 NFT 创建之后或 NFT 创建期间调用 seal 函数。

动机

在最初的 ERC-721 标准中,元数据扩展指定了一个 tokenURI 函数,该函数返回单个代币 ID 的 URI。 这可以托管在 IPFS 上,也可以托管在中心化服务器上。 无法保证 NFT 元数据不会更改。 ERC-1155 元数据扩展也是如此。 除此之外 - 如果你想更新许多 NFT 的元数据,你需要以 O(n) 的时间复杂度来完成,我们知道这在规模上是不可行的。 通过允许去中心化的 URI 指向一个包含许多 NFT ID 的 JSON 对象,我们可以通过一次性提供许多代币的元数据来解决这个问题,而不是一次只提供一个代币的元数据。 我们还可以提供一些方法,让我们可以透明地了解 NFT 是否已被显式“密封”,并且元数据是否托管在去中心化的存储空间中。

智能合约层无法与存储层通信,因此我们需要一种解决方案,以便以太坊上的潜在 NFT 收藏家能够验证他们的 NFT 不会被“恶意拉盘”。 该标准为此提供了一个解决方案。 通过允许创建者在创建期间或之后密封他们的 NFT,他们在创建 NFT 时获得了充分的灵活性。 去中心化的存储意味着永久性 - 在快速发展的数字营销活动或艺术项目世界中,错误可能会发生。 因此,对于创建者来说,在创建项目时具有灵活性非常重要。 因此,该标准允许创建者在他们选择的时间选择加入。 错误确实会发生,元数据应该足够灵活,以便创建者可以修复错误或创建动态 NFT(请参阅 Beeple 的 CROSSROAD NFT)。 如果到了需要使 NFT 元数据永久保存的时候,创建者可以调用 seal 方法。 所有者、潜在所有者或平台可以验证 NFT 是否已密封,并可以检查返回的 URI。 如果 sealedURI 的返回值不是托管在去中心化存储平台上的,或者 isSealed 方法对于给定的 NFT ID 没有返回 true,那么可以说人们不能相信这些 NFT 在未来不会发生变化,然后可以决定是否要继续收藏给定的 NFT。

技术规格

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

interface SealedMetadata {
  /**
    @notice 此函数用于为给定的代币范围设置密封 URI。
    @dev
      - 如果密封 URI 是为单个代币设置的,那么 fromTokenId 和 toTokenId
      的值必须相同。

      - 如果指定的代币范围内的任何代币已被密封,则此函数必须抛出。

      - 此函数可以在 NFT 创建时或在 NFT 创建后调用。

      - 建议此函数只能由智能合约的创建者或 NFT 的创建者执行,
        但这仅是可选的,应根据用例实现。

      - 此函数必须发出 Sealed 事件

      - URI 参数应该指向托管在像 IPFS 这样的去中心化文件系统中的 JSON 文件

    @param fromTokenId 连续代币范围内的第一个代币
    @param toTokenId 连续代币范围内的最后一个代币
    @param uri 指向托管在去中心化文件系统上的 JSON 文件的 URI。
  */
  function seal(uint256 fromTokenId, uint256 toTokenId, string memory uri) external;

  /**
    @notice 此函数返回给定代币 ID 的密封元数据的 URI
    @dev
      - 如果代币 ID 不存在或未密封,则此函数必须抛出

    @param tokenId 要检索密封 URI 的代币 ID

    @return 可以在其中找到给定代币 ID 的元数据的密封 URI
  */
  function sealedURI(uint256 tokenId) external view returns (string);

  /**
    @notice 此函数返回一个布尔值,指示代币 ID 是否已密封
    @dev 如果代币 ID 不存在,则此函数应抛出

    @param tokenId 将检查是否密封的代币 ID

    @return 指示代币 ID 是否已密封的布尔值
  */
  function isSealed(uint256 tokenId) external view returns (bool)

  /// @dev 当密封一系列代币时,会发出此事件
  event Sealed(uint256 indexed fromTokenId, uint256 indexed toTokenId, string memory uri);

}

密封元数据 JSON 格式

密封元数据 JSON 文件可能包含许多不同代币的元数据。 JSON 对象的顶级键必须是代币 ID。


type ERC721Metadata = {
  name?: string;
  image?: string;
  description?: string;
}

type SealedMetaDataJson = {
  [tokenId: string]: string | ERC721Metadata;
}

const sealedMetadata: SealedMetaDataJson = {
    '1': {
        name: 'Metadata for token with ID 1' // 具有 ID 1 的代币的元数据
    },
    '2': {
        name: 'Metadata for token with ID 2' // 具有 ID 2 的代币的元数据
    },
    // Example pointing to another file  // 指向另一个文件的示例
    '3': 'ipfs://SOME_HASH_ON_IPFS'
};

理由

关于规则没有明确要求密封 URI 托管在去中心化文件存储上的理由

为了使此标准在未来保持适用性,智能合约中没有验证可以验证密封 URI 是否托管在 IPFS 或其他去中心化文件存储系统上。 该标准允许潜在的收藏家和平台在客户端上验证 URI。

在一个 JSON 文件中包含许多 NFT 元数据对象或 URI 的理由

通过在一个 JSON 文件中包含许多 NFT 的元数据,我们可以消除设置多个 NFT 的元数据所需的许多交易。 鉴于此文件不应更改,NFT 平台或浏览器可以缓存文件中的元数据。

发出 Sealed 事件的理由

平台和浏览器可以使用 Sealed 事件来自动缓存元数据或更新有关指定 NFT 的信息。

允许 URI 作为 JSON 文件中的值的理由

如果代币的元数据非常大,或者有很多代币,你可以通过引用另一个 URI 而不是将元数据 JSON 存储在顶级元数据文件中来节省文件空间。

向后兼容性

与现有标准没有向后兼容性。 这是一个可以添加到现有 NFT 标准的扩展。

安全考虑

没有与此标准的实施直接相关的安全考虑因素。

版权

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

Citation

Please cite this document as:

Sean Papanikolas (@pizzarob), "ERC-3569: 密封 NFT 元数据标准 [DRAFT]," Ethereum Improvement Proposals, no. 3569, May 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3569.