From 3525d94b0d82b9ea214187f3302b7a4754f9e570 Mon Sep 17 00:00:00 2001 From: Saber-Data61 Date: Tue, 12 Mar 2024 10:23:27 +1100 Subject: [PATCH 01/11] Update erc-5521.md --- ERCS/erc-5521.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index d0839a8b50..fe5205f180 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -4,7 +4,7 @@ title: Referable NFT description: An ERC-721 extension to construct reference relationships among NFTs author: Saber Yu (@OniReimu), Qin Wang , Shange Fu , Yilin Sai , Shiping Chen , Sherry Xu , Jiangshan Yu discussions-to: https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310 -status: Review +status: Last Call type: Standards Track category: ERC created: 2022-08-10 From 53ed3bce398c297b10e37437ad81400866695232 Mon Sep 17 00:00:00 2001 From: Saber-Data61 Date: Tue, 12 Mar 2024 11:06:23 +1100 Subject: [PATCH 02/11] Update erc-5521.md --- ERCS/erc-5521.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index fe5205f180..f23efd63d6 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -5,6 +5,7 @@ description: An ERC-721 extension to construct reference relationships among NFT author: Saber Yu (@OniReimu), Qin Wang , Shange Fu , Yilin Sai , Shiping Chen , Sherry Xu , Jiangshan Yu discussions-to: https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310 status: Last Call +last-call-deadline: 2024-04-02 type: Standards Track category: ERC created: 2022-08-10 From 1eee16206431bedcdfc756f4dc05d4c083ab21d1 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 2 Apr 2024 10:11:54 -0400 Subject: [PATCH 03/11] Update erc-5521.md --- ERCS/erc-5521.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index f23efd63d6..9913b6d27a 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -5,7 +5,7 @@ description: An ERC-721 extension to construct reference relationships among NFT author: Saber Yu (@OniReimu), Qin Wang , Shange Fu , Yilin Sai , Shiping Chen , Sherry Xu , Jiangshan Yu discussions-to: https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310 status: Last Call -last-call-deadline: 2024-04-02 +last-call-deadline: 2024-04-16 type: Standards Track category: ERC created: 2022-08-10 @@ -30,7 +30,7 @@ By adding the `referring` indicator, users can mint new NFTs (e.g., C, D, E) by The key words “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. -- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the rNFTs were being created or `profitSharing` recording the profit sharing of `referring`. +- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or `profitSharing` recording the profit sharing of `referring`. - `referring`: an out-degree indicator, used to show the users this NFT refers to; - `referred`: an in-degree indicator, used to show the users who have refereed this NFT; - `referringKeys`: a helper for mapping conversion of out-degree indicators, used for events; From 98e39d5a15ff8a3ad8dcaa7b83f1319d227cf852 Mon Sep 17 00:00:00 2001 From: OniReimu Date: Wed, 3 Apr 2024 18:45:06 +1100 Subject: [PATCH 04/11] Update erc-5521.md --- ERCS/erc-5521.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 9913b6d27a..7f566cf729 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -22,9 +22,14 @@ This standard is an extension of [ERC-721](./eip-721.md). It proposes two refera ## Motivation -Many scenarios require inheritance, reference, and extension of NFTs. For instance, an artist may develop his NFT work based on a previous NFT, or a DJ may remix his record by referring to two pop songs, etc. Proposing a referable solution for existing NFTs and enabling efficient queries on cross-references make much sense. +Many scenarios require the inheritance, reference, and extension of NFTs. For instance, an artist may develop his NFT work based on a previous NFT, or a DJ may remix his record by referring to two pop songs, etc. A gap in existing NFT standards is the absence of established relationships between an NFT and its original creator. This void isolates NFTs, rendering the sale of each one a one-off transaction, thereby obstructing creators from accruing the full value of their intellectual property over time. + +In this sense, proposing a referable solution for existing NFTs that enables efficient queries on cross-references is necessary. By introducing a reference relationship between NFTs, a sustainable economic model can be established to incentivize continued engagement in creating, using, and promoting NFTs. + +This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including 'referring' and 'referred' relationships, aiding in the formation of a Direct Acyclic Graph (DAG)--based NFT network. This structure provides a transparent graphically historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew. + +An intuitive example: users can create new NFTs (C, D, E) by referencing existing ones (A, B), while the `referred` function informs the original NFTs (A, B) about their citations (e.g., A ← D; C ← E; B ← E, and A ← E). Here, the `createdTimestamp` (block-level) serves as an indicator for the creation time of NFTs (A, B, C, D, E). -By adding the `referring` indicator, users can mint new NFTs (e.g., C, D, E) by referring to existing NFTs (e.g., A, B), while `referred` enables the referred NFTs (A, B) to be aware that who has quoted it (e.g., A ← D; C ← E; B ← E, and A ← E). The `createdTimestamp` is an indicator used to show the creation time of NFTs (A, B, C, D, E). ## Specification @@ -105,7 +110,21 @@ interface TargetContract is IERC165 { ## Rationale -This standard is intended to establish the referable DAG for queries on cross-relationship and accordingly provide the simplest functions. It provides advantages as follows. +### Notices + +- `createdTimestamp`: A key principle of this standard is that an NFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for NFTs are therefore essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where `createdTimestamp = block.timestamp` Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two NFTs within the same block. + +- `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. + +- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. + +- `setNodeReferredExternal`: This function operates conditionally, dependent on successful interface verification in external contracts. Such selective invocation ensures backward compatibility and integration with existing contracts, provided they adhere to specified interfaces. + +- `UpdateNode`: This event disseminates crucial information, including the rNFT ID, its owner, and lists of contract addresses/IDs with rNFTs referring to or referred by the subject rNFT. This data set enables stakeholders to efficiently manage and navigate the complex web of relationships inherent in the rNFT ecosystem. + +### Key Takeaways + +This standard provides several advantages: *Clear ownership inheritance*: This standard extends the static NFT into a virtually extensible NFT network. Artists do not have to create work isolated from others. The ownership inheritance avoids reinventing the same wheel. @@ -113,7 +132,7 @@ This standard is intended to establish the referable DAG for queries on cross-re *Easy Integration*: This standard makes it easier for the existing token standards or third-party protocols. For instance, the rNFT can be applied to rentable scenarios (cf. [ERC-5006](./eip-5006.md) to build a hierarchical rental market, where multiple users can rent the same NFT during the same time or one user can rent multiple NFTs during the same duration). -*Scalable Interoperability* From March 26th 2023, this standard has been stepping forward by enabling cross-contract references, giving a scalable adoption for the broader public with stronger interoperability. +*Scalable Interoperability*: This standard enables cross-contract references, giving a scalable adoption for the broader public with stronger interoperability. ## Backwards Compatibility From 1f4807a34b483d132b382dc946a97a6a6e66accc Mon Sep 17 00:00:00 2001 From: OniReimu Date: Wed, 3 Apr 2024 18:54:47 +1100 Subject: [PATCH 05/11] Update erc-5521.md --- ERCS/erc-5521.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 7f566cf729..ebddc2f905 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -22,11 +22,11 @@ This standard is an extension of [ERC-721](./eip-721.md). It proposes two refera ## Motivation -Many scenarios require the inheritance, reference, and extension of NFTs. For instance, an artist may develop his NFT work based on a previous NFT, or a DJ may remix his record by referring to two pop songs, etc. A gap in existing NFT standards is the absence of established relationships between an NFT and its original creator. This void isolates NFTs, rendering the sale of each one a one-off transaction, thereby obstructing creators from accruing the full value of their intellectual property over time. +Many scenarios require the inheritance, reference, and extension of NFTs. For instance, an artist may develop his NFT work based on a previous NFT, or a DJ may remix his record by referring to two pop songs, etc. A gap in existing NFT standards is the absence of established relationships between an NFT and its original creator. This void isolates NFTs, rendering the sale of each one a one-off transaction, thereby obstructing creators from accruing the full value of their intellectual property over time. In this sense, proposing a referable solution for existing NFTs that enables efficient queries on cross-references is necessary. By introducing a reference relationship between NFTs, a sustainable economic model can be established to incentivize continued engagement in creating, using, and promoting NFTs. -This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including 'referring' and 'referred' relationships, aiding in the formation of a Direct Acyclic Graph (DAG)--based NFT network. This structure provides a transparent graphically historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew. +This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including `referring` and `referred` relationships, aiding in the formation of a Direct Acyclic Graph (DAG)-based NFT network. This structure provides a transparent graphically historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew. An intuitive example: users can create new NFTs (C, D, E) by referencing existing ones (A, B), while the `referred` function informs the original NFTs (A, B) about their citations (e.g., A ← D; C ← E; B ← E, and A ← E). Here, the `createdTimestamp` (block-level) serves as an indicator for the creation time of NFTs (A, B, C, D, E). From 2b1221966b1278ae97288cc4cd3bed598b86be7b Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 16 Apr 2024 10:20:22 -0400 Subject: [PATCH 06/11] Update erc-5521.md --- ERCS/erc-5521.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index ebddc2f905..e93be42de5 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -5,7 +5,7 @@ description: An ERC-721 extension to construct reference relationships among NFT author: Saber Yu (@OniReimu), Qin Wang , Shange Fu , Yilin Sai , Shiping Chen , Sherry Xu , Jiangshan Yu discussions-to: https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310 status: Last Call -last-call-deadline: 2024-04-16 +last-call-deadline: 2024-04-30 type: Standards Track category: ERC created: 2022-08-10 From a2202e70c349024a053a414eec3b6819d8f36843 Mon Sep 17 00:00:00 2001 From: saber Date: Wed, 17 Apr 2024 20:30:40 +1200 Subject: [PATCH 07/11] Response to comments from reviewers Response to comments from reviewers --- ERCS/erc-5521.md | 67 ++++++++++++++++++++++++++--------- assets/erc-5521/ERC_5521.sol | 18 ++++++++++ assets/erc-5521/IERC_5521.sol | 6 ++++ 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index e93be42de5..86649b7b01 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -30,6 +30,18 @@ This standard accordingly introduces a new concept, referable NFT (rNFT), which An intuitive example: users can create new NFTs (C, D, E) by referencing existing ones (A, B), while the `referred` function informs the original NFTs (A, B) about their citations (e.g., A ← D; C ← E; B ← E, and A ← E). Here, the `createdTimestamp` (block-level) serves as an indicator for the creation time of NFTs (A, B, C, D, E). +### Key Takeaways + +This standard provides several advantages: + +*Clear ownership inheritance*: This standard extends the static NFT into a virtually extensible NFT network. Artists do not have to create work isolated from others. The ownership inheritance avoids reinventing the same wheel. + +*Incentive Compatibility*: This standard clarifies the referable relationship across different NFTs, helping to integrate multiple up-layer incentive models for both original NFT owners and new creators. + +*Easy Integration*: This standard makes it easier for the existing token standards or third-party protocols. For instance, the rNFT can be applied to rentable scenarios (cf. [ERC-5006](./eip-5006.md) to build a hierarchical rental market, where multiple users can rent the same NFT during the same time or one user can rent multiple NFTs during the same duration). + +*Scalable Interoperability*: This standard enables cross-contract references, giving a scalable adoption for the broader public with stronger interoperability. + ## Specification @@ -87,6 +99,11 @@ interface IERC_5521 is IERC165 { /// @param `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT. /// @return the referred mapping of the rNFT. function referredOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); + + /// @notice get the timestamp of an rNFT when is being created. + /// @param `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT. + /// @return the timestamp of the rNFT when is being created with uint256 format. + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256); /// @notice check supported interfaces, adhereing to ERC165. function supportsInterface(bytes4 interfaceId) external view returns (bool); @@ -102,6 +119,8 @@ interface TargetContract is IERC165 { function referringOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); function referredOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); + + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256); function supportsInterface(bytes4 interfaceId) external view returns (bool); } @@ -110,29 +129,19 @@ interface TargetContract is IERC165 { ## Rationale -### Notices +### Is this event informative enough? +`UpdateNode`: This event disseminates crucial information, including the rNFT ID, its owner, and lists of contract addresses/IDs with rNFTs referring to or referred by the subject rNFT. This data set enables stakeholders to efficiently manage and navigate the complex web of relationships inherent in the rNFT ecosystem. -- `createdTimestamp`: A key principle of this standard is that an NFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for NFTs are therefore essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where `createdTimestamp = block.timestamp` Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two NFTs within the same block. +Implementers are free to choose to use a struct (a **RECOMMENDED** struct is given in the Reference Implementation), or several separate mappings, or whatever other storage mechanism. Whichever mechanism chosen has no observable effect on the behaviour of the contract, as long as its output can fulfill the `UpdateNode` event. -- `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. +### Why `createdTimestampOf`? +`createdTimestamp`: A key principle of this standard is that an rNFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for rNFTs are therefore essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where `createdTimestamp = block.timestamp` Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two rNFTs within the same block. -- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. -- `setNodeReferredExternal`: This function operates conditionally, dependent on successful interface verification in external contracts. Such selective invocation ensures backward compatibility and integration with existing contracts, provided they adhere to specified interfaces. +### How is cross-contract reference performed? +`setNodeReferredExternal`: This function operates conditionally, dependent on successful interface verification in external contracts. Such selective invocation ensures backward compatibility and integration with existing contracts, provided they adhere to specified interfaces. -- `UpdateNode`: This event disseminates crucial information, including the rNFT ID, its owner, and lists of contract addresses/IDs with rNFTs referring to or referred by the subject rNFT. This data set enables stakeholders to efficiently manage and navigate the complex web of relationships inherent in the rNFT ecosystem. -### Key Takeaways - -This standard provides several advantages: - -*Clear ownership inheritance*: This standard extends the static NFT into a virtually extensible NFT network. Artists do not have to create work isolated from others. The ownership inheritance avoids reinventing the same wheel. - -*Incentive Compatibility*: This standard clarifies the referable relationship across different NFTs, helping to integrate multiple up-layer incentive models for both original NFT owners and new creators. - -*Easy Integration*: This standard makes it easier for the existing token standards or third-party protocols. For instance, the rNFT can be applied to rentable scenarios (cf. [ERC-5006](./eip-5006.md) to build a hierarchical rental market, where multiple users can rent the same NFT during the same time or one user can rent multiple NFTs during the same duration). - -*Scalable Interoperability*: This standard enables cross-contract references, giving a scalable adoption for the broader public with stronger interoperability. ## Backwards Compatibility @@ -284,6 +293,24 @@ contract ERC_5521 is ERC721, IERC_5521, TargetContract { return (_referredKeys, _referredValues); } + /// @notice Get the timestamp of an rNFT when is being created. + /// @param `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT. + /// @return The timestamp of the rNFT when is being created with uint256 format. + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256) { + uint256 memory createdTimestamp; + + if (_address == address(this)) { + require(_exists(tokenId), "ERC_5521: token ID not existed"); + Relationship storage relationship = _relationship[tokenId]; + createdTimestamp = relationship.createdTimestamp; + } else { + TargetContract targetContractInstance = TargetContract(_address); + require(targetContractInstance.supportsInterface(type(TargetContract).interfaceId), "ERC_5521: target contract not supported"); + createdTimestamp = targetContractInstance.createdTimestampOf(_address, tokenId); + } + return createdTimestamp; + } + /// @dev See {IERC165-supportsInterface}. function supportsInterface(bytes4 interfaceId) public view virtual override (ERC721, IERC_5521, TargetContract) returns (bool) { return interfaceId == type(IERC_5521).interfaceId @@ -325,6 +352,12 @@ contract ERC_5521 is ERC721, IERC_5521, TargetContract { ``` +### Notices + +- `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. + +- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. + ## Security Considerations ### Timestamp diff --git a/assets/erc-5521/ERC_5521.sol b/assets/erc-5521/ERC_5521.sol index 911bfa2e7a..b395a22f1e 100644 --- a/assets/erc-5521/ERC_5521.sol +++ b/assets/erc-5521/ERC_5521.sol @@ -138,6 +138,24 @@ contract ERC_5521 is ERC721, IERC_5521, TargetContract { return (_referredKeys, _referredValues); } + /// @notice Get the timestamp of an rNFT when is being created. + /// @param `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT. + /// @return The timestamp of the rNFT when is being created with uint256 format. + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256) { + uint256 memory createdTimestamp; + + if (_address == address(this)) { + require(_exists(tokenId), "ERC_5521: token ID not existed"); + Relationship storage relationship = _relationship[tokenId]; + createdTimestamp = relationship.createdTimestamp; + } else { + TargetContract targetContractInstance = TargetContract(_address); + require(targetContractInstance.supportsInterface(type(TargetContract).interfaceId), "ERC_5521: target contract not supported"); + createdTimestamp = targetContractInstance.createdTimestampOf(_address, tokenId); + } + return createdTimestamp; + } + /// @dev See {IERC165-supportsInterface}. function supportsInterface(bytes4 interfaceId) public view virtual override (ERC721, IERC_5521, TargetContract) returns (bool) { return interfaceId == type(IERC_5521).interfaceId diff --git a/assets/erc-5521/IERC_5521.sol b/assets/erc-5521/IERC_5521.sol index c1f5f1068e..ddef6c5f3f 100644 --- a/assets/erc-5521/IERC_5521.sol +++ b/assets/erc-5521/IERC_5521.sol @@ -29,6 +29,11 @@ interface IERC_5521 is IERC165 { /// @return The referred mapping of an rNFT function referredOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); + /// @notice get the timestamp of an rNFT when is being created. + /// @param `tokenId` of the rNFT being focused, `_address` of contract address associated with the focused rNFT. + /// @return the timestamp of the rNFT when is being created with uint256 format. + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256); + function supportsInterface(bytes4 interfaceId) external view returns (bool); } @@ -36,5 +41,6 @@ interface TargetContract is IERC165 { function setNodeReferredExternal(address successor, uint256 tokenId, uint256[] memory _tokenIds) external; function referringOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); function referredOf(address _address, uint256 tokenId) external view returns(address[] memory, uint256[][] memory); + function createdTimestampOf(address _address, uint256 tokenId) external view returns(uint256); function supportsInterface(bytes4 interfaceId) external view returns (bool); } From a728830e1e35e97cf284cac8221ac221ccc5398d Mon Sep 17 00:00:00 2001 From: saber Date: Wed, 17 Apr 2024 20:43:05 +1200 Subject: [PATCH 08/11] Update erc-5521.md --- ERCS/erc-5521.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 86649b7b01..893bd903b6 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -47,19 +47,24 @@ This standard provides several advantages: The key words “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. -- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or `profitSharing` recording the profit sharing of `referring`. -- `referring`: an out-degree indicator, used to show the users this NFT refers to; -- `referred`: an in-degree indicator, used to show the users who have refereed this NFT; -- `referringKeys`: a helper for mapping conversion of out-degree indicators, used for events; -- `referredKeys`: a helper for mapping conversion of in-degree indicators, used for events; -- `createdTimestamp`: a time-based indicator, used to compare the timestamp of mint, which **MUST NOT** be editable anyhow by callers; +**MUST**-do specification: +- `UpdateNode`: event emitted when `setNode` is invoked; - `safeMint`: mint a new rNFT; - `setNode`: set the referring list of an rNFT and update the referred list of each one in the referring list; - `setNodeReferring`: set the referring list of an rNFT; - `setNodeReferred`: set the referred list of the given rNFTs sourced from different contracts; - `setNodeReferredExternal`: set the referred list of the given rNFTs sourced from external contracts; - `referringOf`: get the referring list of an rNFT; -- `referredOf`: get the referred list of an rNFT. +- `referredOf`: get the referred list of an rNFT; +- `createdTimestampOf`: get the timestamp of an rNFT when it is being created. + +**RECOMMENDED**-do specification: +- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or `profitSharing` recording the profit sharing of `referring`. +- `referring`: an out-degree indicator, used to show the users this NFT refers to; +- `referred`: an in-degree indicator, used to show the users who have refereed this NFT; +- `referringKeys`: a helper for mapping conversion of out-degree indicators, used for events; +- `referredKeys`: a helper for mapping conversion of in-degree indicators, used for events; +- `createdTimestamp`: a time-based indicator, used to compare the timestamp of mint, which **MUST NOT** be editable anyhow by callers. Implementers of this standard **MUST** have all of the following functions: From 9159d492f1bf71a6d8161a1bf8fd3d502c14a1d5 Mon Sep 17 00:00:00 2001 From: saber Date: Wed, 17 Apr 2024 20:48:52 +1200 Subject: [PATCH 09/11] Update erc-5521.md --- ERCS/erc-5521.md | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 893bd903b6..994a251853 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -47,7 +47,6 @@ This standard provides several advantages: The key words “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. -**MUST**-do specification: - `UpdateNode`: event emitted when `setNode` is invoked; - `safeMint`: mint a new rNFT; - `setNode`: set the referring list of an rNFT and update the referred list of each one in the referring list; @@ -58,14 +57,6 @@ The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL - `referredOf`: get the referred list of an rNFT; - `createdTimestampOf`: get the timestamp of an rNFT when it is being created. -**RECOMMENDED**-do specification: -- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or `profitSharing` recording the profit sharing of `referring`. -- `referring`: an out-degree indicator, used to show the users this NFT refers to; -- `referred`: an in-degree indicator, used to show the users who have refereed this NFT; -- `referringKeys`: a helper for mapping conversion of out-degree indicators, used for events; -- `referredKeys`: a helper for mapping conversion of in-degree indicators, used for events; -- `createdTimestamp`: a time-based indicator, used to compare the timestamp of mint, which **MUST NOT** be editable anyhow by callers. - Implementers of this standard **MUST** have all of the following functions: ```solidity @@ -158,6 +149,17 @@ Test cases are included in [ERC_5521.test.js](../assets/eip-5521/ERC_5521.test.j ## Reference Implementation +The **RECOMMENDED** implementation is demonstrated as follows: + +- `Relationship`: a structure that contains `referring`, `referred`, `referringKeys`, `referredKeys`, `createdTimestamp`, and other customized and **OPTIONAL** attributes (i.e., not necessarily included in the standard) such as `privityOfAgreement` recording the ownerships of referred NFTs at the time the Referable NFTs (rNFTs) were being created or `profitSharing` recording the profit sharing of `referring`. +- `referring`: an out-degree indicator, used to show the users this NFT refers to; +- `referred`: an in-degree indicator, used to show the users who have refereed this NFT; +- `referringKeys`: a helper for mapping conversion of out-degree indicators, used for events; +- `referredKeys`: a helper for mapping conversion of in-degree indicators, used for events; +- `createdTimestamp`: a time-based indicator, used to compare the timestamp of mint, which **MUST NOT** be editable anyhow by callers. +- `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. +- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. + ```solidity pragma solidity ^0.8.4; @@ -357,11 +359,6 @@ contract ERC_5521 is ERC721, IERC_5521, TargetContract { ``` -### Notices - -- `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. - -- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. ## Security Considerations From e43e12b8cd79803a56e297db3f105be238c3e844 Mon Sep 17 00:00:00 2001 From: saber Date: Tue, 23 Apr 2024 16:59:25 +1200 Subject: [PATCH 10/11] Update erc-5521.md --- ERCS/erc-5521.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 994a251853..2f5a011ce1 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -26,7 +26,7 @@ Many scenarios require the inheritance, reference, and extension of NFTs. For in In this sense, proposing a referable solution for existing NFTs that enables efficient queries on cross-references is necessary. By introducing a reference relationship between NFTs, a sustainable economic model can be established to incentivize continued engagement in creating, using, and promoting NFTs. -This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including `referring` and `referred` relationships, aiding in the formation of a Direct Acyclic Graph (DAG)-based NFT network. This structure provides a transparent graphically historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew. +This standard accordingly introduces a new concept, referable NFT (rNFT), which can transform static NFTs into a dynamically extensible network. We embed reference information, including `referring` and `referred` relationships, aiding in the formation of a Direct Acyclic Graph (DAG)-based NFT network. This structure provides a transparent graphical historical record and allows users to query, trace, and analyze relationships. It can enable NFT creators to build upon existing works without the need to start anew. An intuitive example: users can create new NFTs (C, D, E) by referencing existing ones (A, B), while the `referred` function informs the original NFTs (A, B) about their citations (e.g., A ← D; C ← E; B ← E, and A ← E). Here, the `createdTimestamp` (block-level) serves as an indicator for the creation time of NFTs (A, B, C, D, E). @@ -131,7 +131,7 @@ interface TargetContract is IERC165 { Implementers are free to choose to use a struct (a **RECOMMENDED** struct is given in the Reference Implementation), or several separate mappings, or whatever other storage mechanism. Whichever mechanism chosen has no observable effect on the behaviour of the contract, as long as its output can fulfill the `UpdateNode` event. ### Why `createdTimestampOf`? -`createdTimestamp`: A key principle of this standard is that an rNFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for rNFTs are therefore essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where `createdTimestamp = block.timestamp` Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two rNFTs within the same block. +`createdTimestamp`: A key principle of this standard is that an rNFT should reference content already accepted by the community (a time-based sequence known by participants). Global timestamps for rNFTs are thus essential, serving to prevent conflicting states (akin to concurrency issues in transaction processing and block organization). We define a block-level timestamp where `createdTimestamp = block.timestamp` Note that, given that the granularity of references is tied to the block timestamp, it is impractical to discern the order of two rNFTs within the same block. ### How is cross-contract reference performed? @@ -158,7 +158,7 @@ The **RECOMMENDED** implementation is demonstrated as follows: - `referredKeys`: a helper for mapping conversion of in-degree indicators, used for events; - `createdTimestamp`: a time-based indicator, used to compare the timestamp of mint, which **MUST NOT** be editable anyhow by callers. - `referringOf` and `referredOf`: First, the current `referringOf` and `referredOf` allow cross-contract looking up, while this cannot be done by directly accessing `_relationship`. Secondly, only if privacy is not a concern, making `_relationship` public simplifies the contract by relying on Solidity’s automatically generated getters. However, if you need to control the visibility of the data, keeping the state variable private and providing specific getter functions would be the best approach. For example, if `_relationship` includes details about specific users’ interactions or transactions or some private extensible parameters (in the updated version, we specifically highlight the `Relationship` can be extended to meet different requirements), always making this data public could reveal users’ behavior patterns or preferences, leading to potential privacy breaches. -- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` becomes necessary for fulfilling our event emission requirements. +- `convertMap`: This function is essential for retrieving the full mapping contents within a struct. Even if `_relationship` is public, The getters only allow retrieval of individual values for specific keys. Since we need comprehensive access to all stored addresses, `convertMap` is necessary to fulfill our event emission requirements. ```solidity @@ -368,13 +368,13 @@ The `createdTimestamp` only covers the block-level timestamp (based on block hea ### Ownership and Reference -The change of ownership has nothing to do with the reference relationship. Normally, the distribution of profits complies to the aggreement when the NFT was being created regardless of the change of ownership unless specified in the agreement. +The change of ownership has nothing to do with the reference relationship. Normally, the distribution of profits complies with the agreement when the NFT was being created regardless of the change of ownership unless specified in the agreement. -Referring a token will not refer its descendants by default. In the case that only a specific child token gets referred, it means the privity of contract will involve nobody other than the owner of this specific child token. Alternatively, a chain-of-reference all the way from the root token to a specific very bottom child token (from root to leaf) can be constructured and recorded in the `referring` to explicitly define the distribution of profits. +Referring a token will not refer to its descendants by default. In the case that only a specific child token gets referred, it means the privity of the contract will involve nobody other than the owner of this specific child token. Alternatively, a chain-of-reference all the way from the root token to a specific very bottom child token (from root to leaf) can be constructed and recorded in the `referring` to explicitly define the distribution of profits. ### Open Minting and Relationship Risks -The `safeMint` function has been deliberately designed to allow unrestricted minting and relationship setting, akin to the open referencing system seen in platforms such as Google Scholar. This decision facilitates strong flexibility, enabling any user to create and define relationships between NFTs without centralized control. While this design aligns with the intended openness of the system, it inherently carries certain risks. Unauthorized or incorrect references can be created, mirroring the challenges faced in traditional scholarly referencing where erroneous citations may occur. Additionally, the open nature may expose the system to potential abuse by malicious actors, who might manipulate relationships or inflate token supply. It is important to recognize that these risks are not considered design flaws but intentional trade-offs, which balances the system's flexibility against potential reliability concerns. +The `safeMint` function has been deliberately designed to allow unrestricted minting and relationship setting, akin to the open referencing system seen in platforms such as Google Scholar. This decision facilitates strong flexibility, enabling any user to create and define relationships between NFTs without centralized control. While this design aligns with the intended openness of the system, it inherently carries certain risks. Unauthorized or incorrect references can be created, mirroring the challenges faced in traditional scholarly referencing, where erroneous citations may occur. Additionally, the open nature may expose the system to potential abuse by malicious actors, who might manipulate relationships or inflate the token supply. It is important to recognize that these risks are not considered design flaws but intentional trade-offs, which balance the system's flexibility against potential reliability concerns. Stakeholders should be aware that the on-chain data integrity guarantees extend only to what has been recorded on the blockchain and do not preclude the possibility of off-chain errors or manipulations. Thus, users and integrators should exercise caution and judgment in interpreting and using the relationships and other data provided by this system. From 87178daaf24fd934c70a6c7b8540564f83390838 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Fri, 24 May 2024 17:01:09 -0400 Subject: [PATCH 11/11] Update erc-5521.md --- ERCS/erc-5521.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-5521.md b/ERCS/erc-5521.md index 2f5a011ce1..706e8f2366 100644 --- a/ERCS/erc-5521.md +++ b/ERCS/erc-5521.md @@ -5,7 +5,7 @@ description: An ERC-721 extension to construct reference relationships among NFT author: Saber Yu (@OniReimu), Qin Wang , Shange Fu , Yilin Sai , Shiping Chen , Sherry Xu , Jiangshan Yu discussions-to: https://ethereum-magicians.org/t/eip-x-erc-721-referable-nft/10310 status: Last Call -last-call-deadline: 2024-04-30 +last-call-deadline: 2024-06-07 type: Standards Track category: ERC created: 2022-08-10