ERC-5380: ERC-721 权利扩展
允许 token 所有者授予其他人使用这些 token 的特定属性的能力
Authors | Gavin John (@Pandapip1), Tim Daubenschütz (@TimDaub) |
---|---|
Created | 2022-03-11 |
Requires | EIP-165, EIP-721, EIP-1046 |
摘要
本 EIP 提出了一个新的接口,允许 ERC-721 token 持有者将这些 token 的有限使用权授予其他地址。
动机
在许多情况下,token 的持有者将其某些属性授予另一个地址是有意义的。一个用例是租赁 token。如果所讨论的 token 代表链上 TCG(集换式卡牌游戏)中的一张交易卡,那么人们可能希望能够在游戏中使用该卡,而无需实际购买它。因此,所有者可以将“属性”授予给租赁者,使其能够在 TCG 中使用。但是,此属性一次只能分配给一个人,否则合约可以简单地将卡“出租”给所有人。如果 token 代表使用权,则允许使用相关媒体的属性不需要这样的限制,并且没有理由使该属性像 token 一样稀缺。
规范
本文档中的关键词“MUST”,“MUST NOT”,“REQUIRED”,“SHALL”,“SHALL NOT”,“SHOULD”,“SHOULD NOT”,“RECOMMENDED”,“MAY”和“OPTIONAL”应按照 RFC 2119 中的描述进行解释。
基础
符合要求的权利合约必须实现以下 Solidity 接口:
/// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface ERC5380Entitlement is ERC165 {
/// @notice 当用户拥有的权利数量发生变化时发出。如果 user 是零地址,则 user 是所有者
event EntitlementChanged(address indexed user, address indexed contract, uint256 indexed tokenId);
/// @notice 设置与给定 ERC-721 token 关联的 user,前提是所有者是 msg.sender。
/// @dev 如果所有者不是 msg.sender,则不应回退。
/// @param user 要授予权利的 user
/// @param contract 要授予的属性
/// @param tokenId 要授予其属性的 tokenId
function entitle(address user, address contract, uint256 tokenId) external;
/// @notice 获取可以接收此权利的最大用户数
/// @param contract 要查询的合约
/// @param tokenId 要查询的 tokenId
function maxEntitlements(address contract, uint256 tokenId) external view (uint256 max);
/// @notice 获取与给定合约和 tokenId 关联的 user。
/// @dev 默认为分配给 contract.ownerOf(tokenId) 的 maxEntitlements(contract, tokenId)
/// @param user 要查询的 user
/// @param contract 要查询的合约
/// @param tokenId 要查询的 tokenId
function entitlementOf(address user, address contract, uint256 tokenId) external view returns (uint256 amt);
}
当使用 ERC5380Entitlement
的接口 ID 调用时,supportsInterface
必须返回 true。
可枚举扩展
建议使用此可选的 Solidity 接口。
/// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface ERC5380EntitlementEnumerable is ERC5380Entitlement { // Also implicitly supports ERC-165
/// @notice 枚举分配给用户的非零权利的 token
/// @dev 如果索引超出范围或 user == address(0),则抛出
/// @param user 要查询的 user
/// @param index 一个计数器
function entitlementOfUserByIndex(address user, uint256 index) external view returns (address contract, uint256 tokenId);
}
当使用 ERC5380EntitlementEnumerable
的接口 ID 调用时,supportsInterface
必须返回 true。
元数据扩展
建议使用此可选的 Solidity 接口。
此扩展使用 ERC-1046 以实现 tokenURI
兼容性。
/// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
interface ERC5380EntitlementMetadata is ERC5380Entitlement { // Also implicitly supports ERC-165
/// @notice ERC-1046 token URI
/// @dev 请参阅 ERC-1046 和下面的元数据模式
function tokenURI() external view returns (string);
}
当使用 ERC5380EntitlementMetadata
的接口 ID 调用时,supportsInterface
必须返回 true。
互操作性元数据扩展
ERC-1046 的 InteroperabilityMetadata
通过以下 TypeScript 接口进行扩展:
/**
* ERC-5380 对 ERC-1046 的互操作性元数据的扩展。
*/
interface ERC5380InteroperabilityMetadata is InteroperabilityMetadata {
/**
* 如果这是 ERC-5380 Token 元数据,则必须为 true,否则,必须省略。
* 将此设置为 true 向钱包指示该地址应被视为 ERC-5380 权利。
**/
erc5380?: boolean | undefined;
}
tokenURI
元数据模式
已解析的 tokenURI
数据必须符合以下 TypeScript 接口:
/**
* ERC-5380 资产元数据
* 可以扩展
*/
interface ERC5380TokenMetadata {
/**
* 互操作性,用于区分不同类型的 token 及其对应的 URI。
**/
interop: ERC5380InteroperabilityMetadata;
/**
* ERC-5380 token 的名称。
*/
name?: string;
/**
* ERC-5380 token 的符号。
*/
symbol?: string;
/**
* 提供对 ERC-5380 token 的简短段落描述,没有任何标记或换行符。
*/
description?: string;
/**
* 一个或多个 URI,每个 URI 指向一个 mime 类型为 `image/*` 的资源,该资源代表此 token。
* 如果图像是位图,则其宽度应在 320 到 1080 像素之间
* 图像的宽高比应在 1.91:1 到 4:5 之间(含)。
*/
images?: string[];
/**
* 一个或多个 URI,每个 URI 指向一个 mime 类型为 `image/*` 的资源,该资源代表此 token 的图标。
* 如果图像是位图,则其宽度应在 320 到 1080 像素之间,并且其高度必须等于其宽度
* 图像的宽高比必须为 1:1,并使用透明背景
*/
icons?: string[];
}
原理
不支持 ERC-20 和 ERC-1155,因为部分所有权比布尔所有权更难跟踪。
向后兼容性
未发现向后兼容性问题。
安全注意事项
版权
在 CC0 下放弃版权及相关权利。
Citation
Please cite this document as:
Gavin John (@Pandapip1), Tim Daubenschütz (@TimDaub), "ERC-5380: ERC-721 权利扩展," Ethereum Improvement Proposals, no. 5380, March 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5380.