Skip to content
This repository has been archived by the owner on Sep 5, 2022. It is now read-only.

Token Data Standard #64

Open
EmelyanenkoK opened this issue Feb 2, 2022 · 13 comments
Open

Token Data Standard #64

EmelyanenkoK opened this issue Feb 2, 2022 · 13 comments

Comments

@EmelyanenkoK
Copy link
Member

EmelyanenkoK commented Feb 2, 2022

⚠️ WARNING: Standards are now published and discussed in the TEPs repository. This page may be out of date.

Summary

A standard interface for tokens (meta)data (in particular NFT or Jettons).

Motivation

For applications like wallets or marketplaces it is quite useful to be able automatically retrieve information for display. Token data standard allows to simplify this process and uniform the way of token display across different applications.

Specification

Content representation

Three options can be used:

  1. Off-chain content layout

    The first byte is 0x01 and the rest is the URI pointing to the JSON document containing the token metadata. The URI is encoded as ASCII.

    If the URI does not fit into one cell, then it uses the "Snake format" described in the "Data serialization" paragraph, the snake-format-prefix 0x00 is dropped.

  2. On-chain content layout

    The first byte is 0x00 and the rest is key/value dictionary.

    Key is sha256 hash of string.

    Value is data encoded as described in "Data serialization" paragraph.

  3. Semi-chain content layout

    Data encoded as described in "2. On-chain content layout".

    The dictionary must have uri key with a value containing the URI pointing to the JSON document with token metadata.

    Clients in this case should merge the keys of the on-chain dictionary and off-chain JSON doc.

Data serialization

Data that does not fit in one cell can be stored in two ways:

  1. Snake format when we store part of the data in a cell and the rest of the data in the first child cell (and so recursively).

    Must be prefixed with 0x00 byte.

    TL-B scheme:

    tail#_ {bn:#} b:(bits bn) = SnakeData ~0;
    cons#_ {bn:#} {n:#} b:(bits bn) next:^(SnakeData ~n) = SnakeData ~(n + 1);
    
  2. Chunked format when we store data in dictionary chunk_index -> chunk.

    Must be prefixed with 0x01 byte.

    TL-B scheme:

     chunked_data#_ data:(HashMapE 32 ^(SnakeData ~0)) = ChunkedData;
    

Data that fits into one cell is stored in "Snake format".

Informal TL-B scheme:

text#_ {n:#} data:(SnakeData ~n) = Text;
snake#00 data:(SnakeData ~n) = ContentData;
chunks#01 data:ChunkedData = ContentData;
onchain#00 data:(HashMapE 256 ^ContentData) = FullContent;
offchain#01 uri:Text = FullContent;

Note, that while TL-B scheme does not constrain bit size of each chunk it is expected that all chunks contain ceil number of bytes.

NFT metadata attributes

  1. uri - Optional. Used by "Semi-chain content layout". ASCII string. A URI pointing to JSON document with metadata.
  2. name - Optional. UTF8 string. Identifies the asset.
  3. description - Optional. UTF8 string. Describes the asset.
  4. image - Optional. ASCII string. A URI pointing to a resource with mime type image.
  5. image_data - Optional. Either binary representation of the image for onchain layout or base64 for offchain layout.

Jetton metadata attributes

  1. uri - Optional. Used by "Semi-chain content layout". ASCII string. A URI pointing to JSON document with metadata.
  2. name - Optional. UTF8 string. The name of the token - e.g. "Example Coin".
  3. description - Optional. UTF8 string. Describes the token - e.g. "This is an example jetton for the TON network".
  4. image - Optional. ASCII string. A URI pointing to a jetton icon with mime type image.
  5. image_data - Optional. Either binary representation of the image for onchain layout or base64 for offchain layout.
  6. symbol - Optional. UTF8 string. The symbol of the token - e.g. "XMPL". Used in the form "You received 99 XMPL".
  7. decimals - Optional. If not specified, 9 is used by default. UTF8 encoded string with number from 0 to 255. The number of decimals the token uses - e.g. 8, means to divide the token amount by 100000000 to get its user representation, while 0 means that tokens are indivisible: user representation of token number should correspond to token amount in wallet-contract storage.
    In case you specify decimals, it is highly recommended that you specify this parameter on-chain and that the smart contract code ensures that this parameter is immutable.

Changelog:

  • 14 May 2022 - the standard is now used not only for NFT, but for all tokens in the TON. Added section "Jetton metadata attributes".
@ghost
Copy link

ghost commented Feb 2, 2022

At the moment, NFT-collection may have common_content, and each token of the collection inherits this data.
In other words, it's just a part of NFT-token metadata.

On the other hand, NFT-collection may have its own metadata (e.g., name or image of the overall collection).

@tvorogme
Copy link

tvorogme commented Feb 3, 2022

It is very gratifying to see that our discussion has turned into an Issue and our @disintar team's proposals have been accepted.

I'm currently full-time writing the CLI and didn't have time to comment on the draft itself, but there is one point that I want to express before the CLI and other comments are published.

It would be cool to add another type tag "SemiChain" - which will mean that attributes, properties, name, image will be inside the contract, everything else will be in the offchain.

This is very necessary to give an opportunity to developers to save some parameters inside the network, which will remain even if the offchain data is lost. And take out heavy content in the off chain.

I don't know yet how to properly separate the fields into offchain and onchain, perhaps you need to give developers the opportunity to choose and enter a binary mask, instead of the first tag.

I understand that this is difficult things both for parsing and for contract code, but this is a necessity that will help make better contracts and protect users from losing content.

@EmelyanenkoK
Copy link
Member Author

EmelyanenkoK commented Feb 4, 2022

@tvorogme
I see three approaches. First one is the same as with image and image_url, when under onchain tag you have ability to either store object onchain, or store only it's URI onchain. Second one is to add offchain_properties as field which contain URI to json with properties stored offchain? Third one is to indeed have semichain tag in full content with additional tag before each property which determine whether this property stored in-place onchain or only URI is presented.
I'm not sure the third option is best one and that we need to update standard.

@EmelyanenkoK
Copy link
Member Author

NoelJacob suggested to use combination of offchain content and onchain authenticated code (hash of the content).
Probably it is candidate for AuthenticatedOffchain tag

@tolya-yanot tolya-yanot changed the title NFT data standard NFT Data Standard Feb 12, 2022
@tolya-yanot
Copy link
Member

Consider standardizing the following metadata attributes:

  • symbol - UTF8 string
  • animation_url - ASCII string
  • attributes - either stringified json object for onchain layout or json object as is for offchain layout
  • properties - either stringified json object for onchain layout or json object as is for offchain layout

@tvorogme
Copy link

tvorogme commented Feb 16, 2022

@tolya-yanot hi.

animation_url is well-needed to define not image content. As I said here we need opportunity to work with mp3 / mp4 /.... not images data and also use image to display to user in app.

attributes - also well-needed field, we need to store some attributes of object onchain, and image of object (or other heavy data) offchain (semi chain model)

You want to remove those fields or you would like to discuss more specification on these fields?
Maybe I can help.

@tolya-yanot
Copy link
Member

@tolya-yanot hi.

animation_url is well-needed to define not image content. As I said here we need opportunity to work with mp3 / mp4 /.... not images data and also use image to display to user in app.

attributes - also well-needed field, we need to store some attributes of object onchain, and image of object (or other heavy data) offchain (semi chain model)

You want to remove those fields or you would like to discuss more specification on these fields? Maybe I can help.

Nobody forbids setting these fields, the question is - do we really need to standardize them?

@tvorogme
Copy link

Nobody forbids setting these fields, the question is - do we really need to standardize them?

Ok. Got it.

Some arguments to specify animation_url field in standart:

animation_url - we need unify field, so all other apps, marketplases, etc. know how to get music / video from NFT. If we leave setting this field to the developers: we will get a situation where everyone will use different fields for animation content. And this means that marketplaces, wallet applications and others will have big problems supporting this diversity.

As an example, you may see that OpenSea collections support this field. E.g. metadata of one song uses image (for display in app) and animation_url so user can click on NFT in his wallet, and wallet take content from animation_url field and play it to user.

In my opinion, music and video for NFT are very common, so we need to set the structure rigidly so that third-party application developers can simply parse the content.

attributes / properties much more complicated, so I need to do some research stuff. The main idea is to have field to display in third-party applications that describe your NFT. You definitely need to approve the exact name of such a field in the standard for easy parsing in the future, but I don't know about the content inside such field.

@NoelJacob
Copy link

NoelJacob suggested to use combination of offchain content and onchain authenticated code (hash of the content). Probably it is candidate for AuthenticatedOffchain tag

Is this being moved ahead with? This is also recommended in the whitepaper (p. 79)

Screenshot_3

There are more criticism to NFTs being reduced to just owning a link. Signal's founder Moxie had detailed the problem his quite famous blog post. (tldr; He made an NFT that changes art based on the IP requesting)

I suggest anything stored off-chain should have on-chain authenticated code, by default.

@lunarstill
Copy link

Hi!

animation_url - we need unify field, so all other apps, marketplases, etc. know how to get music / video from NFT.

I think it's better to keep interface more flexible and use fields like content_type / content_url instead of animation_url, music_url and so on. Also consider scheme that allows to put multiple files into single NFT.

@tvorogme
Copy link

tvorogme commented Mar 9, 2022

Clients in this case should merge the keys of the on-chain dictionary and off-chain JSON doc.

Maybe it'll be cool to clearly define merge rules (on merge conflicts) which must be the same for everyone :)

@solidovic
Copy link

I think this draft should change imageand image_data fields to payload_type and payload (or content_type and content).
why?
Because different NFT will be not only as image. Also lottie-animation (json), mp4 and other.

payload_type can says different NFT explorers how should display NFT (can be based on Media_type https://en.wikipedia.org/wiki/Media_type).

@hacker-volodya
Copy link

@tolya-yanot hi.
animation_url is well-needed to define not image content. As I said here we need opportunity to work with mp3 / mp4 /.... not images data and also use image to display to user in app.
attributes - also well-needed field, we need to store some attributes of object onchain, and image of object (or other heavy data) offchain (semi chain model)
You want to remove those fields or you would like to discuss more specification on these fields? Maybe I can help.

Nobody forbids setting these fields, the question is - do we really need to standardize them?

I think we have to standardize attributes, otherwise there will be a problem to implement, for example, market-independent rarity checking tools.

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

No branches or pull requests

7 participants