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 |
Table of Contents
摘要
一个可替代的 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);
}
原理
实现检测
mirrorERC721
和 baseERC20
方法返回非零地址表示 ERC-20 和 ERC-721 合约分别实现了所需的接口。因此,不需要 ERC-165。
getSkipNFT
和 setSkipNFT
方法可能会 revert。由于使用 Solidity 或 Vyper 编译的合约在调用未定义的方法时会固有地 revert,因此缺少显式 getSkipNFT
和 setSkipNFT
定义的典型 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 限制。
一个有用的模式是使 getSkipNFT
在 owner
是智能合约时默认返回 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.