The Public On-Chain Non-Fungible Token Attributes Repository standard provides the ability for ERC-721 and ERC-1155 compatible tokens to store their attributes on-chain available to any external smart contract interacting with them.
This proposal introduces the ability to assign attributes to NFTs in a public non-gated repository smart contract that is accessible at the same address in all of the networks. The repository smart contract is designed to be a common-good repository, meaning that it can be used by any ERC-721 or ERC-1155 compatible token.
With NFTs being a widespread form of tokens in the Ethereum ecosystem and being used for a variety of use cases, it is time to standardize additional utility for them. Having the ability to store token's attributes on chain allows for greater utility of tokens as it fosters cross-collection interactivity and provides perpetual store of attributes.
This ERC introduces new utilities for ERC-721 and ERC-1155 based tokens in the following areas:
Storing attributes on-chain in a predictable format allows for cross-collection interactivity. This means that the attributes of a token can be used by any external smart contract without the need for the token to be aware of the external smart contract.
For example, a token can represent a game character with its set of attributes and can be used in an unrelated game with the same stats without the need for retrieving these attributes from an off-chain source. This ensures that the data the game is using is legitimate and not tampered with in order to gain an advantage.
Standardized on-chain token attributes allow for their perpetual storage.
With off-chain attributes storage, the attributes are only available as long as the off-chain storage is available. If the storage is taken down, the attributes are lost. With on-chain attributes storage, the attributes are available as long as the blockchain is available. This increases the value of the token as it ensures that the attributes are available for as long as the token exists.
On-Chain storage of token attributes allows for the token to evolve over time. Owner's actions can impact the attributes of the token. Since the attributes are stored on chain, the smart contract has the ability to modify the attribute once certain thresholds are met. This allows for token to become more interactive and reflect owner's dedication and effort.
On-Chain storage of token attributes allows for dynamic state tracking. The attributes can be used to track the state of the token and its owner. This allows for the token to be used in a variety of use cases. One such use case is supply chains; the token can represent a product and its attributes can be used to track the state of the product as it transitions from pending, shipped, delivered, etc.
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.
In addition to the interface we propose that collection owers SHOULD be able to set the schema for the attributes of their collection. We distinguish between 2 types: token attributes and collection attributes. The latter are the attributes that are shared by all tokens in the collection, they can be retrieved and set by using the max uint256 value as tokenId.
For each attribute we specify the following fields: name, description, type, display_name, display_type, decimals, min_value, max_value, conditional_value, modifiers and multi_storage. Only name and type are required. For more details on the fields, please refer to the [JSON schema] available collection-metadata-schema.json, with an example available at collection-metadata-example.json.
The reasoning for conditional_value, modifiers and multi_storage will be discussed in the rationale section.
The message to be signed by the setter in order for the attribute setting to be submitted by someone else is formatted as follows:
The values passed when generating the message to be signed are:
DOMAIN_SEPARATOR - The domain separator of the Attribute repository smart contractMETHOD_TYPEHASH - The typehash of the method being called. The supported values, depending on the method are:
SET_UINT_ATTRIBUTE_TYPEHASH - Used for setting uint attributesSET_STRING_ATTRIBUTE_TYPEHASH - Used for setting string attributesSET_BOOL_ATTRIBUTE_TYPEHASH - Used for setting bool attributesSET_BYTES_ATTRIBUTE_TYPEHASH - Used for setting bytes attributesSET_ADDRESS_ATTRIBUTE_TYPEHASH - Used for setting address attributescollection - Address of the collection containing the token receiving the attributetokenId - ID of the token receiving the attributekey - The attribute keyvalue - The attribute value of the appropriate typedeadline - UNIX timestamp of the deadline for the signature to be submitted. The signed message submitted after the deadline MUST be rejectedThe DOMAIN_SEPARATOR is generated as follows:
The SET_UINT_ATTRIBUTE_TYPEHASH is generated as follows:
The SET_STRING_ATTRIBUTE_TYPEHASH is generated as follows:
The SET_BOOL_ATTRIBUTE_TYPEHASH is generated as follows:
The SET_BYTES_ATTRIBUTE_TYPEHASH is generated as follows:
The SET_ADDRESS_ATTRIBUTE_TYPEHASH is generated as follows:
Each chain, that the Attributes repository smart contract is deployed in, will have a different DOMAIN_SEPARATOR value due to chain IDs being different.
The address of the Emotable repository smart contract is designed to resemble the function it serves. It starts with 0xA77B75 which is the abstract representation of ATTBTS. The address is TBD.
Designing the proposal, we considered the following questions:
The Attributes repository standard is fully compatible with ERC-721 and ERC-1155 and with the robust tooling available for implementations of ERC-721 as well as with the existing ERC-721 infrastructure.
Tests are included in attributesRepository.ts.
To run them in terminal, you can use the following commands:
The proposal does not envision handling any form of assets from the user, so the assets should not be at risk when interacting with an Attributes repository.
The ability to use ECDSA signatures to set attributes on someone else's behalf introduces the risk of a replay attack, which the format of the message to be signed guards against. The DOMAIN_SEPARATOR used in the message to be signed is unique to the repository smart contract of the chain it is deployed on. This means that the signature is invalid on any other chain and the attributes repositories deployed on them should revert the operation if a replay attack is attempted.
Another thing to consider is the ability of presigned message reuse. Since the message includes the signature validity deadline, the message can be reused any number of times before the deadline is reached. The proposal only allows for a single value for a given key to be set, so the presigned message can not be abused to further modify the attribute value. However, if the service using the repository relies on the ability to revert or modify the attribute after certain actions, a valid presigned message can be used to re-assign the attribute of the token. We suggest that the services using the repository in cnjunction with presigned messages use deadlines that invalidate presigned messages after a reasonalby short period of time.
Caution is advised when dealing with non-audited contracts.
Copyright and related rights waived via CC0.