Alert Source Discuss
🚧 Stagnant Standards Track: ERC

ERC-1633: 可重组代币标准 (RFT)

Authors Billy Rennekamp (@okwme), Dan Long <dan@artblx.com>, Kiryl Yermakou <kiryl@artblx.com>, Nate van der Ende <nate@artblx.com>
Created 2018-11-18
Discussion Link https://github.com/ethereum/EIPs/issues/1634
Requires EIP-20, EIP-165, EIP-721

简单总结

ERC-20 扩展,用于 ERC-721 代币的比例所有权。

摘要

此提议,即可重组代币标准,旨在扩展 ERC-20 代币标准并利用 ERC-165 标准接口检测,以表示 ERC-721 非同质化代币的共享所有权。ERC-20 代币标准经过尽可能小的修改,以允许这种新类型的代币以所有熟悉的方式和位置运行,这些方式和位置对于遵循原始 ERC-20 规范的资产来说是熟悉的。虽然此规范的许多可能变体可以实现许多不同的能力和共享所有权场景,但此提案侧重于最小的共同点,以便为各种进一步的扩展提供尽可能多的灵活性。此提案使得可以从合约级别或从外部查询验证同质化代币是否代表非同质化代币的一种共享所有权形式。包含 ERC-165 使得可以从合约级别或从外部查询验证非同质化代币是否由代表共享所有权的 ERC-20 代币所拥有。

动机

共享所有权发生在许多行业,并且有许多原因。随着越来越多的资产通过 ERC-721 非同质化代币标准进行注册、监管和/或表示,将出现更多对这些资产进行共享所有权的需求。例如,ARTBLX Inc. 正在努力促进物理、数字和概念艺术品的集体所有权协议。从此过程中创建的同质化代币将具有附加到它们所代表的非同质化代币的价值。这将有助于底层资产的价格发现、共享所有者的流动性,并作为一种新型资产,可用作贷款或稳定币等其他金融工具的抵押品。提供与此类特殊类型的同质化代币的接口是必要的,以允许第三方将其识别为一种特殊类型的同质化代币,并识别何时集体拥有非同质化代币。这在钱包希望利用底层 NFT 的元数据以在 RFT 旁边显示其他信息的情况下,或者在交易所可能希望以类似方式提供此类信息的情况下,或者在 NFT 市场可能希望将客户引导至希望购买由 RFT 拥有的 NFT 股份的相关交易所的情况下,可能是有用的。在任何适用 ERC-20 的地方,用户了解该代币是否代表共享 NFT 以及该 NFT 可能具有哪些属性将非常有用。

规范

至少,第三方需要做两件事:1) 能够将可重组代币与其他代币标准区分开来,以及 2) 确定何时集体拥有非同质化代币。可以从与非同质化代币的初始接触的角度或从与可重组代币的初始接触的角度来遇到这两种情况。

与可重组代币的初始接触

为了使第三方确认哪个非同质化代币由可重组代币拥有,需要从 RFT 合约到 NFT 合约以及相关代币 ID 的指针。这可以通过两个名为 parentToken()parentTokenId() 的公共 getter 来实现。第一个 getter 返回 address 类型的变量,并指定非同质化代币合约的合约地址。第二个 getter 返回 uint256 类型的变量,并指定非同质化代币的代币 ID。通过这些 getter,可以确定非同质化代币的身份。以下是可重组代币标准接口的示例,其中包括这些 getter 函数:

pragma solidity ^0.4.20;

/// @dev 注意:此接口的 ERC-165 标识符为 0x5755c3f2。
interface RFT /* is ERC20, ERC165 */ {

  function parentToken() external view returns(address _parentToken);
  function parentTokenId() external view returns(uint256 _parentTokenId);

}

此声明的有效性可以从另一个合约(链上)或通过与 RPC 端点交互(链下)来确认。以下是链上场景的示例:

pragma solidity ^0.4.20;

import './RFT.sol';
import './ERC721.sol';

contract ConfirmRFT {

  function confirmRFT(address _RFT) external view returns(bool) {
    address _NFT = RFT(_RFT).parentToken(); // 返回 NFT 合约的地址
    uint256 _tokenId = RFT(_RFT).parentTokenId(); // 返回 NFT 的 ID 的 ID

    return
      NFT(_NFT).supportsInterface(0x80ac58cd) && // 确认它是 ERC-721
      NFT(_NFT).ownerOf(_tokenId) == _RFT; // 确认 NFT 的所有者是 RFT 合约地址
  }

}

以下是在 javascript 中使用 web3.js 实例的链下示例:

async function confirmRFT(web3) {

  const ERC721ABI = [...] // ERC721 的 abi
  const RFTABI = [...] // RFT 的 abi
  const RFTAddress = '0x0123456789abcdef0123456789abcdef' // 已部署 RFT 的地址

  const RFTContract = new web3.eth.Contract(RFTABI, RFTAddress) // 已部署的 RFT 合约实例
  const ERC721Address = await RFTcontract.methods.parentToken().call() // 返回 NFT 合约的地址
  const ERC721TokenId = await RFTcontract.methods.parentTokenId().call() // 返回 NFT 的 ID 的 ID

  const ERC721Contract = new web3.eth.Contract(ERC721ABI, ERC721Address) // 已部署的 ERC721(如 RFT 报告)
  const isERC721 = await ERC721Contract.methods.supportsInterface('0x80ac58cd').call() // 确认它是 ERC-721
  const ownerOfAddress = await ERC721Contract.methods.ownerOf(ERC721TokenId).call() // 获取 NFT 的所有者

  return ERC721Response.toLowerCase() === RFTAddress.toLowerCase() // 确认 NFT 的所有者是 RFT 合约
}

与非同质化代币的初始接触

在检查特定非同质化代币的所有者时,重要的是能够确定所有者实际上是否为可重组代币合约。这可以通过利用 ERC-165 标准接口检测来实现。为了符合该标准,合约必须包含以下 getter 函数,该函数在传递 bytes4 参数 0x01ffc9a7 时返回 true

function supportsInterface(bytes4 interfaceID) external view returns (bool);

在建立对此接口的支持之后,它可以用于确定合约是否符合可重组代币标准。为此,在传递 bytes4 参数 0x5755c3f2 时,supportsInterface(bytes4 interfaceID) getter 函数必须返回 true,该参数是 bytes4(keccak256('parentToken()')) ^ bytes4(keccak256('parentTokenId()'))parentToken.selector ^ parentTokenId.selector 的结果。这可以通过以下代码实现:

pragma solidity ^0.4.20;

import "./ERC20.sol";

/// @dev 注意:此接口的 ERC-165 标识符为 0x5755c3f2。
interface RFT is ERC20 /*, ERC165 */ {

  function supportsInterface(bytes4 interfaceID) external view returns(bool) {
    return
      interfaceID == this.supportsInterface.selector || // ERC165
      interfaceID == this.parentToken.selector || // parentToken()
      interfaceID == this.parentTokenId.selector || // parentTokenId()
      interfaceID == this.parentToken.selector ^ this.parentTokenId.selector; // RFT
  }

  function parentToken() external view returns(address _parentToken);
  function parentTokenId() external view returns(uint256 _parentTokenId);

}

从另一个合约(链上)以及使用 RPC 端点(链下)可以完成实际检查非同质化代币所有者作为可重组代币合约的状态的流程。以下是链上场景的示例:

pragma solidity ^0.4.20;

import './RFT.sol';
import './ERC721.sol';

contract ConfirmRFT {

  function confirmRFT(address _NFT, uint256 _tokenId) external view returns(bool) {
    address _RFT = ERC721(_NFT).ownerOf(_tokenId); // 获取 NFT 的所有者

    return
      RFT(_RFT).supportsInterface(0x01ffc9a7) && // 确认它支持 ERC-165
      RFT(_RFT).supportsInterface(0x5755c3f2) // 确认它是 RFT
  }

}

以下是在 javascript 中使用 web3.js 的链下示例:

async function confirmRFT(web3) {

  const ERC721ABI = [...] // ERC721 的 abi
  const RFTABI = [...] // RFT 的 abi
  const ERC721Address = '0x0123456789abcdef0123456789abcdef' // 已部署 NFT 的地址
  const ERC721TokenId = '7' // NFT 的代币 ID

  const ERC721Contract = new web3.eth.Contract(ERC721ABI, ERC721Address) // 已部署的 ERC721
  const RFTAddress = await ERC721Contract.methods.ownerOf(ERC721TokenId).call() // NFT 的所有者地址


  const RFTContract = new web3.eth.Contract(RFTABI, RFTAddress) // 已部署的 RFT 合约实例
  const isERC165 = await RFTContract.methods.supportsInterface('0x01ffc9a7').call() // 确认它是 ERC-165
  return isERC165 && await RFTContract.methods.supportsInterface('0x5755c3f2').call() // 确认它是 RFT

}

理由

围绕此标准的设计所做的大多数决策都是希望使其尽可能灵活,以适应尽可能多的用例。这包括使该标准 100% 向后兼容 ERC-20 代币标准,并且能够与任何先前部署或将来的 ERC-721 非同质化代币交互。这允许每个项目根据其特定用例确定其自己的用于铸造、销毁和管理其可重组代币的系统。

向后兼容性

可重组代币标准与 ERC-20 代币标准 100% 向后兼容。它是对原始规范的一个小扩展,旨在进一步扩展以适应更具体的用例。保持该标准与 ERC-20 兼容非常重要,以便使该代币能够受益于围绕支持无处不在的 ERC-20 代币标准而发展的生态系统。

可重组代币标准旨在与 ERC-721 非同质化代币标准交互。它被故意保持为不可知论者,超出标准的扩展,以便允许特定项目设计其自己的代币关系,例如相对于各个可重组代币所有者对每个非同质化代币的治理、权利或权限。

实现

pragma solidity ^0.4.20;

/// @dev 注意:此接口的 ERC-165 标识符为 0x5755c3f2。
interface RFT /* is ERC20, ERC165 */ {

  function parentToken() external view returns(address _parentToken);
  function parentTokenId() external view returns(uint256 _parentTokenId);

}

安全注意事项

待定

版权

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

Citation

Please cite this document as:

Billy Rennekamp (@okwme), Dan Long <dan@artblx.com>, Kiryl Yermakou <kiryl@artblx.com>, Nate van der Ende <nate@artblx.com>, "ERC-1633: 可重组代币标准 (RFT) [DRAFT]," Ethereum Improvement Proposals, no. 1633, November 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1633.