Learning Platform
Глоссарий Troubleshooting
Урок 05.02 · 22 мин
Продвинутый
JettonToken StandardSharded TokenMaster-Wallet Pattern

Jetton Pattern: эталон шардированного токена

Проблема: ERC-20 не масштабируется

На Ethereum, ERC-20 хранит все балансы в одном контракте:

// Ethereum ERC-20 — монолитный
contract Token {
    mapping(address => uint256) balances;  // ВСЕ пользователи здесь
    
    function transfer(to, amount) {
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }
}

На Ethereum это нормально (нет шардирования). На TON — bottleneck.

Решение: Jetton = Master + N Wallets

Jetton Standard разделяет state:

Jetton Architecture: Master + Wallets
Jetton Master
Alice Wallet
Bob Wallet
Carol Wallet

Transfer Flow: 3 сообщения

Перевод 100 tokens от Alice к Bob:

Шаг 1: Alice → Alice's Wallet: "transfer(100, Bob)"
  Alice's Wallet:
    - Проверить: owner == Alice? [OK]
    - Проверить: balance >= 100? [OK]
    - balance -= 100 (Alice: 500 → 400)
    - Вычислить адрес Bob's Wallet: hash(wallet_code + init_data(Bob, master))
    - Отправить internal_transfer(100, Alice) → Bob's Wallet

Шаг 2: Alice's Wallet → Bob's Wallet: "internal_transfer(100, from=Alice)"
  Bob's Wallet:
    - Проверить: sender == valid Jetton Wallet? (code hash verification)
    - balance += 100 (Bob: 300 → 400)
    - Если Bob's Wallet не существовал — deploy (init_code in message)
    - Отправить transfer_notification(100, Alice) → Bob

Шаг 3: Bob's Wallet → Bob: "transfer_notification(100, from=Alice)"
  Bob (может быть контракт или кошелёк):
    - Получает уведомление: "вам перевели 100 tokens от Alice"
    - Может обработать: например, DEX обработает swap

Почему deploy при первом получении?

Если Bob никогда не получал этот токен — его Wallet-контракт не существует. Sender (Alice’s Wallet) включает state_init в сообщение — это деплоит Bob’s Wallet автоматически. TON достаточно умён, чтобы проигнорировать state_init, если контракт уже задеплоен.

Канонические Jetton-стандарты и эталонные реализации

“Jetton 2.0” — это маркетинговое название, не отдельный стандарт. На практике production Jetton-контракт собирается из нескольких канонических TEP’ов:

СтандартЧто описываетРеальность 2025-2026
TEP-74Базовый Jetton (Master + Wallet, transfer, internal_transfer)Обязательная база. Все Jetton’ы реализуют TEP-74.
TEP-89Discoverable Wallets (provide_wallet_addresstake_wallet_address)Стало де-факто обязательным: индексеры и DEX полагаются на on-chain discovery, без TEP-89 интеграция ломается.
TEP-177Mintless Jettons (Merkle airdrop, claim прямо в Wallet)Используется массово в airdrop-проектах (DOGS, NotPixel, HMSTR) — claim без предварительного minting миллионам пользователей.

Эталонные репозитории, на которые стоит ориентироваться:

РепозиторийНазначение
ton-blockchain/stablecoin-contractCanonical reference Jetton (TEP-74 + TEP-89), реальная база для USDT-style стейблкоинов
ton-community/mintless-jettonReference impl TEP-177 (TEP-74 + TEP-89 совместимый)
EmelyanenkoK/modern_jettonGas-оптимизированный variant с улучшенной логикой forward-payload
TIP

Что реально стоит за “оптимизациями”

Когда в маркетинге говорят про “ускоренный Jetton” — обычно имеют в виду одно из двух: (1) переход на mintless схему (TEP-177), убирающую массовый pre-mint и снижающий нагрузку на сеть, или (2) обновлённый wallet code с оптимизированной gas-логикой (как в stablecoin-contract или modern_jetton). Базовый transfer flow остаётся 3-сообщенческим, как и в TEP-74.

Security: как Wallet верифицирует sender?

Проблема: подделка internal_transfer

Злоумышленник может попытаться отправить internal_transfer(1000000, fake) напрямую в Bob’s Wallet, чтобы зачислить себе токены.

Решение: Sender Address Verification

Bob's Wallet получает internal_transfer от sender_address:

1. Прочитать claimed_from из body (кто якобы отправил)
2. Вычислить: expected_sender = hash(wallet_code + init_data(claimed_from, master))
3. Проверить: sender_address == expected_sender?
4. Если нет — отклонить! (Sender не является легитимным Wallet)
TIP

Deterministic addresses = trustless verification

Wallet не хранит whitelist допустимых отправителей. Он вычисляет ожидаемый адрес sender-а из claimed data. Если вычисленный адрес != actual sender — сообщение поддельное. Это O(1) verification без storage overhead.

Design Insights для собственных контрактов

Jetton pattern — template для любого sharded state:

JettonВаш контракт
Master = metadata + total_supplyMaster = global config
Wallet = per-user balanceChild = per-user/per-entity state
transfer = wallet→walletoperation = child→child
internal_transfer = verified msgverified_operation = code hash check

Применяйте этот паттерн к:

  • NFT Collection: Collection (master) + Item (child per NFT)
  • Staking Pool: Pool (master) + Position (child per staker)
  • DEX: Pool (master) + LP Wallet (child per liquidity provider)
  • Voting: Proposal (master) + Vote (child per voter)
Проверка знанийKnowledge check
ОтветAnswer

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 2. Jetton transfer от Alice к Bob. Bob никогда не получал этот токен. Что произойдёт при получении internal_transfer?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5