Соберёшь off-chain метаданные NFT по TEP-64: полный JSON коллекции и айтема, on-chain ссылка и get_nft_content.
Где лежат метаданные
TEP-64 допускает off-chain (в контракте — URI на JSON) и on-chain (поля в cell). Off-chain — основной путь для картинок и атрибутов: collection хранит common prefix, item — суффикс (0.json), get_nft_content склеивает полный URL.
Кошельки и маркетплейсы (Getgems, Tonkeeper) читают JSON по HTTP(S)/IPFS. Битая ссылка = «пустой» NFT в UI при живом on-chain владении.
JSON коллекции и айтема + ссылка в контракте
Полный off-chain JSON коллекции (collection.json):
// @ton/core ^0.59.0// TEP-64: off-chain content = 0x01 + URL stringimport { beginCell, Cell } from "@ton/core";/** Off-chain content cell: первый байт 0x01, далее UTF-8 URI */export function offchainContent(uri: string): Cell { return beginCell() .storeUint(0x01, 8) .storeStringTail(uri) .endCell();}// Collection content: часто два ref — collection meta + common item prefixexport function buildCollectionContent(opts: { collectionMetaUrl: string; // https://example.com/nft/collection.json commonItemPrefix: string; // https://example.com/nft/}) { return beginCell() .storeRef(offchainContent(opts.collectionMetaUrl)) .storeRef(offchainContent(opts.commonItemPrefix)) .endCell();}// Item individual content — только суффикс; collection.get_nft_content склеитexport function buildItemIndividualContent(suffix: string): Cell { // suffix = "0.json" → полный URL = commonPrefix + "0.json" return offchainContent(suffix);}
Проверка полного контента айтема:
typescript
// get_nft_content(index, individual_content) на collection → full URI cellconst full = await client.runMethod(collection, "get_nft_content", [ { type: "int", value: 0n }, { type: "cell", cell: individualContent },]);const fullContent = full.stack.readCell();// Парсишь 0x01 + string → https://example.com/nft/0.json
Как это работает
0x01 в начале content cell = off-chain; 0x00 = on-chain dict (реже для картинок).
Collection дедуплицирует prefix: меняешь common URL один раз — обновляются все айтемы (если item хранит только суффикс).
name / image / attributes читает индексатор; on-chain хранит лишь ссылку.
IPFS (ipfs://...) тоже off-chain: нужен gateway у клиента или CDN перед ним.
Частые ошибки
Кладешь полный URL в item и другой prefix в collection → get_nft_content даёт кашу или двойной путь. Либо полный URI в item, либо prefix+suffix — единообразно.
JSON без image / с относительным путём → кошелёк не рисует превью.
HTTP без CORS / 404 после минта → on-chain owner есть, в UI «Unknown NFT». Проверь URL до деплоя.
Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация