CIP - NFT Metadata Standard

Just a side note. You can have real NFT with hundred tokens. For example your apartment ownership, in which the tokens represent the precentage of your share.

The issue with the metadata, unlike in Plutus contract, is that they do not and I think cannot not keep/track the state without processing the relevant transactions, which is very computationally expensive. That is one of the other reasons why we need metadata server.

I highly recommend you guys to read the relevant research papers, starting with, UTXOma, EUTXO and EUTXOma papers. You can find them in IOHK research library.

Hello. Can anyone provide insight as to how to SpaceBudz URLs are populating in pool.pm/tokens? When you click on the image of the SpaceBud it actually goes to their website and page. I tried looking for/at their metadata but did not see anything in there that is triggering that?

1 Like

The linking is a pool.pm feature, it’s not in the metadata.

AH! Got it. Thank you! One more “dumb” question. In pool.pm I am seeing the actual ipfs image appear on the left side under “Mint” column for some tokens. How is this being done? I thought this image gets pulled from metadata which only gets attached at the point of a send transaction (hence appearing on the right side).

Does that make sense?

The metadata is being attached to the minting transaction (or forging). Check the beginning of the discussion here.

What about creating numbered editions, where you create 100 of each in a series - you want the series to be grouped but also the ability to know which numbered item you own. Common in numbered prints of artwork etc.

I didn’t see this mentioned in the thread yet, apologies if it’s covered :slight_smile:

Thinking about doing a Twitter Spaces for fun and ideation if you’re interested? https://twitter.com/benohanlon/status/1380181351610130436?s=20

CC @Spork @linconvidal @mcvetyty @_ilap @SebastienGllmt

3 Likes

The 721 label would be a nice standard to use for the NFT specifically, it is the same schema I used already on my first run of native-assets.

I love the idea of standards, but I think we have to be careful making this official as is. Thinking in terms of ethereum 721 to cardano as noted we have to be careful not to pigeon hole ourselves into a box.

If natively metadata is tied to a transaction, why should we be standardized to tie our NFTs to a single label all together? There is no need if we follow the asset itself. Especially from a spoofing perspective, when we query the 721 label, we’ll still be required to backtrace to verify that it’s valid anyway.

Querying ‘assets’ is simple enough and then a ‘standard’ label that says the type of asset is all we need to filter. Requiring we all chose the same 721 label should not be necessary. The rest sounds great, the convention of having the other standard json fields like name and whatnot.

Overall to me setting standards is kinda like least privileges, let’s go with the minimal standardization to get the job done, then let the community free-for-all the rest.

1 Like

I like the idea of a minimal standard that folks can adapt as they see fit. In analyzing the minting transactions and metadata currently on mainnet, I see that over half of the tokens conform to the following metadata pattern:

{
  "721" : {
    "<policy hash>" : {
      "<asset name>" : {
        . . .
      }
      . . .
    }
    . . .
  }
}

Among these “conforming” tokens, there is the following prevalence of JSON keys describing the asset:

JSON Key Prevalence [%]
name 92.65
image 92.26
type 51.04
description 50.73
properties 49.75
tags 49.65
value 49.64
key 49.63
creator 49.63
publisher 38.57
id 32.76
version 32.56
copyright 32.03
ipfs 6.53
url 6.52
tokens 6.51
policyId 6.51
asset 6.51
cnftFormatVersion 6.50
mimeType 4.21
assetHash 4.21

Below I’ve summarized the statistics (filtered for brevity) for minting metadata of NFTs currently on the blockchain. One important item I find noticeably missing is that almost none of the metadata has a link (IPFS or otherwise) to the monetary policy script (not just its hash): without access to view that script, it is impossible to audit the NFT to verify that it really is an NFT (i.e., that there is only one and that no more can ever be minted).

Token Statistics

Metric Value
Distinct Policies 1328
Distinct Assets 30956
Pseudo-NFTs 27993
NFTs 27726
NFTs with Minting Metadata 27785
Conforming NFTs (see above) 16655

(In the above, “pseudo-NFTs” are tokens that currently have one in existence, but previously had more than one that were then burned.)

Prevalence of Metadata Keys in NFT Minting

Metadata Key NFTs
721 27146
0 440
787084 85
1 22
815159 18

Prevalence of JSON Keys in NFT Minting Metadata

JSON Key Prevalence [%]
name 95.59
image 95.36
arweaveId 37.95
type 36.85
traits 36.10
description 31.30
properties 30.47
tags 30.41
value 30.39
key 30.39
creator 30.37
publisher 23.98
id 20.55
version 20.35
copyright 20.08
ipfs 4.29
url 3.91
tokens 3.91
asset 3.91
policyId 3.90
cnftFormatVersion 3.90
mimeType 2.52
longDescription 2.52
assetType 2.52
assetHash 2.52
assetDescription 2.52
artistName 2.52
gallery 2.51
collectionName 2.15
longitude 2.12
latitude 2.12
location 0.40
color 0.37
Rarity 0.35
Copyright 0.35
collection 0.34
attributes 0.34
3 Likes

This would definitely make the NFT more trustworthy, but my question is, where do you append the policy in the metadata. Just in the first mint transaction with the policy or in all to be consistent. Imagine like with SpaceBudz appending it to each transaction. It’s a little bit redundant.
Another cool way is to have something like etherscan.io on ethereum where you can upload you smart contract in order to verify it. The same could be done with minting policy on cardano, where explorers give the ability to upload it to make a project legit.

2 Likes

That’s a good question. I think just once in the first mint transaction would be sufficient, and just a pointer to where a copy of the script resides on IPFS would work. (Some folks are already doing that.) The audit process would be to study the script, and also verify that its hash matches the policy ID.

Yes, I imagine that something like etherscan.io’s storage of contracts might emerge, especially with the advent of Plutus. Also note that the Cardano Token Registry document includes a provision for storing the script.

Using dynamic data in json tag names makes parsing more difficult since you can’t just build structures and let the deserializer do all the work. Would consider something like

"policy": {
  "hash": "<policy hash>",
  "asset": {
    "name": "<asset name>",
1 Like

The problem with this one is it would destroy the purpose of multiple token mints a little bit and would take up way more storage. It’s harder to retrieve the correct metadata then:

{"policy": {
  "hash": "<policy hash>",
  "asset": {
    "name": "<asset name>",
   },
  "asset1": {
    "name": "<asset name1>",
   }
 },
 "policy1": {
  "hash": "<policy hash1>",
  ...
 }
}

The policy and asset keys would need to be indexed or named differently. That’s way harder to retrieve and makes it less flexible.

2 Likes

Thanks for the standard proposal! I’m using it now!

Using a copyright stamp, why wouldn’t NFT images just have the policy ID and asset name as a text copyright footer in small print at the bottom of the image. this information is known prior to the minting transaction itself. So the IPFS link in the metadata is the hashed image with copyright. I would think this better ties the image and the owner’s rights. Image copies and manipulations could be better identified.

FYI, I’ve been embedding IPTC metadata into NFT images on IPFS. In addition to the using the Copyright Notice, Object Name, and Contact fields, I’ve put the assetID into the Unique Document ID field.

1 Like

Hi Guys. Just joined the party and and am going to conform my metadata to @cardanobits & (@bpool amendment) shown above.

My NFT site (infected-marshies.com) will feature a few NFTs but mostly highly limited (editions of 8 for example) fungiable tokens.

For posterity sake can I take the schema above and assume, since we copied ERC721 for the top level key “721” logic would follow that fungiable tokens take “20” as an integer key i.e both would look like the following…

  "721" : {
    "<policy hash>" : {
      "<asset name>" : {
        "type": "NFT",
        "definition": {
            "name": "NFT_NAME",
            "description": "NFT_DESCRIPTION",
            "tags": [
                "TAG_1_NAME", 
                "TAG_N_NAME"
            ],
        ...


        {
            
"20" : {
    "<policy hash>" : {
      "<asset name>" : {
        "type": "FT",
        "definition": {
            "name": "FT_NAME",
            "description": "FT_DESCRIPTION",
            "tags": [
                "TAG_1_NAME", 
                "TAG_N_NAME"
            ],
        ...

I’m conflicted with this, mostly because Cardano so elegantly makes NFT’s so similar to FT’s (with simply a value of 1) and it seems a shame to use two different top level keys to make the NFT/FT distinction , yet at the same time i find myself uncomfortable using “721” for hopefully obvious reasons. I appreciate the good intentions but seems like ethereum’s more drastic distinction between the two has bled over to cardano with the “721” integer but feel free to flame me and call me too much of a purist and maybe just use “721” but change the type to FT instead? What do you guys think?

Is the 721 label not up for debate still? We have a massive space of 18,446,744,073,709,551,615 possible values and 721 = “NFT” is waaaaay too broad to keep under a single space. What’s the point of this many labels, if we’re going to have these huge categories?

We haven’t even begun to really expand on the potential uses, so it feels a little premature. Why not just use the ‘type’ field that you all came up with? And let the labels figure themselves out? Adding @alessandro, @bwbush and @cardanobits amazing job on all of this, so don’t get me wrong, this is all amazing work ya’ll are doing!

1 Like