Alert Source Discuss
Standards Track: ERC

ERC-2981: NFT 版税标准

Authors Zach Burks (@vexycats), James Morgan (@jamesmorgan), Blaine Malone (@blmalone), James Seibel (@seibelj)
Created 2020-09-15
Requires EIP-165

简述

一种检索非同质化代币 (NFT) 版税支付信息的标准化方法,以实现所有 NFT 市场和生态系统参与者对版税支付的通用支持。

摘要

该标准允许诸如支持 ERC-721ERC-1155 接口的 NFT 之类的合约,发出版税金额的信号,该版税金额应在每次出售或再次出售 NFT 时支付给 NFT 创建者或权利持有人。这适用于希望支持艺术家和其他 NFT 创建者持续获得资金的 NFT 市场。版税支付必须是自愿的,因为诸如 transferFrom() 之类的转账机制包括钱包之间的 NFT 转账,并且执行它们并不总是意味着发生了销售。市场和个人通过使用 royaltyInfo() 检索版税支付信息来实现此标准,该信息指定了对于给定的销售价格,应向哪个地址支付多少费用。支付和通知接收者的确切机制将在未来的 EIP 中定义。此 ERC 应被视为 NFT 版税支付领域进一步创新的最小、节省 gas 的构建块。

动机

目前存在许多 NFT 市场,它们具有多种独特的版税支付实现方式,这些实现方式彼此不兼容或难以被其他市场使用。就像 ERC-20 代币的早期一样,NFT 市场智能合约因生态系统而异,并且没有标准化。此 EIP 使所有市场都可以检索给定 NFT 的版税支付信息。无论 NFT 在哪个市场出售或再次出售,这都可以实现准确的版税支付。

许多最大的 NFT 市场已经实施了与其他市场不兼容的定制版税支付解决方案。此标准实施了标准化的版税信息检索,可以被任何类型的 NFT 市场接受。这个极简主义提案仅提供了一种获取版税金额和接收者的方法。实际的资金转移是市场应该执行的事情。

此标准允许支持 ERC-721ERC-1155 接口的 NFT 采用标准化方式来发出版税信息信号。更具体地说,这些合约现在可以计算版税金额以提供给合法的接收者。

版税金额始终是销售价格的百分比。如果市场选择实施此 EIP,则不会为二级销售支付任何资金。据信,NFT 市场生态系统将自愿实施此版税支付标准;目的是为艺术家/创作者提供持续的资金。NFT 买家在做出 NFT 购买决策时,会将版税支付作为一个因素进行评估。

如果没有商定的版税支付标准,NFT 生态系统将缺乏一种在所有市场上有效收取版税的手段,艺术家和其他创作者将无法获得持续的资金。这将阻碍 NFT 的增长和采用,并打击 NFT 创作者铸造新的和创新代币的积极性。

使所有 NFT 市场能够统一采用单一的版税支付标准将使整个 NFT 生态系统受益。

虽然此标准侧重于 NFT 以及与 ERC-721 和 ERC-1155 标准的兼容性,但 EIP-2981 不要求与 ERC-721 和 ERC-1155 标准兼容。任何其他合约都可以与 EIP-2981 集成以返回版税支付信息。因此,ERC-2981 是适用于许多资产类型的通用版税标准。

简而言之,这是一个总结当今 NFT 版税支付的对话示例:

艺术家:“您的平台是否支持版税支付?” 市场:“是的,我们有版税支付,但是如果您的 NFT 在另一个市场上出售,那么我们无法强制执行此支付。” 艺术家:“那么其他支持版税的市场呢,您不分享我的版税信息以使其起作用吗?” 市场:“不,我们不分享版税信息。”

规范

本文档中的关键词“必须 (MUST)”,“禁止 (MUST NOT)”,“需要 (REQUIRED)”,“应当 (SHALL)”,“不应当 (SHALL NOT)”,“应该 (SHOULD)”,“不应该 (SHOULD NOT)”,“推荐 (RECOMMENDED)”,“可以 (MAY)”和“可选 (OPTIONAL)”应按照 RFC 2119 中的描述进行解释。

符合 ERC-721 和 ERC-1155 的合约可以实现此 ERC 以进行版税支付,以提供一种指定版税支付信息的标准方法。

支持此标准的市场应该实施某种方法将版税转移给版税接收者。实际资金转移和通知的标准将在未来的 EIP 中指定。

市场必须以与传递给 royaltyInfo()_salePrice 相同的交换单位支付版税。这相当于说 _salePrice 参数和 royaltyAmount 返回值必须以相同的货币单位计价。例如,如果销售价格以 ETH 计价,则版税支付也必须以 ETH 支付,如果销售价格以 USDC 计价,则版税支付也必须以 USDC 支付。

此标准的实施者在计算版税金额时必须计算 _salePrice 的百分比。随后调用 royaltyInfo() 可以返回不同的 royaltyAmount。但是,如果实施者选择在 royaltyInfo() 调用之间执行不同的百分比计算,则有一些重要的注意事项。

royaltyInfo() 函数不知道销售和版税支付的交换单位。考虑到这一点,实施者不得返回固定/恒定的 royaltyAmount,其中他们忽略了 _salePrice。出于同样的原因,实施者不得基于将 _salePrice 与常数进行比较来确定 royaltyAmount。在这两种情况下,royaltyInfo() 函数都对交换单位进行了假设,必须避免这种情况。

由于先前所述的原因,使用的百分比值必须独立于销售价格(即,如果百分比值为 10%,则无论 _salePrice 为 10、10000 还是 1234567890,必须应用 10%)。如果版税计算导致余数,则实施者可以向上或向下舍入到最接近的整数。例如,如果版税为 10% 且 _salePrice 为 999,则实施者可以返回 99 或 100 作为 royaltyAmount,两者均有效。

实施者可以选择基于其他可预测的变量来更改百分比值,而这些变量不会对交换单位进行假设。例如,百分比值可能会随着时间的推移线性下降。像这样的方法不应基于像 block.timestamp 这样不可预测的变量,而是基于其他更可预测的状态变化。另一种更合理的方法可以使用 NFT 的转账次数来决定使用哪个百分比值来计算 royaltyAmount。其思想是,在每次 NFT 转账后,百分比值可能会降低。另一个示例可能是为每个唯一的 _tokenId 使用不同的百分比值。

支持此标准的市场,如果返回的 royaltyAmount0不应该发送零值交易。这将浪费 gas,并且在本 EIP 中没有任何用处。

无论销售发生在何处或以何种货币进行,包括链上销售、场外交易 (OTC) 销售和场外销售(例如在拍卖行),支持此标准的市场必须支付版税。由于版税支付是自愿的,因此尊重此 EIP 的实体必须支付,无论销售发生在何处 - 在区块链之外进行的销售仍然是销售。支付和通知接收者的确切机制将在未来的 EIP 中定义。

此标准的实施者必须具有以下所有功能:

pragma solidity ^0.6.0;
import "./IERC165.sol";

///
/// @dev NFT 版税标准接口
///
interface IERC2981 is IERC165 {
    /// ERC165 字节添加到接口数组 - 在实现此标准的父合约中设置
    ///
    /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
    /// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;
    /// _registerInterface(_INTERFACE_ID_ERC2981);

    /// @notice 调用销售价格以确定应支付多少版税以及支付给谁。
    //          is owed and to whom.
    /// @param _tokenId - 查询版税信息的 NFT 资产
    /// @param _salePrice - 由 _tokenId 指定的 NFT 资产的销售价格
    /// @return receiver - 应该向其发送版税的地址
    /// @return royaltyAmount - _salePrice 的版税支付金额
    function royaltyInfo(
        uint256 _tokenId,
        uint256 _salePrice
    ) external view returns (
        address receiver,
        uint256 royaltyAmount
    );
}

interface IERC165 {
    /// @notice 查询合约是否实现了接口
    /// @param interfaceID 接口标识符,如 ERC-165 中指定
    /// @dev 接口标识在 ERC-165 中指定。 此函数
    ///  使用少于 30,000 gas。
    /// @return 如果合约实现了 `interfaceID` 且
    ///  `interfaceID` 不是 0xffffffff,则为 `true`,否则为 `false`
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

例子

在部署期间在 ERC-721 上使用此标准的示例:

部署 ERC-721 并发出对 ERC-2981 的支持信号

constructor (string memory name, string memory symbol, string memory baseURI) {
        _name = name;
        _symbol = symbol;
        _setBaseURI(baseURI);
        // 注册受支持的接口以通过 ERC165 符合 ERC721
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
        // 版税接口
        _registerInterface(_INTERFACE_ID_ERC2981);
    }

检查在您的市场上出售的 NFT 是否实现了版税

bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a;

function checkRoyalties(address _contract) internal returns (bool) {
    (bool success) = IERC165(_contract).supportsInterface(_INTERFACE_ID_ERC2981);
    return success;
 }

原理

可选的版税支付

不可能知道哪些 NFT 转账是销售的结果,哪些只是钱包移动或合并其 NFT。因此,我们无法强制每个转账函数(例如 ERC-721 中的 transferFrom())都涉及版税支付,因为并非每次转账都是需要此类支付的销售。我们相信 NFT 市场生态系统将自愿实施此版税支付标准,以向艺术家/创作者提供持续的资金。NFT 买家在做出 NFT 购买决策时,会将版税支付作为一个因素进行评估。

向单个地址进行简单的版税支付

此 EIP 未指定向版税接收者付款的方式。此外,不可能完全了解并有效地实施所有可能的版税支付逻辑类型。话虽如此,版税支付接收者有责任在他们自己的接收合约或链下流程中实施所有额外的复杂性和逻辑,以进行费用分摊、多个接收者、税收、会计等。尝试将其作为此标准的一部分来执行,会大大增加实施的复杂性,增加 gas 成本,并且不可能涵盖每种潜在的用例。此 ERC 应被视为 NFT 版税支付领域进一步创新的最小、节省 gas 的构建块。未来的 EIP 可以指定有关付款转移和通知的更多详细信息。

版税支付百分比计算

此 EIP 强制执行基于百分比的版税模式。最常见的百分比计算情况可能是 royaltyAmount 始终使用固定百分比从 _salePrice 计算得出,即如果版税为 10%,则无论 _salePrice 为 10、10000 还是 1234567890,都必须应用 10% 的版税。

如前所述,实施者可以使用这种基于百分比的计算进行创新,但有一些重要的注意事项需要考虑。主要是,确保 royaltyInfo() 函数不知道交换单位,并且在百分比计算中避免使用不可预测的变量。为了跟进之前的 block.timestamp 示例,如果发生以下事件,则可以突出显示一些细微差别:

  1. 市场出售 NFT。
  2. 市场延迟 X 天,然后调用 royaltyInfo() 并发送付款。
  3. 市场收到 Y 作为 royaltyAmount,这与 X 天前计算出的 royaltyAmount 金额大相径庭(如果未发生延迟)。
  4. 版税接收者对市场的延迟不满意,因此提出了争议。

与其返回一个百分比并让市场根据销售价格计算版税金额,不如返回一个 royaltyAmount 值,这样就不会与市场就给定销售价格应付多少费用发生争议。版税支付者必须支付 royaltyInfo() 规定的 royaltyAmount

跨所有市场(包括链上和链下)的无单位版税支付

此 EIP 未指定用于销售和版税支付的货币或代币。无论销售中使用何种货币或代币,都必须支付相同的基于百分比的版税,并以相同的货币或代币支付。这适用于任何地点的销售,包括链上销售、场外交易 (OTC) 销售,以及使用法定货币的场外销售,例如在拍卖行。由于版税支付是自愿的,因此尊重此 EIP 的实体必须支付,无论销售发生在何处 - 在区块链之外进行的销售仍然是销售。支付和通知接收者的确切机制将在未来的 EIP 中定义。

通用版税支付

虽然专门针对 NFT 设计,但此标准并不要求实施 EIP-2981 的合约与 ERC-721 或 ERC-1155 标准兼容。任何其他合约都可以使用此接口返回版税支付信息,前提是它能够在接口的约束范围内唯一地标识资产。因此,ERC-2981 是适用于许多其他资产类型的通用版税标准。

向后兼容性

此标准与当前的 ERC-721 和 ERC-1155 标准兼容。

安全考虑

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

版权

CC0 下放弃版权和相关权利。

Citation

Please cite this document as:

Zach Burks (@vexycats), James Morgan (@jamesmorgan), Blaine Malone (@blmalone), James Seibel (@seibelj), "ERC-2981: NFT 版税标准," Ethereum Improvement Proposals, no. 2981, September 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2981.