HomeEIPs
EIPsERC-1948
ERC-1948

Non-fungible Data Token

StagnantStandards Track: ERC
Created: 2019-04-18
Requires: EIP-721
Johann Barbie (@johannbarbie), Ben Bollen <ben@ost.com>, pinkiebell (@pinkiebell)
DiscussionsOriginal linkEdit
1 min read

The ERC-1948 proposal suggests extending non-fungible tokens (NFTs) with the ability to store dynamic data that can change during the token's lifetime. This is useful for NFT use-cases such as cryptokitties that can change color, intellectual property tokens that encode rights holders, and tokens that store data to transport them across chains. The existing metadata standard does not allow for dynamic data to be modified after minting, so this proposal aims to standardize tokens with dynamic data.

The proposal adds a 32-byte data field to NFTs and includes read and write functions to access and update the data, respectively. The write function can only be called by the owner of the token. An event is emitted every time the data updates, including the previous and new values.

The motivation behind this proposal is to enable interactions with bridges for side-chains like xDAI or Plasma chains and to enable protocols that build on data tokens like distributed breeding.

In addition to the ERC-1948 proposal, there is also a mention of a semi-fungible token that combines the quantitative features of ERC-20 with the qualitative attributes of ERC-721. This type of token would be backwards-compatible with ERC-721 and could lead to faster adoption.

Video
Anyone may contribute to propose contents.
Go propose
Original

Simple Summary

Some NFT use-cases require to have dynamic data associated with a non-fungible token that can change during its lifetime. 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 metadata 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.

Motivation

The proposal is made to standardize on tokens with dynamic data. Interactions with bridges for side-chains like xDAI or Plasma chains will profit from the ability to use such tokens. Protocols that build on data tokens like distributed breeding will be enabled.

Specification

An extension of ERC-721 interface with the following functions and events is suggested:

pragma solidity ^0.5.2; /** * @dev Interface of the ERC1948 contract. */ interface IERC1948 { /** * @dev Emitted when `oldData` is replaced with `newData` in storage of `tokenId`. * * Note that `oldData` or `newData` may be empty bytes. */ event DataUpdated(uint256 indexed tokenId, bytes32 oldData, bytes32 newData); /** * @dev Reads the data of a specified token. Returns the current data in * storage of `tokenId`. * * @param tokenId The token to read the data off. * * @return A bytes32 representing the current data stored in the token. */ function readData(uint256 tokenId) external view returns (bytes32); /** * @dev Updates the data of a specified token. Writes `newData` into storage * of `tokenId`. * * @param tokenId The token to write data to. * @param newData The data to be written to the token. * * Emits a `DataUpdated` event. */ function writeData(uint256 tokenId, bytes32 newData) external; }

Rationale

The suggested data field in the NFT is used either for storing data directly, like a counter or address. If more data is required the implementer should fall back to authenticated data structures, like merkle- or patricia-trees.

The proposal for this ERC stems from the distributed breeding proposal to allow better integration of NFTs across side-chains. ost.com, Skale, POA, and LeapDAO have been part of the discussion.

Backwards Compatibility

šŸ¤·ā€ā™‚ļø No related proposals are known to the author, hence no backwards compatibility to consider.

Test Cases

Simple happy test:

const ERC1948 = artifacts.require('./ERC1948.sol'); contract('ERC1948', (accounts) => { const firstTokenId = 100; const empty = '0x0000000000000000000000000000000000000000000000000000000000000000'; const data = '0x0101010101010101010101010101010101010101010101010101010101010101'; let dataToken; beforeEach(async () => { dataToken = await ERC1948.new(); await dataToken.mint(accounts[0], firstTokenId); }); it('should allow to write and read', async () => { let rsp = await dataToken.readData(firstTokenId); assert.equal(rsp, empty); await dataToken.writeData(firstTokenId, data); rsp = await dataToken.readData(firstTokenId); assert.equal(rsp, data); }); });

Implementation

An example implementation of the interface in solidity would look like this:

/** * @dev Implementation of ERC721 token and the `IERC1948` interface. * * ERC1948 is a non-fungible token (NFT) extended with the ability to store * dynamic data. The data is a bytes32 field for each tokenId. If 32 bytes * do not suffice to store the data, an authenticated data structure (hash or * merkle tree) shall be used. */ contract ERC1948 is IERC1948, ERC721 { mapping(uint256 => bytes32) data; /** * @dev See `IERC1948.readData`. * * Requirements: * * - `tokenId` needs to exist. */ function readData(uint256 tokenId) external view returns (bytes32) { require(_exists(tokenId)); return data[tokenId]; } /** * @dev See `IERC1948.writeData`. * * Requirements: * * - `msg.sender` needs to be owner of `tokenId`. */ function writeData(uint256 tokenId, bytes32 newData) external { require(msg.sender == ownerOf(tokenId)); emit DataUpdated(tokenId, data[tokenId], newData); data[tokenId] = newData; } }

Copyright and related rights waived via CC0.

Further reading
Anyone may contribute to propose contents.
Go propose
Adopted by projects
Anyone may contribute to propose contents.
Go propose

Not miss a beat of EIPs' update?

Subscribe EIPs Fun to receive the latest updates of EIPs Good for Buidlers to follow up.

View all
Serve Ethereum Builders, Scale the Community.
Resources
GitHub
Supported by