Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP-NFTMetdataStandard #85

Merged
merged 4 commits into from
Jul 28, 2021
Merged

CIP-NFTMetdataStandard #85

merged 4 commits into from
Jul 28, 2021

Conversation

alessandrokonrad
Copy link
Contributor

No description provided.

}
```

The **`image`** and **`name`** property are marked as required. **`image`** should be an URI pointing to a resource with mime type `image/*` used as thumbnail or as actual link if the NFT is an image (ideally <= 1MB).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason for image property to be required, there are several NFT applications which have 0 reason to have any image, even as thumbnail.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, but it is fair to assume majority of these applications would require a custom or no metadata at all, therefore this CIP does not applies to them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In such case, if the goal is not to create a generic NFT standard, with reasonable required and optional fields, it is not wise to call it NFT Metadata Standard, but rather Image NFT Metadata Standard so it is made clear that this is intended for images only / mostly, as opposed to being a generic NFT attempt to define a NFT standard.

Perhaps this should be two separate CIPs, one for the metadata part that is important for lookup (including a table that lists reserved metadata labels for different NFT applications), and then second CIP that extends each metadata label based off of use-case for the NFT, in this case images.

Copy link
Contributor

@SmaugPool SmaugPool Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an example of such a use case where it would need to use this 721 format without needing an image? Not all NFTs have to use this format if they don't need anything in it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark-stopka this makes sense. The name could be reworded indeed, maybe "Media NFT Metadata Standard"?

Copy link
Contributor

@SmaugPool SmaugPool Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mark-stopka this proposal is not only about images, using the type and src optional fields, it should also support as is:

  • audio
  • video
  • ebook

But all of those seem to benefit from having a thumbnail to represent them (the image field).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the intent of the image field is to be used as a thumbnail, what about calling it thumbnail or preview to disambiguate its role?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image field can be used for NFTs that are images. In my opinion most NFTs are images/art. The idea behind thumbnail is that if the the NFT is not an image, you still have a preview and the actual NFT is then linked under the src field. So it's not only meant for thumbnails.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In such case, if the goal is not to create a generic NFT standard, with reasonable required and optional fields, it is not wise to call it NFT Metadata Standard, but rather Image NFT Metadata Standard so it is made clear that this is intended for images only / mostly, as opposed to being a generic NFT attempt to define a NFT standard.

Perhaps this should be two separate CIPs, one for the metadata part that is important for lookup (including a table that lists reserved metadata labels for different NFT applications), and then second CIP that extends each metadata label based off of use-case for the NFT, in this case images.

As suggested, we are thinking about splitting up the CIP into two CIPs:
The first one really just explains how to create a unique link between tokens and metadata and how to update the link. This one we would call "Metadata Token Link".
The second one takes this one as basis and defines a metadata standard for media files on top. The metadata structure is pretty similar to current CIP ones, but we made some small modifications:

{
  "721": {
    "<policy_id>": {
      "<asset_name>": {
        "name": <string>,

        "image": <uri | array>,
        "mediaType": "image/<mime_sub_type>",

        "description": <string | array>

        "files": [{
          "name": <string>,
          "mediaType": <mime_type>,
          "src": <uri | array>,
          <other_properties>
        }],

        <other properties>
      }
    }
    "version": "1.0"
  }
}

The main difference is that you have the property files instead src now, which is an array and allows to add an arbitrary amount of different media files.
Other properties, like image or description could be either a single string or an array in case 64 bytes are exceeded.
We go more into details with the full proposal.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Allessandro, I have tried it out:
https://explorer.cardano.org/de/transaction?id=9e680460a65812ea940b69bd271f8a835cfb751de7e39c01fd5b3d072363e3d9
Looks good to me. Base64 encoded datauri allows to store the whole content on blockchain.


The **`description`** property is optional.

The **`type`** and **`src`** properties are optional. If **`type`** is defined, **`src`** will be an URI pointing to a resource of this mime type. If the mime type is `image/*`, **`src`** points to the same image in an higher resolution.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you take this route, you need to include mime-type several times, for instance an NFT token could be a song which may have image thumbnail which would be of type image, but the actual valuable payload of such NFT would be the song in a playable format.

Copy link
Contributor

@SmaugPool SmaugPool Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image must have the mime type image/* as indicated and is a thumbnail in case of an additional file. The type field is for the optional src file that could be an audio one, so this use case is handled by the current proposal.

@SmaugPool
Copy link
Contributor

SmaugPool commented Apr 9, 2021

1. Resources Integrity

One thing left out for now from the CIP is a way to check the integrity of files pointed by image and src fields.
Unless the community comes to an agreement about this, this could be handled in another future CIP as an extension using <other properties>

Some related references are:

2. NSFW

With the release of NFT public viewers on the web, it is in my opinion important to come with a way to detect content not suitable for children or work . This could be an nsfw tag, but we have not come to an agreement yet. Propositions and feedback are welcome.

3. Multiple additional files

The only use case for multiple additional files identified for now is the one for 3d files as supported by the Cargo extension to ERC-721 metadata format:

https://docs.cargo.build/advanced-information/cargo-metadata

As it is quite specific and seems to require additional properties anyway to render properly the media, maybe it could be also handled in an extension CIP to this one. One way would be to support src as a list as a single mime type is still enough for this use case.

Practical examples of other use cases where multiple mime types would be needed are welcome.

@mmahut
Copy link
Contributor

mmahut commented Apr 9, 2021

As the script policy of the native asset is not stored on chain, would it make sense to include a proof of the native asset being locked as a single non-fungible unit? This policy field could be used directly on-chain or pointing outside the chain, as I did in the following example, pointing to IPFS in this case.

@mark-stopka
Copy link
Contributor

2. NSFW

With the release of NFT public viewers on the web, it is in my opinion important to come with a way to detect content not suitable for children or work . This could be an nsfw tag, but we have not come to an agreement yet. Propositions and feedback are welcome.

Not only that, license should also be part of the metadata, legally in most jurisdictions a copyrighted work is not public-domain unless specified otherwise, but the exact opposite, unless license grants more permissive use, such work is considered sole ownerhip of it's author(s).


```
{
"721": {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that the label we adopt should also be included in CIP10

@alessandrokonrad
Copy link
Contributor Author

As the script policy of the native asset is not stored on chain, would it make sense to include a proof of the native asset being locked as a single non-fungible unit? This policy field could be used directly on-chain or pointing outside the chain, as I did in the following example, pointing to IPFS in this case.

That's a good point. How would you add it to big NFT groups with the same policy? Maybe it's a little redundant there if you have to include into each transaction the same policy reference. Maybe explorers and third party tools can store the policies, where you simply upload them to make the policy legit. Something like etherescan is doing for smart contracts.

@SmaugPool
Copy link
Contributor

SmaugPool commented Apr 9, 2021

2. NSFW

With the release of NFT public viewers on the web, it is in my opinion important to come with a way to detect content not suitable for children or work . This could be an nsfw tag, but we have not come to an agreement yet. Propositions and feedback are welcome.

Not only that, license should also be part of the metadata, legally in most jurisdictions a copyrighted work is not public-domain unless specified otherwise, but the exact opposite, unless license grants more permissive use, such work is considered sole ownerhip of it's author(s).

@mark-stopka Good point. Not sure if we should make it optional or not (as you say the default might not be the same in every jurisdiction, even if most grant no permission in this case).

It seems to me that publishing a media NFT on the blockchain should at least allow public viewers to display it, but maybe there are some use cases where this is not wanted?

@Foxxinator
Copy link

Hi guys, I have just submitted a fund 5 proposal to look at a similar standard that is going on here: https://cardano.ideascale.com/a/dtd/Tokenization-of-a-physical-asset/351135-48088

I want to piggy back on what is being discussed here as from what I see, the conversation is looking more at digital art style NFTs. See my use case slides - if I wanted to create a token to represent a physical asset like a football club token (that represents ownership) - how would this fit with the standard being discussed so far?

Apologies if this comes completely out of left field, but would appreciate your ideas on this one and I hope you can see where I am going with this. (Tokenizing property, real artwork, businesses etc)

@mark-stopka
Copy link
Contributor

if I wanted to create a token to represent a physical asset like a football club token (that represents ownership) - how would this fit with the standard being discussed so far?

It would not, which is why I keep pushing for a general NFT standard and then derived sub-sandards for individual NFT classes.

@mmahut
Copy link
Contributor

mmahut commented Apr 10, 2021

Are there any plans to integrate this with the off-chain metadata registry in the future?

@alessandrokonrad
Copy link
Contributor Author

Are there any plans to integrate this with the off-chain metadata registry in the future?

Taking over the property names for example?
But nothing planned yet. One idea I have in mind is, that you can check for an asset if it has data in the off-chain registry first. If there is nothing then it will be checked on-chain according to this standard.


## Abstract

This proposal defines an NFT Metadata Standard for Native Tokens.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

"version": "1.0"
}
}
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity and better interoperability, it would be good to provide a CDDL specification of this structure, and possible a companion JSON example.

"<policy_id>": {
"<asset_name>": {
"name": "<name>",
"image": "<uri>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If including an image link, it could be a good idea to also include a hash of the image data inside the metadata itself so that one can verify that the linked image does indeed corresponds to what the author originally linked.

}
```

The **`image`** and **`name`** property are marked as required. **`image`** should be an URI pointing to a resource with mime type `image/*` used as thumbnail or as actual link if the NFT is an image (ideally <= 1MB).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the intent of the image field is to be used as a thumbnail, what about calling it thumbnail or preview to disambiguate its role?

"<policy_id>": {
"<asset_name>": {
"name": "<name>",
"image": "<uri>",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important to note as Spacebudz utilized IPFS Cid v0 hashes and so the "ipfs:" prefix was acceptable. However, expanding the use case to IPFS Cid v1 hashes, the "ipfs:" prefix will cause the JSON value to exceed 64-characters and create unusable metadata format/structure. I would argue that something along the lines of the "CNFT" format with an "asset": {} descriptor is more future-proof.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting. What about making the image field an array in case the uri exceeds 64 bytes. The concatenation of the strings is the uri. This basically allows for any length. In case the uri is less than 64 bytes you keep it as string without array. So it saves storage as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, so the definition would be:
image: "typeof string|array"...

That would be potentially possible if it's not better to use a separate identifier like "url" to show the prefix, i.e.
url: "https://blockfrost.io/ipfs/",
image: "[ipfsHash]"
or
url: "https://ipfs.io/ipfs/",
image: "[ipfsHash]"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that makes total sense,although I would not prefer https gateways, when you use already ipfs. Better keep the ipfs:// protocol. One advantage tho of making it with an array is that you could also embed data URIs.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fair point, "url" could contain either "ipfs:", "https://path/to/thing/", or "data:" (probably other things I'm not thinking of as well). image may then contain string|array as necessary and it will just be up to the platform to handle gluing the pieces together in the case of an array.

Copy link

@nilaysaha nilaysaha Apr 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above structure has one major problem. Suppose a single Token is minted for the policyId mentioned in the Metadata which consist of say 100 NFT, then it means that when we want to transfer ownership of the NFTs minted in this transaction, we would have to always tie it up to this single token. Thus split ownership would be impossible. Thus this is ideal for example, if we want to print a set of gaming cards that form a complete set (so that either we own all or none of these). Or maybe i am missing something. Would love to be corrected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mint the same token with quantity 100 you can easily split that up. They all refer to the same metadata and of course can have multiple owners.

@Crypto2099
Copy link
Collaborator

We need a good way to handle "serialized" or semi-fungible NFTs such as limited edition prints. What I see right now looking at the live, on-chain metadata is that people are following this format and creating replication of things like the same IPFS link dozens if not hundreds of times. I have personally been following the early CNFT.io format for these types of minting but would love to pull the metadata much more inline with this format.

To that end, I would propose the introduction of "Top Level" descriptors that describe global properties of all tokens that may have been batch-minted under a policy in a single transaction to avoid data duplication.

{
  "721": {
    "asset": {
      [common_asset_attributes]
    },
    "publisher": [
      "https://link.to.my/profile"
    ],
    "[policyId]": {
      "[assetId]": "[asset Display name]" 
    }
  }
}

In this case the assetId: "[asset Display name]" could probably be either a string (if only a friendly display name is provided) or an object with key: value pairs that describe custom properties of this asset.

"721": {
"<policy_id>": {
"<asset_name>": {
"name": "<name>",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like name&description shouldn't be there. I think we have two options:

  1. Double-down on the idea that this kind of common metadata (name & description.) should be stored on the metadata server
  2. Accept that name&description can also be stored on chain via tx metadata and to avoid every standard having to repeat this field, we should use a different namespace (not 721) so that other standards can use this also instead of every token standard having to repeat name&description in their definition.

Maybe this is not as big of a deal if the whole 721 metadata ends up being just on IPFS (but still not clear what wallets should do if 721 specifies a name, but the metadata server defines a different name)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion it's crucial for many NFTs to have the metadata on-chain, even if it's just name or description. I would go with the 2. option and you should either use the off-chain registry or on-chain metadata, not both. If both exist one should have a higher priority by default (I would say the on-chain metadata).

Yes right, we are going to split up this CIP as suggested. The first one will define the base of how to retrieve on-chain metadata in general for a token (maybe this is were we can put common properties like name and description). The second one implements the base structure and is pretty much the like current CIP, which is an NFT metadata standard for media files and uses the 721 label.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion it's crucial for many NFTs to have the metadata on-chain, even if it's just name or description

Could you elaborate on that? While I understand it may be a little bit easier for downstream applications to have metadata readily available on-chain. The cost for doing an extra query to fetch them from an off-chain registry is quite low, especially since the image itself already has to be fetched so it is not like this is introducing an extra operational cost.

The blockchain is a ledger, not a database. It makes for a very poor choice of storage and, storing ten of thousands of NFT metadata on the blockchain does not sound like a good idea to me. Rather, the blockchain is good at recording hashes of content stored off-chain. I like the approach of associated metadata with some tokens in the minting transaction as it makes the relationship between the metadata and the token creator unambiguous. However, we should avoid storing the actual content on the chain and prefer off-chain solutions for that.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been following up with this thread, and I'm thinking that if you rely on IPFS to provide image, why not use it to store the metadata as well? I know the downs, but, i'm forward with the fact that we need to store as less as possible on chain, "a ledger is not a database", on the long run this is not healthy for the chain. IPFS is already largely relied upon by practically all NFTs around, and IPFS CIDs can represent anything, a file, an image, a json, a text....

Versioning/labeling the on-chain metadata with something like 721 (not 721), is, in my honest opinion, the best approach so the community (& marketplaces) can agree on formats on how to validate the metadata that comes back from IPFS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use it to store the metadata as well?

This is actually one avenue we've indeed considered during the editor meeting. On the plus side, IPFS store data by hashes, so we get both addressable and verifiable content in one URI. We could very much imagine storing a JSON file on IPFS with a format defined by this CIP, and likely carrying another URI to an image hosted on IPFS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say you buy a very expensive NFT, where the link to the image or other media file is on-chain, but the name and description is not. Now the original creator can change the name and description to something arbitrary and ridiculous. These common properties will be shown in most third parties and it could actually have an impact on the value of the NFT. You depend on the creator in some respect.

I agree that content should not be stored on-chain, especially not images or alike. But I think that name and description don't take up too much storage and are actually part of metadata. But let's assume the metadata for one specific NFT is pretty large. Instead of using the off-chain registry, I would rather use a decentralized file storage like IPFS and propose the following structure:

{
  "721": {
    "<policy_id>": {
      "<asset_name>": {
         "metadata": "ipfs://<hash>"
      }
    }
  }
}

The metadata property now contains all the properties that would have been on-chain. The IPFS link is just an example. Any other decentralized storage solution works as well. The idea is just to keep everything as decentralized as possible and don't rely on 3rd parties or the creator itself.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my thoughts exactly Alessandro, thanks for the great work pushing this CIP forward btw, i'm here to help any way I can.
The on-chain metadata label can define a way for us to know what to expect from IPFS, this makes total sense to me, you can't tamper a file once it's on IPFS, it will have a new CID, so it's immutable as well (and addressable).

I understood your concern to make querying those name/descriptions easier by having it on-chain, but I don't think it makes much of a difference if you grab it from IPFS as well like you've shown above.

I think that the community is eager to flourish in terms of NFTs, and doing this off-chain (on IPFS), can also help on this regard, we can quickly iterate versions/labels and evolve, without having to rely on on-chain structural changes.

The optimal solution for all this, i think would be having an official Cardano sidechain for data/object storage, but I think we are a long way to get there and the quickest (not the best) solution for us now, to allow NFTs to grow in a predictable yet flexible manner, is going off-chain (on IPFS) with all those meta-data needs.

But yes, I also agree with you, that name/description can be perceived as a part of the on-chain metadata, and is something general to most NFT needs (and cheap if we limit description). What I'd like to see to assess this, is a simulation on how much weight this can add to the chain in like, a hundred year time considering some arbitrary numbers on growth, OR, maybe Sebastien or someone can give us an evaluation on how damaging this can be in terms of weight added on-chain (it's indeed a pretty small footprint though).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IPFS can go a long way if we use it smartly. I'm just thinking around, please let me know if I'm awfully wrong on those ideas.

We could have a Policy ID as a result of this proposal, that can mint type definitions for NFT content types.
Imagine we mint a versioned json or typescript or whatever, that describes all possible NFT types and their data formats. We'd have an image type, audio type, copyright, tags, attributes all that jazz into a single file, that describe all possible types, and store that on IPFS, with the CID being on-chain. This way, anyone can use this policy ID, to fetch this type definition and determine what to expect from NFT projects.

On the other end, the NFT builders that want to comply with our agreed upon specification, would use this policy and its type definitions to structure their own meta-data. I find this approach interesting, cause let's say I want to mint an NFT with a combination of audio / image / attributes / copyright, I wouldn't need a brand-new standard, but just use the types, and this can be built in a way Marketplaces can automatically identify what kinds of data an NFT has, not caring if it's only an image, or a mix of all available type definitions.

Then, in the event we need to change our type definition, it would go under a CIP agreement, so we mint and update version of the type definition scheme.

I know this is semi-on-chain, and I also don't like the idea of not having all that on-chain, but reality is, majority of NFTs do rely on IPFS, and its not going away.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey that's a very interesting. If I understood that right, instead of proposing more CIPs for various use cases, NFTs are minted containing the metadata structure and 3rd parties can look up the structures right? The question is who will decide which types are valid or allowed to be minted.

Regarding the off-chain approach I have no problem with IPFS. Before I was referring to the official off-chain metadata registry, which is mutable and the owner of the policy can change the metadata whenever he wants. With IPFS or other decentralized file storages you have immutability.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep! Cardano Native Tokens works completely different from ERCs, so, there's an opportunity for us to approach this with freedom of thought. Cause in the end, a standard is not really required, and we cannot guarantee a standard will be followed.

So instead having one/multiple standards, we can have a type definition schema, that lays out the format for all possible NFT media/data types.

We have no control over how people mint, what people mint, and what format they'll follow, what we can have is a type definition that sets the data structure on how an audio metadata block look like, or image and so on, and this would be set by this CIP, and be fetched using a Policy ID from this CIP.

Then, NFT builders and marketplaces can lookup this definition via this CIP Policy ID, in order to lookup types and know how to build or what to expect from an NFT projects.

Note: Again, i'm just doing some thought exercises on this issue, not that this is the best approach.

@crptmppt
Copy link
Contributor

crptmppt commented May 11, 2021

it looks like this CIP is more targeted for images - can this be narrowed in scope to accommodate? Last conversation occurred in https://www.crowdcast.io/e/cip-editors-meeting-22 - And should be continued in the following meeting (23). Thank you for joining the conversation at the next meeting!
(meeting 21 notes here, meeting 22 notes to be updated within a week)

@shawnim
Copy link
Contributor

shawnim commented May 12, 2021

Sorry if this is a dumb question.
Why use the label "721"?
If you are not coming from the Ethereum ecosystem, it has no meaning.
This isn't an implementation of ERC-721.
So why not use a more meaningful label, such as "nft"?

@alessandrokonrad
Copy link
Contributor Author

Sorry if this is a dumb question.
Why use the label "721"?
If you are not coming from the Ethereum ecosystem, it has no meaning.
This isn't an implementation of ERC-721.
So why not use a more meaningful label, such as "nft"?

The JSON metadata top level must be a map (JSON object) with unsigned integer keys.

@alessandrokonrad
Copy link
Contributor Author

it looks like this CIP is more targeted for images - can this be narrowed in scope to accommodate? Last conversation occurred in https://www.crowdcast.io/e/cip-editors-meeting-22 - And should be continued in the following meeting (33). Thank you for joining the conversation at the next meeting!
(meeting 21 notes here, meeting 22 notes to be updated within a week)

it looks like this CIP is more targeted for images - can this be narrowed in scope to accommodate? Last conversation occurred in https://www.crowdcast.io/e/cip-editors-meeting-22 - And should be continued in the following meeting (33). Thank you for joining the conversation at the next meeting!
(meeting 21 notes here, meeting 22 notes to be updated within a week)

It's not only for images, but for all kind of media files. Imagine buying a new Music-CD, of course the actual content is the music, but it also comes with a cover. So the idea here is the same. The image property links to a cover/thumbnail and the actual music link is under the files property. This can be applied for almost all kind of media NFTs and makes the NFT accessible to all 3rd parties, because not all 3rd parties will support exotic file types.
But if the NFT itself is an image or digital art of course the image property is used here as well.

So the image property is used alone, if the NFT itself is an image.
If the NFT is a different media file, a combination of image and files is used.
I'm refering to this structure I recently added in the comments: #85 (comment)

@rphair
Copy link
Collaborator

rphair commented May 13, 2021

With possible attributes for creative works (media types & more) and physical objects for which NFTs might indicate ownership, as well as their attribution & copyright (individuals, companies, web sites, etc.) it would be nice to integrate with an object standard like schema.org which already has such a rich vocabulary, is already known by so many designers, and has been so widely adopted with plans to continue it long into the future.

The standard includes many agreed-upon conventions about which arguments and definitions are required or optional for each type of entity. The schema is already parseable as JSON as in the web-based examples here, so definitions like these might even be suitable to put directly into the on-chain metadata, and at least rationalise the off-chain metadata if not: https://yoast.com/json-ld/

This could be part of the answer for how to anticipate entity and creator types that don't exist yet and/or go well beyond MIME types, since the schema.org standard is itself a continually updated JSON file: https://schema.org/version/latest/schemaorg-current-https.jsonld

... which would mean CIP maintainers wouldn't have to update the standard for object references every time a new object was invented or recognised, or whenever someone wanted to expand the scope of how Cardano NFTs are used.

@crptmppt
Copy link
Contributor

crptmppt commented May 21, 2021

This was again discussed at the last Editor meeting (22), please refer to the notes to catchup on the conversation.
This tentative CIP is scheduled to be discussed further at the next public meeting this Tuesday, thank you for attending as feasible to broaden/continue the conversation.

@KtorZ
Copy link
Member

KtorZ commented May 25, 2021

Suggestions to move this proposal forward:

  1. Scope that CIP to specifying URI for NFT metadata. I don't think IPFS should be a must (but more of a possible option) for it is needlessly restrictive. However, the URI must come with a hash of the content to be verifiable (note that, IPFS gives that for free indeed). As stated several time, directly publishing metadata on-chain is ill-advised and would in the long-run create bloat on the network. Clients consuming blocks from a node would likely have a network connection anyway and be able to fetch metadata from various servers easily. In the long-run, we can also imagining some intermediate caching solutions in the forms of CDNs or registries.

  2. Metadata URI can then piggy-back on existing battle-tested schemas from https://schema.org/ which already provides a framework for specifying metadata for various media type. For example, the schema for an image is given by: https://schema.org/ImageObject and a concrete example:

    {
      "@context": "https://schema.org",
      "@type": "ImageObject",
      "author": "Jane Doe",
      "contentLocation": "Puerto Vallarta, Mexico",
      "contentUrl": "mexico-beach.jpg",
      "datePublished": "2008-01-25",
      "description": "I took this picture while on vacation last year.",
      "name": "Beach in Mexico"
    }
  3. The schema.org schemas are purposely wide and covering a lot of use-cases. So it wouldn't be crazy to also have projects providing their own schemas, or, restricting some existing schemas to a certain set of properties.

cc @alessandrokonrad , thoughts?

@zachyking
Copy link

It's not only for images, but for all kind of media files. Imagine buying a new Music-CD, of course the actual content is the music, but it also comes with a cover. So the idea here is the same. The image property links to a cover/thumbnail and the actual music link is under the files property. This can be applied for almost all kind of media NFTs and makes the NFT accessible to all 3rd parties, because not all 3rd parties will support exotic file types.
But if the NFT itself is an image or digital art of course the image property is used here as well.

However if you buy song or even simpler sound, image is only optional. That's exactly my case on project I hope to release soon.

@alessandrokonrad
Copy link
Contributor Author

alessandrokonrad commented May 31, 2021

Suggestions to move this proposal forward:

  1. Scope that CIP to specifying URI for NFT metadata. I don't think IPFS should be a must (but more of a possible option) for it is needlessly restrictive. However, the URI must come with a hash of the content to be verifiable (note that, IPFS gives that for free indeed). As stated several time, directly publishing metadata on-chain is ill-advised and would in the long-run create bloat on the network. Clients consuming blocks from a node would likely have a network connection anyway and be able to fetch metadata from various servers easily. In the long-run, we can also imagining some intermediate caching solutions in the forms of CDNs or registries.
  2. Metadata URI can then piggy-back on existing battle-tested schemas from https://schema.org/ which already provides a framework for specifying metadata for various media type. For example, the schema for an image is given by: https://schema.org/ImageObject and a concrete example:
    {
      "@context": "https://schema.org",
      "@type": "ImageObject",
      "author": "Jane Doe",
      "contentLocation": "Puerto Vallarta, Mexico",
      "contentUrl": "mexico-beach.jpg",
      "datePublished": "2008-01-25",
      "description": "I took this picture while on vacation last year.",
      "name": "Beach in Mexico"
    }
  3. The schema.org schemas are purposely wide and covering a lot of use-cases. So it wouldn't be crazy to also have projects providing their own schemas, or, restricting some existing schemas to a certain set of properties.

cc @alessandrokonrad , thoughts?

Right, any URI works and it's not limited to IPFS. As you said for URIs with no hash inclued, we need the hash inside the metadata. I would add a property called sha256Hash (already being used in some metadata) containing the hash of the image from the image property. The same for any media file inside the files array.

I would support on-chain and off-chain approaches. I personally think it's not only about proofs, but also about longevity of the file itself. What do you do with a hash, if you can't prove it, because the file is not available. If you move the metadata fully off-chain you lose all properties of the NFT if the metadata are not available.

Schema.org could work in someway yeah, but since this standard is not only about images, but also allows to include any kind of media file in any combination, I'm not sure how this can be integrated.

@rokindo
Copy link

rokindo commented Jun 3, 2021

Here is a scenario: what if someone developed a sort of game/world where everything is tokenized? Say, for example, that someone develops an MMORPG where everything from equipment, weapons, characters (that has stats/characteristics), skins, and all items, in general, are tokenized. And then furthermore there is some sort of marketplace within the game to buy/sell/trade in-game NFTs.

Say, for example, there are many kinds of weapons, and they all function differently (depending on class), they all have their own "skin" or artwork, they all have different stats, etc.

How could we allow this to happen? From reading everything in this thread, it seems that there is a large focus on more simple NFT infrastructures where there is simply an art piece/creative work and a title and maybe a description.

I would like to bring a new perspective to this discussion.

Theoretically speaking, I believe it is possible to import any data from the real world or the Internet onto the blockchain. With that being said, I believe that the standard for metadata should be as simple as possible because there are too many applications and too many different use cases for NFTs.

So the first and most obvious question is: is the above example even possible? If so, how would this metadata structure look like?
I would think that there needs to be a general format that encompasses such a huge project like this. And not only would it have to apply to this application but it would have to apply to any arbitrary application. Furthermore, would you store these files/information/metadata on-chain? Would you store these on IPFS?

The question then becomes, how can we create a metadata structure that can accommodate the tokenization of "everything"?
In my opinion, I think the simpler, the better since there is an infinite amount of use-cases. As long as the specific token is defined by a "name" to delineate the title of this specific file/data and maybe a "type" or "description" of such file are the only necessary components of this structure.

@Crypto2099
Copy link
Collaborator

@rokindo what you're describing sounds more like a use-case for a "closed system" token. In this case, as you mention, you can get as crazy/fancy as your heart desires because your game (in this specific example) would know how to handle the various attributes and such that are applied to a given token. There would probably be a very limited-scope use case for these types of tokens to exist on other platforms outside of the game.

What is nice about the currently described metadata structure is that it could, however, already accommodate what you're asking for since all metadata is in JSON, you can easily add/remove elements that you need/don't need without a great impact and without affecting the underlying structure of the NFT itself.

For example, on a project where there are "descriptors" to the art, I generally like to include an "attributes" object that contains key-value pairs of information about the referenced art as follows:

{
  "721": {
    "[policyId]": {
      "[tokenId]": {
        "image": "ipfs://[imageIpfsHash]",
        "name": "My Super Cool Token",
        "attributes": {
          "strength": 10,
          "luck": 20,
          "health": 19
        }
      }
    }
  }
}

@Crypto2099
Copy link
Collaborator

Sorry if this is a dumb question.
Why use the label "721"?
If you are not coming from the Ethereum ecosystem, it has no meaning.
This isn't an implementation of ERC-721.
So why not use a more meaningful label, such as "nft"?

The "labels" (in this case 721) must be numerical due to how they are stored in the database and on-chain. So 721 is as good as any other number and since this is somewhat of a Cardano mirror of the 721 format (now with some expansion) it stands to reason 721 is as good as any other number.

@rokindo
Copy link

rokindo commented Jun 4, 2021

@Crypto2099 is it possible to do the described technique of attaching HTML to the meta while simultaneously tokenizing everything?

@Crypto2099
Copy link
Collaborator

@Crypto2099 is it possible to do the described technique of attaching HTML to the meta while simultaneously tokenizing everything?

Sure, you could use something like IPFS to link to an HTML file stored on IPFS and simply need to add a pointer to that data via the on-chain metadata. The token itself is just a vessel to record a ledger of the ownership of that asset on-chain.

@@ -0,0 +1,119 @@
---
CIP:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 (tentative)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind in your meeting that the last update proposal is the one in this comment:

#85 (comment)

As an aside, this is also the one supported by pool.pm currently.

@crptmppt
Copy link
Contributor

(conversation might be ahead of meeting notes at this point, this is a reference)
6/8 Editors meeting (24) discussed this PR - see notes.
=> This PR is moved into a Review slot for tomorrow's CIP Editors Meeting (25)

… to CIP-0010 registry; added backward compatibility with hint to version 2.0 including schema.org
@crptmppt
Copy link
Contributor

crptmppt commented Jul 7, 2021

6/29 Editors meeting (25) discussed this PR - see notes. (conversation might be ahead of meeting notes at this point, this is a reference)

=> PR is now in 'Last Check': it will get another look at next week's meeting (26) and should be merged in after that - consider attending the meeting if relevant to you.

Copy link
Collaborator

@SebastienGllmt SebastienGllmt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed there's been a commit that fixes up the README to match what is actually implemented and so I'm approving this PR.

However, I would really like if there could be a comment by somebody (@alessandrokonrad ?) to confirm that the commit updates the README to the state we want for v1

Copy link
Member

@KtorZ KtorZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed in previous meeting, merging this one as-is for it is already capturing various existing implementations. However, we're looking forward into producing a new version later on as a separate PR which would include suggestions and ideas covered in past discussions.

@alessandrokonrad you mentioned you wanted to do some edits in the last meeting; if you're happy with the latest changes then let us know so we can proceed merging this one 👍

@alessandrokonrad
Copy link
Contributor Author

As discussed in previous meeting, merging this one as-is for it is already capturing various existing implementations. However, we're looking forward into producing a new version later on as a separate PR which would include suggestions and ideas covered in past discussions.

@alessandrokonrad you mentioned you wanted to do some edits in the last meeting; if you're happy with the latest changes then let us know so we can proceed merging this one

I just made one more tiny change, but yes this can be merged now👍

@crptmppt
Copy link
Contributor

crptmppt commented Jul 28, 2021

@alessandrokonrad thanks for providing repo owner edit access so PR files can be moved/renamed/adjusted (need to setup CIP # - seemingly 0025) and be merged!

@alessandrokonrad
Copy link
Contributor Author

@alessandrokonrad thanks for providing repo owner edit access so PR files can be moved/renamed/adjusted (need to setup CIP # - seemingly 0025) and be merged!

Alright👍
I thought it will be 0020. My commit to the CIP-0010 registry.json must be changed as well then:

"description": "CIP-0020 - NFT Metadata Standard"

@crptmppt crptmppt requested a review from KtorZ July 28, 2021 08:30
@crptmppt crptmppt merged commit 15a0cd1 into cardano-foundation:master Jul 28, 2021
@AriFordsham
Copy link

The "labels" (in this case 721) must be numerical due to how they are stored in the database and on-chain. So 721 is as good as any other number and since this is somewhat of a Cardano mirror of the 721 format (now with some expansion) it stands to reason 721 is as good as any other number.

It's not - it's confusing. It makes the reader think it's Ethereum ERC721 compatible. 25 for CIP25 is much better.

@atrhacker
Copy link

atrhacker commented Dec 9, 2021

the issue you have now with this CIP which was backed by pool.pm and nami creator, is that everyone who created a native token (not necessarily a nft) adapted this "standard" to be able to have a logo on pool.pm...
At the end of the day native tokens are then considered as collectibles in NAMI because they have metadata associated with it. and not anymore as native tokens. As it was the only way to preview a logo for the most popular blockchain explorer on cardano (pool.pm)..

In the meantime in the token registry, you have some NFTs....

This is all very confusing and does not make any sense IMO.

@michaelpj
Copy link
Contributor

This CIP does not have a Rationale section. This is important, because it needs to justify why it achieves the goals that it sets out to, and in particular why the scheme is secure. I believe it does not achieve its goals, for the reasons below.


This approach is fundamentally unsafe for the reasons discussed here: #118 (comment)

It conflates the creator of the token with the party who performs the minting action. These are often but not always the same person, and you can't tell without... metadata. This confusion means that if this is adopted as a a standard then anyone whose tokens don't follow this pattern will potentially be vulnerable to metadata spoofing attacks.


The inference the CIP takes from this quote is also incorrect:

Given a token in a EUTXOma ledger, we can ask “where did this token come from?” Since tokens are always created in specific forging operations, we can always trace them back through their transaction graph to their origin.

Shortly afterwards, there is this additional sentence

In the case of fungible tokens, there may be multiple possible traces: since such tokens are
interchangeable, if two tokens of some asset are forged separately, and then later mingled in the
same output, then we cannot say which one came from which forging.

That is, there is only a unique origin for non-fungible tokens. But whether a token is fungible or not is a global property, so you can't tell whether it is or not without... metadata.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet