Минт jetton-токена

Заминтишь jetton через master: поймёшь роль admin, тело mint-сообщения и куда приходят токены.

Кто минтит и куда падают токены

Минт делает только admin master-контракта. Master увеличивает total_supply и шлёт internal_transfer на jetton-wallet получателя. В mint передаёшь адрес owner (обычный кошелёк) — master сам резолвит/деплоит его jetton-wallet.

Admin задаётся при деплое. Потерял ключ admin — минт и смена метаданных недоступны (если контракт не предусматривает recovery).


Собираем mint-сообщение (эталонный JettonMinter)

typescript
// @ton/core ^0.59.0, @ton/ton ^15.1.0, @ton/blueprint ^0.27.0
// Layout: ton-blockchain/jetton-contract JettonMinter
// mint#642b7d07 query_id to_address ton_amount master_msg:^Cell
import { Address, beginCell, toNano } from "@ton/core";
import { NetworkProvider } from "@ton/blueprint";

const OP_MINT = 0x642b7d07;
const OP_INTERNAL_TRANSFER = 0x178d4519;

function buildMint(opts: {
  owner: Address;
  jettonAmount: bigint;
  forwardTon: bigint;
  queryId?: bigint;
}) {
  const q = opts.queryId ?? 0n;

  // master_msg: то, что master перешлёт на jetton-wallet получателя
  const masterMsg = beginCell()
    .storeUint(OP_INTERNAL_TRANSFER, 32)
    .storeUint(q, 64)
    .storeCoins(opts.jettonAmount)
    .storeAddress(null) // from (mint): пустой адрес
    .storeAddress(opts.owner) // response_destination (excesses)
    .storeCoins(opts.forwardTon)
    .storeBit(false) // no forward_payload
    .endCell();

  return beginCell()
    .storeUint(OP_MINT, 32)
    .storeUint(q, 64)
    .storeAddress(opts.owner) // чей jetton-wallet получит токены
    .storeCoins(toNano("0.05")) // Gram, который master приложит к internal_transfer
    .storeRef(masterMsg)
    .endCell();
}

export async function run(provider: NetworkProvider) {
  const sender = provider.sender();
  if (!sender.address) throw new Error("Wallet not connected");

  // Адрес ТВОЕГО JettonMinter после деплоя (не чужой mainnet-токен)
  const master = Address.parse(
    "EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c", // ← замени
  );
  const recipient = Address.parse(
    "EQCD39VS5jcptHL8vMjEXrzGaRcCVYto7HUn4bpAOg8xqB2N",
  );

  // decimals=9 → 1.0 jetton = 1_000_000_000n
  await sender.send({
    to: master,
    value: toNano("0.1"), // газ admin→master + master→wallet
    body: buildMint({
      owner: recipient,
      jettonAmount: 1_000_000_000n,
      forwardTon: toNano("0.01"),
    }),
  });
}

Перед mainnet сверь OP_MINT и layout с исходником своего master (Tact-шаблон Blueprint может отличаться opcode). Расхождение = failed compute phase.

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

  • Внешнее сообщение → master, отправитель должен быть admin.
  • owner — адрес кошелька пользователя, не jetton-wallet.
  • master_msg с internal_transfer увеличивает balance на wallet получателя и при необходимости деплоит wallet.
  • Внешний value (здесь 0.1 GRAM) покрывает всю цепочку; ton_amount внутри mint — сколько master кладёт в сообщение на wallet.

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

Минтишь не с admin-ключа → master отклоняет; supply не растёт.

Передал jetton-wallet вместо owner → minter создаст wallet «от имени» контракта-кошелька. Всегда передавай owner-кошелёк.

Мало Gram в value / ton_amount → не хватает на деплой wallet или gas; mint падает или bounce.


Что дальше

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