CIP - NFT Metadata Standard

We agree that tags and rights would be good to have in the global schema. I think more discussion could be had around how these rights are expressed, i.e. an IPFS file similar to how Github repositories contain a LICENSE file?

It does cause issues of modifying the rights to an NFT yes, though I’m unsure how common it is for artists to change the rights of an item after having sold it. Ideally rights are set before the sale, and should really be cemented for future sales. Thoughts anyone?

Agreed, collaborators is a platform specificity that we want to include which will fit perfectly into <other properties> field.

@cardanobits, this format looks good to us, if we can agree on the issue of rights. Finally, do we have plans to limit the nesting of the other_properties field? I.e. should something like this be supported:

...
"properties": {
                "PROP_1_KEY":  { "Some": [ { "nested": "objects" }, { "more": "nested" }, { "etc": "etc" } ] },
                "PROP_N_KEY": "PROP_N_VALUE",
},

...

Thanks

Seems to me it would be beneficial to change the "file": "FILE_ID" from a string to an array, to accomodate NFTs that are made of many parts. Like so:

"files": [
    "FILE_1_ID",
    "FILE_N_ID"
]

@Lovada_Art I don’t see why it would be necessary to limit the nesting of the other_properties field. It permits arbitrary platform metadata to be inserted while still being conformant to the standard, so it is good to keep it as free as possible in my opinion.

Okay, this all makes sense to me, but if we want to make it escalable, i think we can have something like this so:

"MINTING_POLICY": { 
        "NFT_ID": {
            "name": "NFT_NAME",
            "description": "NFT_DESCRIPTION",
            "tags": [
                "TAG_1_NAME", 
                "TAG_N_NAME"
            ],
            "properties": {
                "PROP_1_KEY": "PROP_1_VALUE",
                "PROP_N_KEY": "PROP_N_VALUE",
            },
            "rights": {
                "PROP_1_KEY": "PROP_1_VALUE",
                "PROP_N_KEY": "PROP_N_VALUE",
            },
            "files": {
                "FILE_1": {
                    "mType": "MIME_TYPE",
                    "mHost": "HOST_PROTOCOL",
                    "bUrl": "BASE_URL",
                    "file": "FILE_ID"
                },
                "FILE_N": {
                    "mType": "MIME_TYPE",
                    "mHost": "HOST_PROTOCOL",
                    "bUrl": "BASE_URL",
                    "file": "FILE_ID"
                },
            },
        }
    }

In this way, we can have an extensible rights field, which could contain a file (using the same schema as the files, for each one) o key-value elements… depending on the type of rights you want to have in that NFT.

Also, I wouldn’t limit the nesting… since it’s a json, any platform can iterate it and draw the information, with dynamic fields.

2 Likes

So finnally, we do not have a way to add metadata to NFT?

+1 on piggybacking on RDF or already established vocabularies. Schema.org has a bunch that are used by HTML microdata standard. A very generic example, a Thing: Thing - Schema.org Type

4 Likes

Perhaps the metadata standard should include a pointer to the schema to which the metadata conforms. This would allow versioning and would support the varied use cases (virtual art, physical art, intellectual property, etc.) that will emerge. A token could even support multiple metadata standards (e.g., one for display in wallets, others for various NFT marketplaces) in cases where that was relevant and useful.

I also think that it is critical for a potential owner to be able to audit the script under which the token was minted, so a standard should provide some pathway to a verifiable copy of the script.

Well, my final proposal for this, in order to follow the standards and make this the most extensible:

{ 
    "policy": "POLICY_ID",
    "nft": {
        "name": "NFT_NAME",
        "description": "NFT_DESCRIPTION",
        "tags": [
            "TAG_1_NAME", 
            "TAG_N_NAME"
        ],
        "properties": [
            {
                "key": "PROP_1_KEY",
                "value": "PROP_1_VALUE"
            },
            {
                "key": "PROP_N_KEY",
                "value": "PROP_N_VALUE"
            }
        ],
        "rights": [
              {
                "key": "RIGHT_1_KEY",
                "value": "RIGHT_1_VALUE"
              },
              {
                "key": "RIGHT_N_KEY",
                "value": "RIGHT_N_VALUE"
              }
        ],
        "files": [
             {
                "name": "FILE_1_NAME",
                "mType": "MIME_TYPE",
                "mHost": "HOST_PROTOCOL",
                "bUrl": "BASE_URL",
                "file": "FILE_ID"
            },
            {
                "name": "FILE_N_NAME",
                "mType": "MIME_TYPE",
                "mHost": "HOST_PROTOCOL",
                "bUrl": "BASE_URL",
                "file": "FILE_ID"
            }
        ]
    }
}
5 Likes

Agreed, just wanted to clarify before people start adding heavily nested data. Developers of any NFT explorer type apps should just be aware that these fields may need to be flattened if displayed in a human readable form in their app, but it’s just an edge case we wanted to raise. Open is 100% better than restricted on that front.

@cardanobits, this schema looks great! We’re more than happy to work off that schema unless others object.

1 Like

Great! Feel free to reach me anytime for further discussion or help!

This thread has been really helpful to me, thanks guys.

I’m stuck with a problem though. I’m adding my images but they’re not showing in pool.pm (the only place that seems to show the image).

Is there a particular file type, size or expression i’m missing?

I’ve been tweeking the json file, at the moment it is;

@cardanobits this looking good but since we’re talking about Metadata standards why not make room for other standards not just NFT, e.g Oracle, etc. See my take below using what you’ve started

{ 
    "policy": "POLICY_ID",
    "type": "NFT",
    "definition": {
        "name": "NFT_NAME",
        "description": "NFT_DESCRIPTION",
        "tags": [
            "TAG_1_NAME", 
            "TAG_N_NAME"
        ],

I just added a “type” property for clarity and also for querying JSON field

SELECT * FROM tx_metadate WHERE json -> 'type' = 'NFT' and json -> 'policy' = 'SPACEBUSPOLICY' ;
3 Likes

Totally agree with that @bpool

The great thing about using ipfs is that the file address is the hash of the contents of the “rights” file so it is immutable/cemented (unlike http, where the filename is unrelated to the contents of the file). Any changes to the rights file will change its address on ipfs

1 Like

++ This is exactly the same Thing I was telling @v-almonacid the other day!

@killifish and me have been thinking to use/extend it for different token purposes not only limited to artwork.
We think it would make sense to create an standard around a minimal json-ld schema that would be stored as Cardano metadata and whose metadata graph is then extended with just one reference/entrypoint to objects that reside in the storage network (IPFS/Filecoin/Arweave/whatever). And the other way back, objects in the storage network would reference back to Cardano; that’s where my idea/PoC of having a standard URI to address Cardano metadata [0] came from. Something like cardano+metadata://$TX_ID?network=$NETWORK&key=$METADATUM_LABEL but fixing it to follow RFCs and being browser friendly. Read more about URI considerations on CIP-0013 [1] for stake/payment URLs developed by @SebastienGllmt and @COSDpool :slight_smile:

We think Ticket [2] is close to be a perfect representation of what an NFT is in the scope of Cardano metadata, and any system could add semantics to it using the same json-ld standard outside Cardano ledger. This [3] is what we are thinking to build from Gimbalabs [4] for an event ticketing system in this direction :slight_smile:

[0] GitHub - repsistance/cardano-meta-handler
[1] CIPs/CIP-0013.md at master · cardano-foundation/CIPs · GitHub
[2] Ticket - Schema.org Type
[3] create model/schema/db for events (#1) · Issues · gimbalabs / playground / event-ticketing · GitLab
[4] https://gimbalabs.com

6 Likes

That’s exactly why there are top level keys. I chose the 721 label to make clear that this one is NFT metadata and not any oracle stuff, etc… Think of it like having different server ports for different use cases.

3 Likes

Did you ever find a solution for this? Having a similar problem myself

Ok, so 721 is the standard key for NFT, do we have a list of these metadata key mappings?

CIP10 is meant to keep track of the mappings

2 Likes

You cannot burn and re-mint an NFT without Plutus contract. If you can with simple/native script than it is not real NFT. Why? Because you as the token controller is able to mint anytime any amount without burning it. While in Plutus the rules have been already set what everybody can verify and they are predictable, but nobody can predict your future actions.

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.