NFT-стандарт на TON: коллекции и айтемы

Поймёшь модель NFT на TON (TEP-62): зачем нужны collection и item, кто хранит owner и куда слать transfer.

Collection и item в NFT

NFT на TON (TEP-62) — не запись в mapping одного контракта. Collection знает, сколько айтемов выпущено, хранит общий контент и умеет посчитать адрес item по index. Item — отдельный смарт-контракт: у него свой адрес, owner и individual content. Метаданные — TEP-64; роялти — TEP-66 на collection.

text
Collection  EQ...COLL
  next_item_index, collection_content, owner
  get_nft_address_by_index(i) → EQ...ITEM_i

Item #0  EQ...ITEM_0  ← owner A, index 0
Item #1  EQ...ITEM_1  ← owner B, index 1

Владение и transfer живут в item. Collection не списывает NFT «за тебя».


Читаем collection и item

typescript
// @ton/ton ^15.1.0, @ton/core ^0.59.0
// Стандарты: TEP-62 (NFT), TEP-64 (metadata)
import { Address, TonClient } from "@ton/ton";

const client = new TonClient({
  endpoint: "https://toncenter.com/api/v2/jsonRPC",
});

const collection = Address.parse(
  "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", // ← адрес своей коллекции
);

// get_collection_data → (next_item_index, collection_content, owner_address)
const collData = await client.runMethod(collection, "get_collection_data");
const nextIndex = collData.stack.readNumber();
const owner = collData.stack.readAddress();
console.log({ nextIndex, owner: owner?.toString() });

// get_nft_address_by_index(0) → адрес item #0
const addrRes = await client.runMethod(collection, "get_nft_address_by_index", [
  { type: "int", value: 0n },
]);
const itemAddress = addrRes.stack.readAddress();

// get_nft_data на item → (init?, index, collection, owner, individual_content)
const itemData = await client.runMethod(itemAddress!, "get_nft_data");
const init = itemData.stack.readNumber();
const index = itemData.stack.readNumber();
const collFromItem = itemData.stack.readAddress();
const itemOwner = itemData.stack.readAddress();
console.log({
  init,
  index,
  collection: collFromItem?.toString(),
  owner: itemOwner?.toString(),
});

Как это работает

  • get_collection_data — счётчик айтемов, контент коллекции, owner коллекции (не owner айтема).
  • get_nft_address_by_index — детерминированный адрес item; можно узнать до деплоя.
  • get_nft_data на item — кто владеет NFT прямо сейчас (owner_address).
  • Item хранит ссылку на collection; перед доверием сверь: get_nft_address_by_index(index) == адрес item.

Частые ошибки

Шлёшь transfer на collection → collection не меняет owner айтема. Цель — адрес item.

Доверяешь только collection из item без проверки → поддельный item может указать любую коллекцию. Сверяй адрес через get_nft_address_by_index.

Путаешь owner коллекции и owner айтема → owner коллекции минтит/редактирует; owner айтема делает transfer.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация