ERC-1948: Non-fungible Data Token

tl;dr;

Some use-cases require to have dynamic data associated with a non-fungible token that can change during its live-time. Examples for dynamic data:

  • cryptokitties that can change color
  • intellectual property tokens that encode rights holders
  • tokens that store data to transport them across chains

The existing meta-data standard does not suffice as data can only be set at minting time and not modified later.

Abstract

Non-fungible tokens (NFTs) are extended with the ability to store dynamic data. A 32 bytes data field is added and a read function allows to access it. The write function allows to update it, if the caller is the owner of the token. An event is emitted every time the data updates and the previous and new value is emitted in it.

4 Likes

Copied from the draft:

Non-fungible tokens (NFTs) are extended with the ability to store dynamic data. A 32 bytes data field is added and a read function allows to access it. The write function allows to update it, if the caller is the owner of the token. An event is emitted every time the data updates and the previous and new value is emitted in it.

pragma solidity ^0.5.2;
interface IERC1948 {
  event DataUpdated(uint256 indexed tokenId, bytes32 oldData, bytes32 newData);
  function readData(uint256 _tokenId) public view returns (bytes32);
  function writeData(uint256 _tokenId, bytes32 _newData) public;
}

Interesting, this is very similar to what we (@decanus @lrettig @amyjung & me) did with Radical Bodies: protocol/contracts/IERC721VariableMetadata.sol at master · RadicalBodies/protocol · GitHub

We called it “variable metadata”, another hash URL to variable data:

pragma solidity ^0.5.0;
interface IERC721VariableMetadata {
  // Retrieve the currently set variable metadata.
  function variableMetadataURI(uint256 tokenId) external view returns (string);
  // Replace the variable metadata.
  function replaceVariableMetadataURI(uint256 tokenId, string metadataURI) external;
}

I wonder if it would be possible to reconcile the two proposals by introducing a “data type” field?

3 Likes

good to see that there are more use-cases for variable data. I think that is a great idea to merge these.

i’m not particularly keen about the string data type, as it is not represented efficiently, and i don’t want to use the chain to store data. how about this proposal:

interface IERC721VariableData {
  event DataUpdated(uint256 indexed tokenId, bytes32 oldData, bytes32 newData, uint256 dataType);
  function getDataType(uint256 _tokenId) external view returns (uint256);
  // Retrieve the currently set variable data.
  function readData(uint256 _tokenId) external view returns (uint256 type, bytes32 data);
  // Replace the variable data.
  function writeData(uint256 _tokenId, bytes32 _newData) external;
}

Here I assume:

  • data type is set at token minting, and does not change after.
  • I see 3 types we could use right away:
    • type 0 - pure data, the token stores a single uint256, or sha256 hash
    • type 1 - the token stores a hash of a string (to implement the URI). string needs to be provided in msg.Data and verified against hash
    • type 2 - the token stores the root of a merkle tree, proofs need to be provided with msg.data