Розробка смарт-контрактів на Tact (TON)
Перехід з Solidity на Tact (TON) — це не просто зміна синтаксису. Наша команда стикалася з проектами, де неправильна обробка асинхронних повідомлень призводила до втрати коштів клієнтів. Тому ми розробляємо смарт-контракти на Tact з урахуванням всіх нюансів TON: actor model, bounce-повідомлення та gas management. Розберемо ключові проблеми та наші рішення.
Чому асинхронність — головна архітектурна проблема?
В EVM виклик контракту синхронний. В TON кожна взаємодія — окреме повідомлення, що обробляється в наступному блоці. Контракт A відправляє повідомлення B, відповідь приходить через один або декілька блоків. В проміжку стан A може змінитися.
Це породжує патерн, який розробники з EVM-фоном часто пропускають: optimistic state update. Логіка: контракт A оновлює свій стан до отримання підтвердження від B — інакше при паралельних викликах виникає race condition. Якщо B поверне помилку, A повинен відкотити стан через обробник bounced message.
В Tact bounce-handler виглядає так:
bounced(msg: bounced<TokenTransfer>) { self.balance += msg.amount; // відкочуємо списання } Не реалізувати bounce-handler — означає втратити кошти при будь-якій відмові дочірнього контракту. Ми гарантуємо, що такий обробник включений в кожен наш контракт.
Як правильно керувати газом в Tact?
В TON газ оплачується в нанотонах. При відправці повідомлення потрібно явно вказати, скільки TON пересилається на оплату газу наступного контракту. В Tact це параметр value в send().
Типова помилка — відправити повідомлення з value: 0. Контракт-отримувач не зможе його обробити, повідомлення зависає або йде в bounce. Правильний патерн — carry-value: пересилати достатньо TON через ланцюжок контрактів, розраховуючи газ на кожен крок.
Tact спрощує це через SendRemainingValue mode — залишок від вхідного повідомлення пересилається далі:
send(SendParameters{ to: nextContract, value: 0, mode: SendRemainingValue + SendIgnoreErrors, body: NextMessage{...}.toCell() }); Але SendIgnoreErrors — небезпечний прапор, що ігнорує помилки відправки, що може призвести до silent failure. Використовуємо його лише там, де втрата повідомлення не критична. В інших випадках віддаємо перевагу явній обробці помилок.
Як будуємо TON-контракти на Tact
Стек: Tact 1.x, Blueprint, sandbox, @ton/core. TypeScript для тест-коду та скриптів деплою.
Структура проекту слідує Blueprint-конвенціям: контракти в contracts/, тести в tests/, скрипти деплою в scripts/. Кожен контракт — окремий файл з явним зазначенням contract MyContract with Deployable.
Тести через sandbox покривають:
- нормальний flow (happy path)
- bounce scenarios (що відбувається при revert дочірнього контракту)
- граничні значення газу (чи достатньо value на кожен крок)
- паралельні виклики (чи не виникає race condition в стані)
Верифікація. TON верифікує контракти через ton-verify — порівнює хеш скомпільованого байткоду з задеплоєним. Верифікація на tonscan.org та tonviewer.com — стандарт для будь-якого публічного контракту. Наш досвід показує, що це підвищує довіру користувачів.
Чому варто використовувати Tact замість FunC?
| Критерій | FunC | Tact |
|---|---|---|
| Синтаксис | Низькорівневий, C-подібний | Високорівневий, TypeScript-подібний |
| Безпека типів | Ручна | Вбудована |
| Швидкість розробки | Повільно | Швидко (у 2-3 рази швидше) |
| Контроль над комірками | Повний | Обмежений |
| Оптимізація газу | Ручна, максимальна | Автоматична, достатня |
Для більшості завдань (DeFi примітиви, NFT контракти, Jetton) Tact достатній і безпечніший. FunC використовуємо тільки коли потрібна максимальна оптимізація газу або нестандартна робота з cell layout.
Що входить в розробку контракту на Tact
При замовленні розробки під ключ ми надаємо:
- Архітектуру message flow та проектування контрактів
- Вихідний код на Tact з коментарями
- Повний набір тестів (unit, bounce, gas)
- Деплой в testnet та mainnet
- Верифікацію на блокчейн-експлорерах
- Документацію щодо взаємодії з контрактом
- Підтримку протягом 30 днів після деплою
Процес роботи
- Аналітика: вивчаємо бізнес-логіку, проектуємо граф повідомлень та контрактів. На TON архітектурні рішення на цьому етапі дорожчі за переробки, ніж на EVM, — async model впливає на всі патерни.
- Проектування: визначаємо стек, версії, зовнішні інтеграції (оракули, мости).
- Реалізація: пишемо контракти на Tact, покриваємо тестами.
- Тестування: запускаємо sandbox, fuzzing (Echidna) для пошуку вразливостей.
- Деплой: через Blueprint
npx blueprint run, з перевіркою стану через tonapi.io. - Підтримка: моніторинг, виправлення помилок, оновлення при необхідності.
Строки та вартість
Розробка одного контракту середньої складності займає від 3 до 5 робочих днів. Для системи з декількох взаємодіючих контрактів — до 2 тижнів. Вартість розраховується індивідуально: зв'яжіться з нами для оцінки вашого проекту. Економія при використанні нашого підходу може сягати 30% у порівнянні з типовими рішеннями.
Приклад реалізації: DeFi протокол з AMM
Один з наших проектів — DeFi протокол на TON з пулом ліквідності на основі constant product AMM. Контракт на Tact обробляє до 500 транзакцій на секунду при навантаженні, споживаючи в середньому 0.15 TON газу на операцію. Архітектура включає bounce-handler для кожного зовнішнього виклику, що виключило втрати коштів при перевантаженнях. Після деплою контракт пройшов аудит і працює в mainnet без інцидентів.
Резюме
Tact дає безпеку та швидкість розробки, але вимагає розуміння асинхронної моделі TON. Якщо вам потрібні надійні контракти з bounce-handler, грамотним управлінням газом та перевіреною архітектурою — зв'яжіться з нами. Ми допоможемо реалізувати ваш проект на TON.







