Align token metadata in ICRC-7 with ICRC-3 history blocks

@benji @skilesare @dieter.sommer @cryptoschindler , developers on this community.

In the ICRC-7 standard, the icrc7_token_metadata method returns metadata for a given set of tokens. The 7mint block schema also contains this same metadata.

This results in an issue, where for any given token the method could return metadata that is different from the block schema metadata. Which means the history blocks cannot recreate a given ledger state at any point in time.

To resolve this issue I had the following ideas in mind. Please respond to this forum post and poll to indicate which idea would have your preference, which ideas you’d object to and if you have any other ideas.

1. Make metadata static

Update the spec to require the metadata of a token to never change. For dynamic metadata, another extension standard like ICRC-60 would add support for dynamic metadata with another method and block schema at a later time.

Optionally, the spec could be defined as SHOULD instead of MUST to provide for a stopgap that allows for dynamic metadata until a standard for dynamic metadata is available and can be migrated to.

Since static metadata doesn’t change, this data can be indexed without the need to ever update this data again. Though since the ICRC-3 history is a single chain, an indexer could just as well process metadata changes since it already need to keep track of mints and burns anyway.

2. Add metadata changed block

Update the spec to add an additional block for metadata changes. Optionally, the collection metadata could have an entry to indicate that token metadata is dynamic or static.

This would mean though that a ledger can only have static or dynamic token metadata but not both. One example where you might want both could be an NFT token of a game character that has base stats that never change and dynamic stats that change e.g. level.

On the other hand, nothing prevents a ledger implementation to go out of spec and modify token metadata anyway even though it indicates the data is static. So maybe the collection metadata to indicate this isn’t really needed and users must rely on what the developer communicates regarding this, possibly verifying this by checking the ledger implementation and deployed WASM hash to verify which metadata is dynamic and which static.

3. Remove metadata from mint block

Update spec to remove metadata from mint block. This would mean that the metadata could be any value at any time and is not tracked in canister history. Personally I wouldn’t really opt for this option, making it untracked makes it similar to off-chain metadata, you can’t track it and rely on it on-chain.

4. Other

Please let me know in the comments below if you have any other ideas regarding this.

Poll to indicate preference

  • 1 Make metadata static
  • 2 Add metadata changed block
  • 3 Remove metadata from mint block
  • 4 Other, please respond below with any ideas
0 voters
1 Like

Personally, at this moment, I’m leaning towards 2 Add metadata changed block.

Most importantly, it’s a small change that makes the base standard support all use cases without the need for any extensions.

The concept of static token metadata can be communicated in different ways:

  • All token metadata is static (can be part of this standard):
    • ICRC-3 supported block schemas does not return metadata changed block
    • Collection metadata entry that indicates that token metadata is static
  • Some token metadata is static (can be part of another standard):
    • Token metadata key prefix/suffix that indicates the key value is static

Initially I was leaning towards 1 Make metadata static, but since an indexer needs to loop over all ICRC-3 blocks anyway to keep track of mints and burns, I can’t think of a use-case that would require two metadata variants with both static and dynamic methods.

Nonetheless, extension standards are still needed to define how token metadata could be updated with a method for self minting tools, standardize keys and values for e.g. token name and image, etc.

1 Like

I was thinking about this over the week.

What I was doing with my implementations that update meta data was adding an another mint block with the same tokens but different metadata. This is obviously confusing, so having an update block would be fine.

For simplicity and getting the standard out, I think it would also be OK to say that the metadata SHOULD be static unless another ICRC extension is used that adds dynamic metadata.

For example, see ICRC-60 NFT Working Group - Next Steps - ICRC-8, ICRC-56, ICRC-59, ICRC-60

So 2 or 4. :grinning:

1 Like

After thinking more about this, I’d say both 1 and 2 can be acceptable solutions for ICRC-7, but 3 is not an option as it essentially removes the key part of the NFT (e.g., the real-world asset being owned) from the ledger history. Adopting 3 would mean to dismantle one of the key properties of NFTs.

Option 1 would be a simple change, but we would not have dynamic NFTs yet with ICRC-7.

Option 2 is nice in terms of solving the update of metadata, but it would mean that metadata is either static or dynamic, unless we add another method for dynamic metadata. The difficult part here is probably to find a good tradeoff that works well for ICRC-7 and does not constrain us in the future.

Composability / consistency with the upcoming general NFT standards that are in the process of being drafted is very important here.

It’s hard to opt for an option 1 or 2 currently without going deeper into the issue and looking at all implications.

This discussion is really at the core of the NFT standard, so I suggest we spend some time in tomorrow’s WG meeting to further discuss it. If we get this wrong, it may harm the standard, if we get it right, we may unlock lots of goodness w.r.t. NFTs on ICP.

@sea-snake, thanks a lot for the detailed write up and for triggering this important discussion. Thought more about it and for me it is clear now that we should go for Option 2 for multiple reasons.

  • ICRC-7 has always been intended to be a simple NFT standard, but still it should comprise all necessary functionality, and one of those is dynamic metadata. Not having dynamic metadata in this basic standard would not be true to the idea of a basic standard on ICP, as dynamicity of metadata is one of the key things ICP enables, compared to other chains, where this is much more tedious…
  • We are already very close to this simple, yet powerful standard, and explicitly defining the basics for dynamic NFTs is one small missing step to reach that completely.
  • People with basic demands for dynamic NFTs will be able to just just ICRC-7/-37, those with more elaborate requirements will implement the full-blown ICRC-60, which is more complex, but also (much) more powerful. But I think we should not force everyone who has basic needs for dynamic NFTs to go for the full ICRC-60 as it’s also much more complex to implement.

Thinking about this more, I need to disagree that both cannot be combined. I think we can have both static and dynamic metadata without any issues. The single Value element can contain a top-level Map which contains a static Value and a dynamic Value, and those Values contain the static and dynamic metadata, respectively. The ledger must never change the static metadata, by can change the dynamic metadata. Having both classes of metadata in one Value should not be constraining. We can make this approach a best practice and make it a SHOULD requirement, so people can still deviate if they want.

Both on minting and update, the full Value MUST be hashed to guarantee full data integrity. This makes the updates to the dynamic parts fully traceable and would detect tampering with the static part.

Ledgers that only have static metadata do not need this, but MAY just go with any Value representation that fits their need, but they MAY also follow this scheme with the dynamic part being empty.

ICRC-3 Block Schema

ICRC-7 needs to extend the block schema with a type=7update for the blocks for updating metadata. This block would contain an element tx defined as follows:

  • it MUST contain a field tx.tid with the token id
  • it MUST contain a field tx.metadata with the metadata or hash thereof
  • it MAY contain a field tx.from with an account who initiated the update

The tx.metadata MUST contain the (hash of the) full Value with both static and dynamic metadata in order to have full traceability of changes and prevent static metadata from being tampered with.

Rationale

This approach would be a very simple, yet powerful foundation to build many NFT-based applications. Not doing this imposes an undue constraint that may hamper adoption as people would be forced to go with a much harder-to-implement add-on standard to get dynamic NFT functionality. Those who need it, will still implement the add-on, but not everyone should be forced to do it.

Also conceptually, this approach makes lots of sense because of the ICRC-7 metadata representation using the Value type resembles the ICRC-3 technical Value representation as the most canonical realization of the metadata. Any add-on standards may use more complex representations like ICRC-16 for additional functionality. But those, for whom the simple ICRC-7 representation is sufficient, already get an out-of-the-box solution for their needs without needing to implement a much more complex machinery.

Conclusion

After more thinking about this, I would claim that following Option 2 for supporting dynamic NFT metadata, in addition to static metadata, is the right and natural way to go forward with. It provides a nice and simple framework for NFTs on ICP for many users with simple requirements to dynamic NFTs. People with more elaborate requirements can revert to implementing ICRC-60, which is more more comprehensive.

Let’s discuss this in the Working Group meeting tomorrow!

1 Like

2 and 4. :grinning:

2 now with a metadata update block.
4 later with the ICRC-60 proposal.