Gas Model в TON
Три типа fees
В TON стоимость транзакции складывается из трёх независимых компонент:
Transaction Phases
Каждая транзакция проходит 5 фаз:
Transaction Phases:
1. Storage Phase
→ Списать накопленный storage fee с баланса контракта
→ Если баланс < 0 → freeze контракт
2. Credit Phase
→ Зачислить value из входящего сообщения на баланс
3. Compute Phase
→ Выполнить TVM код
→ Списать compute fee
→ Если gas закончился → abort
4. Action Phase
→ Отправить исходящие сообщения
→ Списать forward fee за каждое сообщение
5. Bounce Phase (если compute failed + bounce: true)
→ Создать bounce message
→ Вернуть оставшийся value
Storage Phase ПЕРВАЯ
Storage fee списывается ДО зачисления value из сообщения. Если контракт долго не получал сообщений и накопил storage debt — весь value может уйти на погашение debt, и на compute не останется.
Compute Fee: формулы
compute_fee = gas_used × gas_price
gas_price ≈ 1000 nanoton per gas unit (basechain, текущий)
= 0.000001 TON per gas unit
Примеры:
Simple transfer: ~3,000 gas = ~0.003 TON
Jetton transfer: ~10,000 gas = ~0.01 TON
DEX swap: ~30,000 gas = ~0.03 TON
Deploy contract: ~5,000 gas = ~0.005 TON
Что стоит дорого в gas
| Операция | Gas Cost | Почему дорого |
|---|---|---|
| Cell load | ~100 gas | Загрузка cell из storage |
| Cell store | ~500 gas | Запись cell в storage |
| Hash computation | ~50 gas per 256 bits | Криптография |
| Dict get/set | ~3,000-50,000 gas | Traversal Patricia trie |
| Message send | ~1,000 gas + forward fee | Serialization + routing |
Forward Fee: формулы
forward_fee = lump_price + cells × cell_price + bits × bit_price
Текущие параметры (basechain):
lump_price = 400,000 nanoton (~0.0004 TON)
cell_price = 400,000 nanoton per cell
bit_price = 1 nanoton per bit
Пример (Jetton transfer message, ~2 cells, ~700 bits):
forward_fee = 0.0004 + 2 × 0.0004 + 700 × 0.000000001
≈ 0.0012 TON
Storage Fee: формулы
storage_fee = cells × cell_price_per_second + bits × bit_price_per_second
storage_fee_per_second = cells × 1 + bits × 1 (nanoton, approximate)
Annual fee ≈ cells × 31.5M + bits × 31.5M (nanoton)
≈ 0.0000315 TON per cell per year
≈ 0.00036 TON per KB per year
Design Implications
1. Минимизируйте outgoing messages
Каждое исходящее сообщение = forward_fee. Меньше messages = дешевле:
[NO] 5 notifications (5 × forward_fee):
send(user, "swap done");
send(analytics, "swap event");
send(admin, "swap log");
send(treasury, "fee");
send(referral, "bonus");
[OK] 2 messages (2 × forward_fee):
send(user, "swap done + excess");
emit_log("swap_event"); // off-chain indexers подхватят
// treasury fee = deducted from swap, no separate message
// referral = batched, not per-swap
2. Рассчитайте gas budget для всей операции
DEX Swap Gas Budget:
User → DEX Pool: external msg
Forward: ~0.001 TON
DEX Pool compute:
Load state: ~500 gas
Verify sender: ~200 gas
Calculate output: ~1,000 gas
Update reserves: ~500 gas
→ Compute: ~0.003 TON
DEX Pool → User Jetton Wallet: internal msg
Forward: ~0.001 TON
User Jetton Wallet compute:
Process transfer: ~5,000 gas
→ Compute: ~0.005 TON
Total ≈ 0.01 TON per swap
User should send ≈ 0.05 TON (with safety margin)
Excess returned to user
3. Gas price может меняться
Network config parameters определяют gas prices. Валидаторы могут изменить через голосование:
[WARN] Не хардкодьте gas amounts!
[NO] send(target, ton("0.05"), body); // hardcoded
[OK] int fee = get_forward_fee(cells, bits) + estimated_compute + MARGIN;
send(target, fee, body);
Системные принципы gas-оптимизации лучше всего ложатся на конкретные FunC/Tolk-техники: какие инструкции TVM дёшевы, как переиспользовать cells, какие конструкции компилятор оптимизирует, а какие — нет. Практический разбор — в курсе по TON.
FunC/Tolk: оптимизация газа на практике