ERC-6806: ERC-721 持有时间跟踪
向 ERC-721 代币添加持有时间信息
Authors | Saitama (@saitama2009), Combo <combo@1combo.io>, Luigi <luigi@1combo.io> |
---|---|
Created | 2023-03-30 |
Discussion Link | https://ethereum-magicians.org/t/draft-eip-erc721-holding-time-tracking/13605 |
Requires | EIP-721 |
摘要
本标准是 ERC-721 的扩展。它添加了一个接口,用于跟踪和描述一个账户持有 Non-Fungible Token (NFT) 的时间。
动机
在某些用例中,了解 NFT 被一个账户持有的时长非常有价值。此信息可用于奖励长期持有者,确定对独家内容的访问权限,甚至可以基于持有时间来实现特定的业务逻辑。然而,当前的 ERC-721 标准没有内置的机制来跟踪 NFT 持有时间。
本提案旨在通过扩展 ERC-721 标准,使其包含持有时间跟踪功能,从而解决这些限制。
规范
本文档中的关键词“必须”,“不得”,“必需”,“应该”,“不应该”,“推荐”,“可以”和“可选”应按照 RFC 2119 中的描述进行解释。
接口
以下接口扩展了现有的 ERC-721 标准:
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0
interface IERC6806 {
function getHoldingInfo(
uint256 tokenId
) external view returns (address holder, uint256 holdingTime);
}
函数
getHoldingInfo
function getHoldingInfo(uint256 tokenId) external view returns (address holder, uint256 holdingTime);
此函数返回指定 NFT 的当前持有者以及该 NFT 被当前账户持有的时长(以秒为单位)。
tokenId
: NFT 的唯一标识符。- 返回值: 一个元组,包含当前持有者的地址和持有时间(以秒为单位)。
原理
将 getHoldingInfo
函数添加到 ERC-721 标准的扩展允许开发人员实现需要持有时间信息的基于 NFT 的应用程序。此扩展保持与现有 ERC-721 实现的兼容性,同时为新的用例提供额外的功能。
getHoldingInfo
函数提供了一种直接的方法来检索 NFT 的持有时间和持有者地址。通过使用秒作为持有持续时间的单位,它可以确保精度并与智能合约中其他基于时间的函数兼容。
getHoldingInfo
同时返回 holder
和 holdingTime
,以便出于计算持有时间的目的,可以忽略某些代币所有者(由实现决定)。例如,合约可以获得 NFT 的所有权作为贷款的抵押品。这样的贷款合约可以被忽略,因此实际所有者的持有时间会正确增加。
向后兼容性
此提案与现有的 ERC-721 标准完全向后兼容,因为它使用不影响核心功能的新函数扩展了该标准。
参考实现
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./IERC6806.sol";
contract ERC6806 is ERC721, Ownable, IERC6806 {
mapping(uint256 => address) private _holder;
mapping(uint256 => uint256) private _holdStart;
mapping(address => bool) private _holdingTimeWhitelist;
constructor(
string memory name_,
string memory symbol_
) ERC721(name_, symbol_) {}
function _afterTokenTransfer(
address from,
address to,
uint256 firstotTokenId,
uint256
) internal override {
if (_holdingTimeWhitelist[from] || _holdingTimeWhitelist[to]) {
return;
}
if (_holder[firstotTokenId] != to) {
_holder[firstotTokenId] = to;
_holdStart[firstotTokenId] = block.timestamp;
}
}
function getHoldingInfo(
uint256 tokenId
) public view returns (address holder, uint256 holdingTime) {
return (_holder[tokenId], block.timestamp - _holdStart[tokenId]);
}
/**
* @dev 设置是否忽略重置持有时间
* @param account 需要设置的地址
* @param ignoreReset 是否忽略重置
*/
function setHoldingTimeWhitelistedAddress(
address account,
bool ignoreReset
) public onlyOwner {
_holdingTimeWhitelist[account] = ignoreReset;
emit HoldingTimeWhitelistSet(account, ignoreReset);
}
}
安全考虑
此 EIP 引入了用于跟踪持有时间的额外状态管理,这可能具有安全隐患。实施者应警惕与持有时间操纵相关的潜在漏洞,尤其是在转移期间。
在实施此 EIP 时,开发人员应注意潜在的攻击媒介,例如重入攻击和抢先交易攻击,以及智能合约的一般安全最佳实践。应进行充分的测试和代码审查,以确保实施的安全性和正确性。
此外,开发人员应考虑与维护和更新持有时间信息相关的 gas 成本。可能需要进行优化以最大程度地减少对合约执行成本的影响。
同样重要的是要注意,持有时间信息的准确性取决于底层区块链时间戳的准确性。虽然区块时间戳通常是可靠的,但矿工可以在一定程度上对其进行操纵。因此,在需要绝对精度的情况下,不应将持有时间数据作为唯一的真实来源。
版权
版权及相关权利通过 CC0 放弃。
Citation
Please cite this document as:
Saitama (@saitama2009), Combo <combo@1combo.io>, Luigi <luigi@1combo.io>, "ERC-6806: ERC-721 持有时间跟踪 [DRAFT]," Ethereum Improvement Proposals, no. 6806, March 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6806.