Alert Source Discuss
📢 Last Call Standards Track: ERC

ERC-7631: 双重性质代币对

用于连接的可替代和不可替代代币对的规范

Authors vectorized (@vectorized), Thomas (@0xth0mas), Quit (@quitcrypto), Michael Amadi (@AmadiMichael), cygaar (@cygaar), Harrison (@pop-punk)
Created 2024-02-21
Last Call Deadline 2025-05-19
Requires EIP-20, EIP-721

摘要

一个可替代的 ERC-20 代币合约和一个不可替代的 ERC-721 代币合约可以相互连接,允许在一个合约上执行的操作反映在另一个合约上。本提案定义了如何查询两个代币合约之间的关系。它还允许账户配置在 ERC-20 到 ERC-721 同步期间是否应跳过 ERC-721 的铸造和转移。

动机

ERC-20 可替代代币和 ERC-721 不可替代代币标准为联合的、双重性质的代币对提供了足够的灵活性。ERC-20 代币的转移可以自动触发 ERC-721 代币的转移,反之亦然。这使得诸如原生 ERC-721 分数化之类的应用成为可能,其中获取 ERC-20 代币会导致自动发行 ERC-721 代币,其数量与 ERC-20 余额成比例。

双重性质代币对保持完全符合 ERC-20 和 ERC-721 代币标准。本提案旨在增强双重性质代币对的功能。

为了便于查询代币之间的关系,分别为 ERC-20 和 ERC-721 代币提出了扩展接口。这实现了各种生活质量的改进,例如允许去中心化交易所和 NFT 市场显示代币之间的关系。

此外,用户可以配置在 ERC-20 到 ERC-721 同步期间是否要跳过 ERC-721 的铸造和转移。

规范

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

概述

双重性质代币对包括一个 ERC-20 合约和一个 ERC-721 合约。

按照惯例,ERC-20 合约被指定为基础合约,ERC-721 合约被指定为镜像合约。

ERC-20 扩展接口

ERC-20 合约必须实现以下接口。

interface IERC7631Base {
    /// @dev 返回镜像 ERC-721 合约的地址。
    ///
    /// 该方法可能会 revert 或返回零地址,
    /// 以表示尚未链接镜像 ERC-721 合约。
    ///
    /// 如果返回一个非零地址,则返回的地址必须
    /// 实现 `IERC7631Mirror` 并且其 `baseERC20()` 方法必须
    /// 返回此合约的地址。
    ///
    /// 一旦返回了一个非零地址,此方法
    /// 必须不能 revert 并且返回的值不能更改。
    function mirrorERC721() external view returns (address);
}

ERC-20 合约可以实现以下接口。

interface IERC7631BaseNFTSkippable {
    /// @dev 当 `owner` 的跳过 NFT 状态
    /// 更新为 `status` 时,实现应该发出此事件。
    ///
    /// 此事件的目的是向索引器发出信号,表明
    /// 跳过 NFT 的状态已更改。
    ///
    /// 为了实现简单,
    /// 即使状态未更改,也可以发出此事件。
    event SkipNFTSet(address indexed owner, bool status);

    /// @dev 如果在 ERC-20 到 ERC-721 同步期间应跳过
    /// 对 `owner` 的 ERC-721 铸造和转移,则返回 true。
    /// 否则,返回 false。
    /// 
    /// 此方法可能会 revert
    /// (例如,合约未初始化,不支持该方法)。
    ///
    /// 如果此方法 revert:
    /// - 交互代码应将 `setSkipNFT` 功能解释为
    ///   不可用,并隐藏任何调用 `setSkipNFT` 的功能。
    /// - `owner` 的跳过 NFT 状态应解释为未定义。
    ///
    /// 一旦为给定的 `owner` 返回了 true 或 false 值,
    /// 此方法对于给定的 `owner` 必须不能 revert。
    function getSkipNFT(address owner) external view returns (bool);

    /// @dev 设置调用者的跳过 NFT 状态。
    ///
    /// 此方法可能会 revert
    /// (例如,权限不足,不支持该方法)。
    ///
    /// 建议保持此方法无需权限。
    ///
    /// 发出 {SkipNFTSet} 事件。
    function setSkipNFT(bool status) external;
}

ERC-721 扩展接口

ERC-721 合约必须实现以下接口。

interface IERC7631Mirror {
    /// @dev 返回基础 ERC-20 合约的地址。
    ///
    /// 该方法可能会 revert 或返回零地址,
    /// 以表示尚未链接基础 ERC-20 合约。
    ///
    /// 如果返回一个非零地址,则返回的地址必须
    /// 实现 `IERC7631Base` 并且其 `mirrorERC721()` 方法必须
    /// 返回此合约的地址。
    ///
    /// 一旦返回了一个非零地址,此方法
    /// 必须不能 revert 并且返回的值不能更改。
    function baseERC20() external view returns (address);
}

原理

实现检测

mirrorERC721baseERC20 方法返回非零地址表示 ERC-20 和 ERC-721 合约分别实现了所需的接口。因此,不需要 ERC-165

getSkipNFTsetSkipNFT 方法可能会 revert。由于使用 Solidity 或 Vyper 编译的合约在调用未定义的方法时会固有地 revert,因此缺少显式 getSkipNFTsetSkipNFT 定义的典型 IERC7631Base 实现仍然符合 IERC7631BaseNFTSkippable

NFT 跳过

跳过 NFT 的方法允许账户避免在每次有 ERC-20 转移时自动向其铸造 ERC-721 代币。

它们在以下情况下很有用:

  • 使用大量 ERC-20 代币加载 vesting 合约,以便 vesting 给许多用户。
  • 使用大量 ERC-20 代币加载糖果机合约,以便向客户出售 ERC-721 代币。
  • 在流动性池中移入/移出大量 ERC-20 代币。
  • 在管理帐户之间转移大量 ERC-20 代币。

在标准中包含跳过 NFT 的方法将:

  • 使应用程序能够方便地显示用户跳过 NFT 的选项。
  • 使应用程序能够转移任意数量的 ERC-20 代币,而无需与铸造多个 ERC-721 代币相关的 O(n) gas 成本,这可能会超过区块 gas 限制。

即使在 gas 成本较低的 EVM 链上,也建议使用这些方法,因为批量自动 ERC-721 转移仍然可能超过区块 gas 限制。

一个有用的模式是使 getSkipNFTowner 是智能合约时默认返回 true。

选择 getSkipNFT 返回一个布尔值是为了简单起见。如果需要更复杂的行为,开发人员可以添加自己的额外方法。

实现约定

ERC-20 合约被指定为约定上的基础合约,因为典型的实现可以方便地从 ERC-20 余额派生 ERC-721 余额。如果需要,这并不禁止人们在 ERC-721 合约中实现大部分逻辑。

本提案不涵盖代币同步逻辑。这是为了为各种实现模式和新颖的用例(例如,自动 rebase 的代币)留下灵活性。

链接机制

为了灵活性,省略了链接过程。开发人员可以使用任何所需的机制(例如,在构造函数、初始化程序中链接,或通过两个合约上的自定义仅管理员公共方法链接)。唯一的限制是一旦建立配对必须是不可变的(以简化索引逻辑)。

向后兼容性

未发现向后兼容性问题。

安全考虑

同步访问控制

同步逻辑的外部方法必须受到保护,以便只有另一个合约有权调用它们。

稀有 NFT 狙击

对于提供具有不同稀有度级别的 ERC-721 代币的双重性质集合,应以不易通过元数据抓取和 ERC-20 代币转移来进行游戏的方式显示 ERC-721 元数据。一个建议是要求 ERC-721 代币由同一帐户持有一段时间,然后再显示其元数据。

Out-of-gas 拒绝服务

转移 ERC-20 代币可以自动启动多个 ERC-721 代币的铸造、转移或销毁。这可能会导致 O(n) gas 成本,而不是典型的 ERC-20 代币转移的 O(1) gas 成本。用于选择 ERC-721 代币 ID 的逻辑也可能导致额外的 gas 成本。同步逻辑必须考虑与 ERC-721 相关的 gas 成本,以防止 out-of-gas 拒绝服务问题。

版权

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

Citation

Please cite this document as:

vectorized (@vectorized), Thomas (@0xth0mas), Quit (@quitcrypto), Michael Amadi (@AmadiMichael), cygaar (@cygaar), Harrison (@pop-punk), "ERC-7631: 双重性质代币对 [DRAFT]," Ethereum Improvement Proposals, no. 7631, February 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7631.