主权桥接NFT

该标准旨在使NFT的创建者和持有者能够突破单个域的限制,拥抱以太坊生态系统中rollup技术的创新和实验。该标准提出了xERC-721和xERC-721Lockbox接口,允许NFT在不同的rollup链之间安全、无摩擦地迁移,同时保持NFT社区自身的主权,并扩展了ERC721Enumerable接口,以便开发者能够查询在单个域上铸造的NFT数量。

摘要

以下标准将 NFT 的创建者和持有者从单一域的限制中解放出来 —— 扩大了他们拥抱以太坊生态系统中 rollup 之间大量创新和实验的机会。

动机

ERC-721 定义的非同质化代币已成为自 2017 年最初的 EIP 提案以来最重要和使用最广泛的数字资产标准之一。 然而,在该标准最初引入时,以太坊生态系统的路线图不包括通过 rollup 进行扩展。 此后,我们看到以太坊生态系统中的大部分活动都迁移到了 rollup。 这使得现有和新的 NFT 集合被困在一个单一的域中。

随着跨不同 rollup 构建的 NFT 新应用程序的出现,NFT 能够以最小的摩擦安全地跨 rollup 域迁移变得越来越重要。 此外,至关重要的是,当这些 NFT 升级为跨多个域移动时,我们不会引入不必要的风险或依赖任何特权第三方,例如特定的互操作性网络。 主权应掌握在 NFT 社区自身手中。

之前已经有关于解决这个问题的讨论和提案:

  • 在 2021 年 9 月,Vitalik 在以太坊研究论坛上发布了“跨 rollup NFT 包装器和迁移想法”。提出了“包装器 NFT”的概念,该概念使 NFT 能够扩展到 rollup,并利用“包装器管理器合约”。在许多方面,你可以看到下面提出的代币接口在方向上与他的提案一致,但赋予传输层更大的自由,以最大限度地减少他讨论的接收链概念所导致的复杂性。
  • 9 月晚些时候,Pavel Sinelnikov 也在以太坊研究论坛上创建了一个名为“跨层桥接 NFT”的帖子,迭代了 Vitalik 最初的提案。以下提案与 2021 年提出的这些概念之间的核心区别在于,我们在 ZK rollup 以及快速最终性机制方面都取得了重大改进,这使我们能够定义更抽象的接口,而不会过度适应乐观 rollup 产生的 7 天提款延迟。
  • 最近也是最重要的,在 2023 年,Connext 团队提出了 xERC20,它强烈地启发了下面的提案。xERC20 确立了“主权桥接代币”的概念。我们非常同意该 EIP 提案中做出的设计决策,以至于我们直接遵守了该 EIP 中使用的桥接授权接口。

规范

本文档中的关键词“必须”("MUST")和“应该”("SHOULD")应按照 RFC 2119 和 RFC RFC 8174 中的描述进行解释。

代币接口

所有 xERC-721 必须 实现以下接口:

interface IXERC-721 {
    /**
     * @notice 当设置 lockbox 时发出
     *
     * @param _lockbox lockbox 的地址
     */
    event LockboxSet(address _lockbox);

    /**
     * @notice 当设置限制时发出
     *
     * @param _mintingLimit 我们设置为桥的更新后的铸币限制
     * @param _burningLimit 我们设置为桥的更新后的燃烧限制
     * @param _bridge 我们为其设置限制的桥的地址
     */
    event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge);

    /**
     * @notice 当限制过低的用户尝试调用 mint/burn 时 revert
     */
    error IXERC-721_NotHighEnoughLimits();

    struct Bridge {
        BridgeParameters minterParams;
        BridgeParameters burnerParams;
    }

    struct BridgeParameters {
        uint256 timestamp;
        uint256 ratePerSecond;
        uint256 maxLimit;
        uint256 currentLimit;
    }

    /**
     * @notice 设置 lockbox 地址
     *
     * @param _lockbox lockbox 的地址(如果没有 lockbox 则为 0x0)
     */
    function setLockbox(address _lockbox) external;

    /**
     * @notice 更新任何桥的限制
     * @dev 只能由所有者调用
     * @param _mintingLimit 我们设置为桥的更新后的铸币限制
     * @param _burningLimit 我们设置为桥的更新后的燃烧限制
     * @param _bridge 我们为其设置限制的桥的地址
     */
    function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external;

    /**
     * @notice 返回桥的最大限制
     *
     * @param _bridge 我们正在查看其限制的桥
     * @return _limit 桥的限制
     */
    function mintingMaxLimitOf(address _bridge) external view returns (uint256 _limit);

    /**
     * @notice 返回桥的最大限制
     *
     * @param _bridge 我们正在查看其限制的桥
     * @return _limit 桥的限制
     */
    function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit);

    /**
     * @notice 返回桥的当前限制
     *
     * @param _bridge 我们正在查看其限制的桥
     * @return _limit 桥的限制
     */
    function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit);

    /**
     * @notice 返回桥的当前限制
     *
     * @param _bridge 我们正在查看其限制的桥
     * @return _limit 桥的限制
     */
    function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit);

    /**
     * @notice 向用户铸造一个非同质化代币
     * @dev 只能由桥调用
     * @param _user 接收铸造的非同质化代币的用户的地址
     * @param _tokenId 要铸造的特定非同质化代币
     * @param _tokenURI 与非同质化代币对应的元数据
     */
    function mint(address _user, uint256 _tokenId, string _tokenURI) external;

    /**
     * @notice 向用户批量铸造非同质化代币
     * @dev 只能由桥调用
     * @param _user 需要铸造代币的用户的地址
     * @param _tokenIdList 要铸造给用户的特定代币的列表
     * @param _tokenURIList 每个单独代币的元数据列表
     */
    function mintBatch(address _user, uint256[] calldata _tokenIdList, string[] calldata _tokenURIList) external;

    /**
     * @notice 为用户销毁一个非同质化代币
     * @dev 只能由桥调用
     * @param _user 需要销毁非同质化代币的用户的地址
     * @param _tokenId 要销毁的非同质化代币
     */
    function burn(address _user, uint256 _tokenId) external;

    /**
     * @notice 为用户销毁非同质化代币
     * @dev 只能由桥调用
     * @param _user 需要销毁代币的用户的地址
     * @param _tokenIdList 要销毁的非同质化代币的列表
     */
    function burnBatch(address _user, uint256[] calldata _tokenIdList) external;
}

ERC-721 没有为开发者提供批量传输功能 —— 这一直是开发者的痛点,导致了像 ERC-1155 这样的新标准的引入。当跨多个 rollup 进行编程时,这个问题更加严重,因为它引入了异步性和补偿互操作性网络以验证和中继交易的成本。因此,我们决定使用额外的 mintBatchburnBatch 函数接口来扩展合约。

在 mint 函数中,传入的 tokenURI 数据 应该 符合 RFC 3986 中定义的标准,或者符合 EIP-721 中定义的“ERC721 元数据 JSON 模式”,如下所示:

{
  "title": "Asset Metadata",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "标识此 NFT 代表的资产"
    },
    "description": {
      "type": "string",
      "description": "描述此 NFT 代表的资产"
    },
    "image": {
      "type": "string",
      "description": "指向具有 mime 类型 image/* 的资源的 URI,表示此 NFT 代表的资产。 考虑使任何图像的宽度在 320 到 1080 像素之间,宽高比在 1.91:1 到 4:5 之间(含)。"
    }
  }
}

Lockbox 接口

interface IXERC-721Lockbox {
  /**
   * @notice 当非同质化代币被存入 lockbox 时发出
   */
  event Deposit(address _sender, uint256[] _tokenIdList);

  /**
   * @notice 当非同质化代币从 lockbox 中提取时发出
   */
  event Withdraw(address _sender, uint256[] _tokenIdList);

  /**
   * @notice 当用户尝试提取并且调用失败时 revert
   */
  error IXERC-721Lockbox_WithdrawFailed();

  /**
   * @notice 将非同质化代币存入 lockbox
   *
   * @param _tokenIdList 要存入的非同质化代币
   */
  function deposit(uint256[] calldata _tokenIdList) external;

  /**
   * @notice 从 lockbox 中提取非同质化代币
   *
   * @param _tokenIdList 要提取的非同质化代币
   */
  function withdraw(uint256[] calldata _tokenIdList) external;
}

可枚举扩展

此外,我们提出了对现有 ERC721Enumerable 接口的扩展,以使开发者能够查询在单个域上铸造的非同质化代币的数量。 我们向具有可变总供应量的非同质化代币集合的开发者指出,重要的是要传播 totalSupply 变量的状态更新,以包括任何时候有更新的域。 这同样适用于 EIP-7281。

interface XERC721Enumerable /* is ERC721Enumerable */ {
  /**
   * @notice 返回此域上的非同质化代币的数量
   */
  function localSupply() external view returns (uin256);
}

理由

标准化主权

这个提出的标准受到了 Connext 团队在 EIP-7281 (xERC20) 中提出的先前工作的强烈影响。 所有桥接授权接口与 EIP-7281 保持相同,以便为资产发行人构建的用于管理桥接的开发者工具可以同时用于多域 ERC-20 和 ERC-721。

这个 EIP 与 EIP-7281 结合使用,仅仅是以太坊生态系统开放标准套件的开始,因为我们正在拥抱一个真正的以 rollup 为中心的生态系统。 通过利用标准化的接口,我们不仅可以建立更严格测试的开发者工具,这些工具可以用于所有数字资产,而且我们还为引入其他标准打开了机会,这些标准可以进一步改进数字资产发行人可用的功能,而无需定制集成。

当资产发行人采用这个标准时,他们 应该 参考 EIP-7281 中关于速率限制的部分,以及在初始化任何速率限制功能时对限制的边缘情况考虑。

数据结构差异

话虽如此,用于 ERC-721 的数据结构从根本上不同于 ERC-20 的数据结构,因此我们需要在一定程度上修改接口。 必要的修改存在于 mint 和 burn 函数中。

批量 Mint 和 Burn

我们还扩展了接口,以包括 mintBatch 和 mintBurn 函数。 我们起草这个 EIP 的目标是尽可能地符合现有标准,同时促进跨域传输的最安全机制。 虽然 ERC-721 不包含可比较的 transferBatch 函数,但我们相信扩展接口以包括跨域批量传输非常重要,因为在使用外部互操作性网络来促进这些传输时,引入了固有的成本和复杂性。 为了创造最佳的开发者体验,这为智能合约开发者打开了以最佳方式实施传输的机会,使他们能够将跨域传输的风险隔离到单个事务中,该事务的失败情况可以以比这些跨域函数调用数组更简单的方式处理。

向后兼容性

这个 EIP 的设计特别之处在于,我们可以授权新的 NFT 集合以最佳的方式启动,以便为以太坊 rollup 生态系统的持续扩展做好准备,同时不排除已经启动的集合。 现有的 NFT 集合可以通过部署一个新的门户合约轻松地采用这个标准,这使它们可以在 rollup 生态系统的其余部分中访问,从而实现一个简单且最小的机制。

此外,已经存在大型的市场,可以促进用户之间 NFT 的交换,并且 xERC-721 必须 符合这些交易所用来促进与已经围绕 NFT 构建的其余工具无缝集成的接口。 这同样适用于 NFTFi 协议。

安全考虑

特别注意最大限度地减少授权 NFT 社区使用此功能所需的代码 —— 我们坚信,最小的标准是授权人们以促进可组合性,同时最大限度地降低任何安全风险的方式利用新机会的最佳方式。

具体来说,团队在将集合升级到 xERC-721 时 应该 考虑的最明显的安全考虑因素是他们在选择促进单个 NFT 传输的互操作性网络时所做的选择。 我们敦促高价值 xERC-721 的社区甚至考虑使用额外的安全措施,例如利用来自多个桥接提供商的 m of n 多签名确认。

参考实现

待办事项:在收到审查和反馈后

版权

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

  • 原文链接: github.com/omni-network/...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
omni-network
omni-network
江湖只有他的大名,没有他的介绍。