- On-chain metadata: stored on the blockchain, including name, attributes, and image.
- Off-chain metadata: stored via a link to a metadata file hosted off-chain.
- Semi-chain metadata: a hybrid approach that stores small fields (e.g., name or attributes) on-chain, while hosting the image off-chain and storing only a link to it.
Snake data encoding
The Snake encoding allows a portion of data to be stored in a standardized cell, with the remainder stored recursively in child cells. In this scheme, Snake-encoded data is typically prefixed with the0x00 byte (see the note below for exceptions). TL-B schema:
TL-B
bufferToChunks, BitBuilder, and BitReader are provided by the surrounding tooling and helper utilities.TypeScript
0x00 byte prefix is not always required in the root cell when using Snake, for example, with off-chain NFT content. Also, cells are filled with bytes rather than bits to simplify parsing. To avoid issues when adding a reference in a child cell after it has already been written to its parent, the Snake cell is constructed in reverse order.
Chunked encoding
The chunked encoding stores data in a dictionary that mapschunk_index to a chunk. Chunked encoding must be prefixed with the 0x01 byte. This in-structure marker is distinct from the top-level content marker 0x01 that indicates off-chain content. TL-B schema:
TL-B
TypeScript
NFT metadata attributes
| Attribute | Type | Requirement | Description |
|---|---|---|---|
uri | ASCII string | optional | A URI pointing to a JSON document with metadata used by the semi-chain content layout. |
name | UTF-8 string | optional | Identifies the asset. |
description | UTF-8 string | optional | Describes the asset. |
image | ASCII string | optional | A URI pointing to a resource with an image MIME type. |
image_data | binary | optional | Either a binary representation of the image for the on-chain layout or base64 for the off-chain layout. |
Jetton metadata attributes
| Attribute | Type | Requirement | Description |
|---|---|---|---|
uri | ASCII string | optional | A URI pointing to a JSON document with metadata used by the semi-chain content layout. |
name | UTF-8 string | optional | Identifies the asset. |
description | UTF-8 string | optional | Describes the asset. |
image | ASCII string | optional | A URI pointing to a resource with an image MIME type. |
image_data | binary | optional | Either a binary representation of the image for the on-chain layout or base64 for the off-chain layout. |
symbol | UTF-8 string | optional | Token symbol — for example, “XMPL” — used in the form “You have received 99 XMPL”. |
decimals | UTF-8 string | optional | The number of decimal places used by the token. If not specified, the default is 9. A UTF-8–encoded string containing a number from 0 to 255; for example, 8 means the on-chain amount must be divided by 100000000 to get the user-facing representation. |
amount_style | string | optional | Defines how token amounts should be displayed for external applications. One of n, n-of-total, %. |
render_type | string | optional | Indicates how external applications should categorize and render the token. currency — display as a currency (default). game — game-style display: renders like an NFT, also shows the number of tokens, and respects amount_style. |
amount_style
n— number of jettons (default). If the user has 100 tokens with 0 decimals, display 100.n-of-total— the number of jettons out of the total issued. For example, if thetotalSupplyis 1000 and the user has 100, display “100 of 1000” (or an equivalent representation of the ratio).%— the percentage of total issued jettons. For example, with a total of 1000 and a user balance of 100, display 10% (100 ÷ 1000 = 0.1).
render_type
currency— display as a currency (default).game— game-style display that appears as an NFT, shows the number of tokens, and respectsamount_style.
Parsing metadata
To parse metadata, first retrieve the NFT data from the blockchain. For details, see retrieving NFT data. After the on-chain NFT data is retrieved, determine the content type by reading the first byte of the content, then parse accordingly.Off-chain
If the metadata byte string starts with0x01, the content is off-chain. Decode the remainder using Snake as an ASCII string to obtain the URL. Once you fetch the off-chain metadata and identification data, the process is complete. Example URL for off-chain NFT metadata:
https://s.getgems.io/nft/b/c/62fba50217c3fe3cbaad9e7f/95/meta.json
Contents of the referenced URL:
json
On-chain and semi-chain
If the metadata byte string starts with0x00, it indicates on-chain or semi-chain NFT metadata.
The metadata is stored in a dictionary where the key is the SHA-256 hash of the attribute name, and the value is data stored using the Snake or chunked format.
Read known attributes such as uri, name, image, description, and image_data. If the uri field is present, the layout is semi-chain: download the off-chain content specified by uri and merge it with the dictionary values.
Examples:
On-chain NFT: EQBq5z4N_GeJyBdvNh4tPjMpSkA08p8vWyiAX6LNbr3aLjI0
Semi-chain NFT: EQB2NJFK0H5OxJTgyQbej0fy5zuicZAXk2vFZEDrqbQ_n5YW
On-chain jetton master: EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs
How to parse
Use the following API to parse metadata: API Metadata. It handles most cases within gas limits; in rare cases, parsing may fail.Important notes on NFT metadata
- For NFT metadata, the
name,description, andimage(orimage_data) fields are commonly used to display the NFT. - For jetton metadata, the
name,symbol,decimals, andimage(orimage_data) fields are commonly used. - Anyone can create an NFT or jetton using any
name,description, orimage. To prevent scams and confusion, apps should clearly distinguish tokens by their address rather than by names or tickers. - Some items may include a
videofield linking to video content associated with the NFT or jetton.