--- eip: 5007 title: Time NFT, EIP-721 Time Extension description: Add start time and end time to EIP-721 tokens. author: Anders (@0xanders), Lance (@LanceSnow), Shrug discussions-to: https://ethereum-magicians.org/t/eip-5007-eip-721-time-extension/8924 status: Last Call last-call-deadline: 2022-09-25 type: Standards Track category: ERC created: 2022-04-13 requires: 165, 721 --- ## Abstract This standard is an extension of [EIP-721](./eip-721.md). 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. ```solidity /** * @dev the EIP-165 identifier for this interface is 0x7a0cdf92. */ interface IERC5007 /* is IERC721 */ { /** * @dev Returns the start time of the NFT as a UNIX timestamp. * * Requirements: * * - `tokenId` must exist. */ function startTime(uint256 tokenId) external view returns (int64); /** * @dev Returns the end time of the NFT as a UNIX timestamp. * * Requirements: * * - `tokenId` must exist. */ function endTime(uint256 tokenId) external view returns (int64); } ``` 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. ```solidity /** * @dev the EIP-165 identifier for this interface is 0x620063db. */ interface IERC5007Composable /* is IERC5007 */ { /** * @dev Returns the ancestor token id of the NFT. * * Requirements: * * - `tokenId` must exist. */ function rootTokenId(uint256 tokenId) external view returns (uint256); /** * @dev Mint a new token from an old token. * The rootTokenId of the new token is the same as the rootTokenId of the old token * * Requirements: * * - `oldTokenId` must exist. * - `newTokenId` must not exist. * - `newTokenOwner` cannot be the zero address. * - `newTokenStartTime` require(oldTokenStartTime < newTokenStartTime && newTokenStartTime <= oldTokenEndTime) */ function split( uint256 oldTokenId, uint256 newTokenId, address newTokenOwner, int64 newTokenStartTime ) 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) * - `newTokenOwner` cannot be the zero address. * - `newTokenId` must not exist. */ function merge( uint256 firstTokenId, uint256 secondTokenId, address newTokenOwner, uint256 newTokenId ) external; } ``` ## Rationale ### Time Data Type The max value of `int64` is 9,223,372,036,854,775,807. As a timestamp, 9,223,372,036,854,775,807 is about year 292,471,210,648. `uint256` is too big for C, C++, Java, Go, etc, and `int64` is natively supported by mainstream programming languages. ## Backwards Compatibility This standard is fully EIP-721 compatible. ## Test Cases Test cases are included in [test.js](../assets/eip-5007/test/test.js). Run in terminal: ```shell cd ../assets/eip-5007 npm install truffle test ``` ## Reference Implementation See [`ERC5007.sol`](../assets/eip-5007/contracts/ERC5007.sol). ## Security Considerations No security issues found. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).