From 6506de43921526dc799ec63409766658e0ab1c99 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 19 Apr 2023 13:21:34 -0700 Subject: [PATCH 1/5] add versioned token ID EIP --- EIPS/eip-tbd.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 EIPS/eip-tbd.md diff --git a/EIPS/eip-tbd.md b/EIPS/eip-tbd.md new file mode 100644 index 00000000000000..83fca500f4f255 --- /dev/null +++ b/EIPS/eip-tbd.md @@ -0,0 +1,84 @@ +--- +eip: tbd +title: Versioned TokenId Standard for Dynamic NFTs +author: James Wenzel (emo.eth, @emo_eth) +discussions-to: https://ethereum-magicians.org/t/tbd +status: Draft +type: Standards Track +category: ERC +created: 2023-04-19 +requires: 721 +--- + +## Simple Summary +This EIP proposes an extension to the EIP-721 non-fungible token standard by introducing a Versioned TokenId standard for "dynamic" NFTs with on or offchain properties that may change over time. The new `versionedTokenId` is meant to track both the "identifier" of a token as well as its current "version" so that old outstanding orders and approvals for updated tokens are automatically invalidated. + +## Abstract +The key change this EIP makes to the EIP-721 standard is the introduction of Versioned TokenIds. A `uint256 versionedTokenId` MUST encode both the true token "identifier" along with a "version number". Encoding details should be left up to individual token implementations. + +When any onchain action occurs that changes a dynamic token's metadata (on or offchain), the token contract MUST emit a transfer event for the current `versionedTokenId` from the current owner to the null address (i.e., "burning" the old token). It also then MUST emit a transfer event of an updated `versionedTokenId` (which encodes the new "version number" and the same "identifier") from the null address to the original owner. The actual encoded token "identifier" MUST not change, and the encoded "version number" MUST change. + +## Motivation +The primary motivation for this EIP is to prevent unintentional sales or approved transfers of tokens whose metadata has been updated, while maintaining backward compatibility with all known marketplaces. + +Currently, if a token has a metadata update that makes it subjectively more or less valuable, all open orders, bids, and asks will still be valid. This standard aims to prevent malicious or unintended sales and previously approved transfers of NFTs after they have been changed on or offchain. By implementing this EIP, developers can create NFTs that automatically update their `versionedTokenId` when metadata changes occur, which will invalidate open orders and ensure that only the latest version of a token is used in onchain transactions. + +## Specification + +### Methods + +#### getCurrentVersionedTokenId + +```solidity +function getCurrentVersionedTokenId(uint256 tokenId) external view returns (uint256); +``` + +This method MUST return the current Versioned TokenId for the "identifier" encoded by a given `tokenId`. + +It MUST revert if passed a `tokenId` with an invalid or non-existent "identifier." + +It MUST return the current "version number" for the "identifier" encoded by the `tokenId`. + +It MUST NOT revert if the encoded "version number" is incorrect or outdated. This is to ensure it is always possible to find the current "version number" for a given token, even with an out-of-date or otherwise incorrect `versionedTokenId` (so long as the encoded "identifier" is valid). + +Implementation details about storage and retrieval of versioned token IDs SHOULD be left up to individual implementations. + + +Since some NFT marketplaces allow for bulk-signing of up to millions of orders, token developers who anticipate many metadata updates for their token SHOULD make individual token "version numbers" non-incremental but monotonically increasing. They SHOULD use a method of deriving new "version numbers" that makes it difficult or impossible to anticipate future `versionedTokenIds` far in advance, in order to make bulk signature phishing impractical. + +As an example, one method would be to use the current BLOCKHASH or PREVRANDAO to increment the current version number, truncated to the desired number of bits. While BLOCKHASH and PREVRANDAO are deterministic and able to be influenced, they are impractical to predict indefinitely far in advance, and are not easily influenced by a single actor. + + +### Changes to EIP-721 Methods +The following methods from EIP-721 MUST be updated to handle `versionedTokenIds`: + +```solidity +function approve(address, uint256) external; + +function getApproved(uint256) external returns (address) external view; + +function ownerOf(uint256) external returns (address) external view; + +function transferFrom(address, address, uint256) external; + +function safeTransferFrom(address, address, uint256) external; + +function safeTransferFrom(address, address, uint256, bytes) external; + +function tokenURI(uint256) external view returns (string); // from the optional ERC721Metadata extension +``` + +Each method MUST revert when called with a `versionedTokenId` that encodes an incorrect or outdated "version number". Each method SHOULD behave normally when called with a `versionedTokenId` that encodes the correct "version number" for a valid "identifier." + + +### Events + +#### `event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);` + +The standard ERC-721 `Transfer` event MUST be emitted when a token's metadata changes, first for the current `versionedTokenId` (including its encoded "token version") from the current owner to the null address, then for the updated `versionedTokenId` (which encodes the new "token version" and the same "identifier") from the null address to the original owner. + + + +## Rationale + +The introduction of versioned token IDs allows for better and safer marketplace handling of NFTs with changing metadata, and ensures that only the latest "version" of a token is used in onchain transactions. The specified behavior in this EIP minimizes the changes to the EIP-721 standard while maintaining full backwards compatibility with all known marketplaces. \ No newline at end of file From 82b3e4928ecb97027b056cc963046da4b2d3c118 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 19 Apr 2023 13:27:12 -0700 Subject: [PATCH 2/5] update with number --- EIPS/{eip-tbd.md => eip-6912.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename EIPS/{eip-tbd.md => eip-6912.md} (98%) diff --git a/EIPS/eip-tbd.md b/EIPS/eip-6912.md similarity index 98% rename from EIPS/eip-tbd.md rename to EIPS/eip-6912.md index 83fca500f4f255..203d8c44712187 100644 --- a/EIPS/eip-tbd.md +++ b/EIPS/eip-6912.md @@ -1,8 +1,8 @@ --- -eip: tbd +eip: 6912 title: Versioned TokenId Standard for Dynamic NFTs author: James Wenzel (emo.eth, @emo_eth) -discussions-to: https://ethereum-magicians.org/t/tbd +discussions-to: https://ethereum-magicians.org/t/eip-6912-versioned-tokenids-for-dynamic-nfts/13897 status: Draft type: Standards Track category: ERC From decdfb107397bb86e78aafc7728c02a0e8796d12 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 19 Apr 2023 13:35:45 -0700 Subject: [PATCH 3/5] address validation errors --- EIPS/eip-6912.md | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/EIPS/eip-6912.md b/EIPS/eip-6912.md index 203d8c44712187..822d8446b51c0e 100644 --- a/EIPS/eip-6912.md +++ b/EIPS/eip-6912.md @@ -1,7 +1,8 @@ --- eip: 6912 -title: Versioned TokenId Standard for Dynamic NFTs -author: James Wenzel (emo.eth, @emo_eth) +title: Versioned TokenIDs for Dynamic NFTs +description: A minimal, backwards-compatible specification for versioned token IDs for dynamic NFTs. +author: emo.eth (@jameswenzel) discussions-to: https://ethereum-magicians.org/t/eip-6912-versioned-tokenids-for-dynamic-nfts/13897 status: Draft type: Standards Track @@ -11,10 +12,10 @@ requires: 721 --- ## Simple Summary -This EIP proposes an extension to the EIP-721 non-fungible token standard by introducing a Versioned TokenId standard for "dynamic" NFTs with on or offchain properties that may change over time. The new `versionedTokenId` is meant to track both the "identifier" of a token as well as its current "version" so that old outstanding orders and approvals for updated tokens are automatically invalidated. +This EIP proposes an extension to the [ERC-721](./eip-721.md) non-fungible token standard by introducing a Versioned TokenId standard for "dynamic" NFTs with on or offchain properties that may change over time. The new `versionedTokenId` is meant to track both the "identifier" of a token as well as its current "version" so that old outstanding orders and approvals for updated tokens are automatically invalidated. ## Abstract -The key change this EIP makes to the EIP-721 standard is the introduction of Versioned TokenIds. A `uint256 versionedTokenId` MUST encode both the true token "identifier" along with a "version number". Encoding details should be left up to individual token implementations. +The key change this EIP makes to the ERC-721 standard is the introduction of Versioned TokenIds. A `uint256 versionedTokenId` MUST encode both the true token "identifier" along with a "version number". Encoding details should be left up to individual token implementations. When any onchain action occurs that changes a dynamic token's metadata (on or offchain), the token contract MUST emit a transfer event for the current `versionedTokenId` from the current owner to the null address (i.e., "burning" the old token). It also then MUST emit a transfer event of an updated `versionedTokenId` (which encodes the new "version number" and the same "identifier") from the null address to the original owner. The actual encoded token "identifier" MUST not change, and the encoded "version number" MUST change. @@ -44,13 +45,8 @@ It MUST NOT revert if the encoded "version number" is incorrect or outdated. Thi Implementation details about storage and retrieval of versioned token IDs SHOULD be left up to individual implementations. -Since some NFT marketplaces allow for bulk-signing of up to millions of orders, token developers who anticipate many metadata updates for their token SHOULD make individual token "version numbers" non-incremental but monotonically increasing. They SHOULD use a method of deriving new "version numbers" that makes it difficult or impossible to anticipate future `versionedTokenIds` far in advance, in order to make bulk signature phishing impractical. - -As an example, one method would be to use the current BLOCKHASH or PREVRANDAO to increment the current version number, truncated to the desired number of bits. While BLOCKHASH and PREVRANDAO are deterministic and able to be influenced, they are impractical to predict indefinitely far in advance, and are not easily influenced by a single actor. - - -### Changes to EIP-721 Methods -The following methods from EIP-721 MUST be updated to handle `versionedTokenIds`: +### Changes to ERC-721 Methods +The following methods from ERC-721 MUST be updated to handle `versionedTokenIds`: ```solidity function approve(address, uint256) external; @@ -81,4 +77,16 @@ The standard ERC-721 `Transfer` event MUST be emitted when a token's metadata ch ## Rationale -The introduction of versioned token IDs allows for better and safer marketplace handling of NFTs with changing metadata, and ensures that only the latest "version" of a token is used in onchain transactions. The specified behavior in this EIP minimizes the changes to the EIP-721 standard while maintaining full backwards compatibility with all known marketplaces. \ No newline at end of file +The introduction of versioned token IDs allows for better and safer marketplace handling of NFTs with changing metadata, and ensures that only the latest "version" of a token is used in onchain transactions. The specified behavior in this EIP minimizes the changes to the ERC-721 standard while maintaining full backwards compatibility with all known marketplaces. + +## Security Considerations + + +Since some NFT marketplaces allow for bulk-signing of up to millions of orders, token developers who anticipate many metadata updates for their token SHOULD make individual token "version numbers" non-incremental but monotonically increasing. They SHOULD use a method of deriving new "version numbers" that makes it difficult or impossible to anticipate future `versionedTokenIds` far in advance, in order to make bulk signature phishing impractical. + +As an example, one method would be to use the current BLOCKHASH or PREVRANDAO to increment the current version number, truncated to the desired number of bits. While BLOCKHASH and PREVRANDAO are deterministic and able to be influenced, they are impractical to predict indefinitely far in advance, and are not easily influenced by a single actor. + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From ceb6115bd4697b1882244ab989761da984bb29a6 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 19 Apr 2023 13:36:49 -0700 Subject: [PATCH 4/5] merge summary and abstract --- EIPS/eip-6912.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/EIPS/eip-6912.md b/EIPS/eip-6912.md index 822d8446b51c0e..4643b0232b292f 100644 --- a/EIPS/eip-6912.md +++ b/EIPS/eip-6912.md @@ -11,11 +11,10 @@ created: 2023-04-19 requires: 721 --- -## Simple Summary -This EIP proposes an extension to the [ERC-721](./eip-721.md) non-fungible token standard by introducing a Versioned TokenId standard for "dynamic" NFTs with on or offchain properties that may change over time. The new `versionedTokenId` is meant to track both the "identifier" of a token as well as its current "version" so that old outstanding orders and approvals for updated tokens are automatically invalidated. - ## Abstract -The key change this EIP makes to the ERC-721 standard is the introduction of Versioned TokenIds. A `uint256 versionedTokenId` MUST encode both the true token "identifier" along with a "version number". Encoding details should be left up to individual token implementations. +This EIP proposes an extension to the ERC-721 non-fungible token standard by introducing a Versioned TokenId standard for "dynamic" NFTs with on or offchain properties that may change over time. The new versionedTokenId is meant to track both the "identifier" of a token as well as its current "version" so that old outstanding orders and approvals for updated tokens are automatically invalidated. + +A `uint256 versionedTokenId` MUST encode both the true token "identifier" along with a "version number". Encoding details should be left up to individual token implementations. When any onchain action occurs that changes a dynamic token's metadata (on or offchain), the token contract MUST emit a transfer event for the current `versionedTokenId` from the current owner to the null address (i.e., "burning" the old token). It also then MUST emit a transfer event of an updated `versionedTokenId` (which encodes the new "version number" and the same "identifier") from the null address to the original owner. The actual encoded token "identifier" MUST not change, and the encoded "version number" MUST change. From e1169f6aa374934f2b039f28cc845e9a3de39e70 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 19 Apr 2023 13:38:31 -0700 Subject: [PATCH 5/5] remove ens --- EIPS/eip-6912.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-6912.md b/EIPS/eip-6912.md index 4643b0232b292f..3abf4e131f2e50 100644 --- a/EIPS/eip-6912.md +++ b/EIPS/eip-6912.md @@ -2,7 +2,7 @@ eip: 6912 title: Versioned TokenIDs for Dynamic NFTs description: A minimal, backwards-compatible specification for versioned token IDs for dynamic NFTs. -author: emo.eth (@jameswenzel) +author: James Wenzel (@jameswenzel) discussions-to: https://ethereum-magicians.org/t/eip-6912-versioned-tokenids-for-dynamic-nfts/13897 status: Draft type: Standards Track