This standard is an extension of ERC-721. It proposes some additional functions (startTime, endTime) to help with on-chain time management.
Motivation
Some NFTs have a defined usage period and cannot be used outside of that period. With traditional NFTs that do not include time information, if you want to mark a token as invalid or enable it at a specific time, you need to actively submit a transaction—a process both cumbersome and expensive.
Some existing NFTs contain time functions, but their interfaces are not consistent, so it is difficult to develop third-party platforms for them.
By introducing these functions (startTime, endTime), it is possible to enable and disable NFTs automatically on chain.
Specification
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY” and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
/**
* @dev the ERC-165 identifier for this interface is 0xf140be0d.
*/interfaceIERC5007/* is IERC721 */{/**
* @dev Returns the start time of the NFT as a UNIX timestamp.
*
* Requirements:
*
* - `tokenId` must exist.
*/functionstartTime(uint256tokenId)externalviewreturns(uint64);/**
* @dev Returns the end time of the NFT as a UNIX timestamp.
*
* Requirements:
*
* - `tokenId` must exist.
*/functionendTime(uint256tokenId)externalviewreturns(uint64);}
The composable extension is OPTIONAL for this standard. This allows your NFT to be minted from an existing NFT or to merge two NFTs into one NFT.
/**
* @dev the ERC-165 identifier for this interface is 0x75cf3842.
*/interfaceIERC5007Composable/* is IERC5007 */{/**
* @dev Returns the asset id of the time NFT.
* Only NFTs with same asset id can be merged.
*
* Requirements:
*
* - `tokenId` must exist.
*/functionassetId(uint256tokenId)externalviewreturns(uint256);/**
* @dev Split an old token to two new tokens.
* The assetId of the new token is the same as the assetId of the old token
*
* Requirements:
*
* - `oldTokenId` must exist.
* - `newToken1Id` must not exist.
* - `newToken1Owner` cannot be the zero address.
* - `newToken2Id` must not exist.
* - `newToken2Owner` cannot be the zero address.
* - `splitTime` require(oldToken.startTime <= splitTime && splitTime < oldToken.EndTime)
*/functionsplit(uint256oldTokenId,uint256newToken1Id,addressnewToken1Owner,uint256newToken2Id,addressnewToken2Owner,uint64splitTime)external;/**
* @dev Merge the first token and second token into the new token.
*
* Requirements:
*
* - `firstTokenId` must exist.
* - `secondTokenId` must exist.
* - require((firstToken.endTime + 1) == secondToken.startTime)
* - require((firstToken.assetId()) == secondToken.assetId())
* - `newTokenOwner` cannot be the zero address.
* - `newTokenId` must not exist.
*/functionmerge(uint256firstTokenId,uint256secondTokenId,addressnewTokenOwner,uint256newTokenId)external;}
Rationale
Time Data Type
The max value of uint64 is 18,446,744,073,709,551,615. As a timestamp, 18,446,744,073,709,551,615 is about year 584,942,419,325. uint256 is too big for C, C++, Java, Go, etc, and uint64 is natively supported by mainstream programming languages.