GitHub Logo HIP-657: Mutable metadata fields for dynamic NFTs

Author Patches Punks
Working Group Jason Fabritz, Sean Cuscus, Cooper Kunz, May Chan, Burstall Stowerling, Ian Holsman, Ashe Oro, Michael Garber, Paul Sullivan
Discussions-To https://github.com/hashgraph/hedera-improvement-proposal/discussions/607
Status Accepted
Needs Council Approval Yes
Review period ends Tue, 28 Feb 2023 07:00:00 +0000
Type Standards Track
Category Core
Created 2023-01-04
Updated 2024-02-02

Abstract

Currently, there is no native way to update the metadata of a non-fungible token (NFT) on the Hedera network. This HIP proposes the creation of a new key called the METADATA key, which will allow updating NFT metadata. This will provide the Hedera network with functional parity with other networks and enable developers to create dynamic NFTs with new interactions.

Motivation

Dynamic NFTs are a valuable addition to the world of non-fungible tokens because they allow for more interactive and immersive experiences. With the ability to update the metadata of an NFT, developers can create game pieces that gain new equipment and stats, legal agreements that reflect changing parameters, or even NFTs that update their images based on the time of day. Dynamic NFTs also open up the possibility for NFTs to be used in a wider range of industries and applications, such as supply chain tracking, real estate, among others. The potential for dynamic NFTs is numerous, and their introduction will greatly enhance the capabilities of the NFT ecosystem.

Rationale

To address this issue, the proposed solution is to create a new key called the METADATA key. This key will allow NFTs in a collection to update their metadata.

The use of the METADATA key to update NFT metadata will not affect the functionality of existing NFTs on the Hedera Network. It will be available for new and existing NFTs.

  • HIP-765 will add metadata for non-fungible token classes.
  • HIP-646 will add metadata for fungible tokens.

The METADATA key will also allow updating the metadata introduced by these HIPs.

User stories

  • As a creator of NFTs, I want to be able to update the metadata of an NFT in my collection so that I can add new information or make changes to the existing metadata.

  • As a creator of NFTs, I want to be able to update the metadata of an NFT while leaving an auditable on-chain history of when the update happened and which key was used to sign for the update action so that I can retain as much transparency as possible.

  • As a creator of NFTs, I want to use IPFS to manage my dynamic NFT’s metadata so that I don’t have to use a centralized file storage solution to enable the ability to edit.

  • As a developer building applications on top of the Hedera Network, I want the ability to update the metadata of NFTs so that I can create dynamic NFTs and build more advanced use cases.

Specification

The METADATA key will be a new key that allows for updating the metadata of an NFT in a new UpdateNfts transaction.

The UpdateNfts transaction should accept the following parameters:

  • nft_id: the identifier (NftID) of the NFT to be updated
  • metadata: the new metadata for the NFT

Example transaction:

const transaction = await TokenUpdateNfts()
     .setTokenId(tokenId)
     .setSerialNumbers([nft1, nft2, nft3])
     .setMetadata(newMetadata)
     .sign(METADATAKEY)
     .execute(client);

Protobuf

message TokenUpdateNftsTransactionBody {
    /**
     * The token for which to update NFTs.
     */
    TokenID token = 1;

    /**
     * The list of serial numbers to be updated.
     */
    repeated int64 serialNumbers = 2;

    /**
     * The new metadata of the NFT(s)
     */
    google.protobuf.BytesValue metadata = 3;
}

TokenCreate and TokenUpdate should be updated to add this new metadata key

message TokenCreateTransactionBody {
...
    /**
     * The key which can change the metadata of a token definition or individual NFT.
     */
    Key metadata_key = 24;
}

message TokenUpdateTransactionBody {
...
    /**
     * The key which can change the metadata of a token definition or individual NFT.
     */
    Key metadata_key = 17;
}

Requirements: The NFT must exist on the Hedera network and should only be allowed to execute if it is signed by the new METADATA key. The new metadata must be a valid byte array limited to 100 bytes. The update must be made atomically and be recorded on the Hedera network.

TokenGetInfo will include the METADATA key in the response

message TokenInfo {

    [...]

    /**
     * The key which can change the metadata of a token definition or individual NFT.
     */
    Key metadata_key = 28;
}

Mirror Node Changes

Given the introduced metadata_key is applicable to the token type (fungible and non-fungible) and is used to manage both the metadata for the overall collection as well as that for individual NFTs, the REST API token level response is where the metadata key is returned and not for individual NFTs via /api/v1/tokens/{tokenId}/nfts/{serial}.

/api/v1/tokens/{tokenId}

For any token, the metadata_key is returned in the standard key format, along with the base64 encoded token/collection level metadata. If no metadata key is set for the token, then "metadata_key": null is returned.

{
    "admin_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    },
    "auto_renew_account": "0.0.1020",
    "auto_renew_period": 6999999,
    "created_timestamp": "1706556543.894559367",
    "custom_fees": {
        "created_timestamp": "1706556543.894559367",
        "fixed_fees": [],
        "royalty_fees": []
    },
    "decimals": "0",
    "deleted": true,
    "expiry_timestamp": 1713556542894559367,
    "fee_schedule_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    },
    "freeze_default": false,
    "freeze_key": null,
    "initial_supply": "0",
    "kyc_key": null,
    "max_supply": "0",
    "memo": "Mirror Node acceptance test: 2024-01-29T19:29:03.525656Z Create token",
    "metadata": "VEVTVF9tZXRhZGF0YQ==",
    "metadata_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    },
    "modified_timestamp": "1706556543.894559367",
    "name": "non_fungible_name",
    "pause_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    },
    "pause_status": "UNPAUSED",
    "supply_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    },
    "supply_type": "INFINITE",
    "symbol": "non_fungible",
    "token_id": "0.0.1036",
    "total_supply": "0",
    "treasury_account_id": "0.0.1020",
    "type": "NON_FUNGIBLE_UNIQUE",
    "wipe_key": {
        "_type": "ED25519",
        "key": "0aa8e21064c61eab86e2a9c164565b4e7a9a4146106e0a6cd03a8c395a110e92"
    }
}

Backwards Compatibility

The addition of the METADATA key will not affect the functionality of existing NFTs on the Hedera Network because it will be available for use on new NFTs.

Security Implications

The use of the METADATA key and creation of a NftMetadataUpdate transaction will not introduce any new security concerns.

How to Teach This

TBD

Reference Implementation

The reference implementation must be complete before any HIP is given the status of “Final”. The final implementation must include test code and documentation.

Rejected Ideas

Open Issues

There are currently no open issues with this proposal.

References

TBD

Copyright/license

This document is licensed under the Apache License, Version 2.0 – see LICENSE or (https://www.apache.org/licenses/LICENSE-2.0)

Citation

Please cite this document as: