Разработка смарт-контрактов на FunC (TON)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка смарт-контрактов на FunC (TON)
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1258
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1170
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    873
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1092
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    830

Разработка смарт-контрактов на FunC (TON)

TON — это не ещё один EVM-клон. Разработчик, который приходит с опытом Solidity, первые две недели проводит в состоянии лёгкого шока: стек-ориентированная виртуальная машина TVM, ячеистая модель хранения данных через Cell, асинхронная передача сообщений между контрактами, и FunC — язык, который выглядит как функциональный C с элементами Lisp. Это не недостатки, это архитектурные решения, которые дают TON уникальные свойства масштабируемости. Но кривая обучения резкая.

Как устроен TON изнутри

TVM и Cell — не то, к чему вы привыкли

В EVM контракт — это байткод, storage — это key-value хранилище с 32-байтными слотами. В TVM контракт хранится как дерево Cell-объектов. Каждая Cell — это до 1023 бит данных и до 4 ссылок на другие Cell. Storage контракта — это тоже Cell-дерево, которое целиком загружается при каждом вызове и целиком сохраняется обратно.

Это влечёт конкретные следствия. Нет слот-коллизий как в EVM proxy. Нет проблемы unbounded storage growth в том же смысле. Но есть своя боль: чтение глубоко вложенной структуры данных требует последовательного разбора Cell через begin_parse() / load_uint() / load_ref(). Забудешь порядок полей при десериализации — получишь неверные данные без ошибки компилятора.

Асинхронная модель сообщений

В Solidity contractA.functionB() — это синхронный вызов в рамках одной транзакции. В TON всё иначе: контракты общаются через сообщения, каждое из которых обрабатывается в отдельной транзакции. Если контракт A отправляет сообщение контракту B, который отправляет сообщение контракту C — это три отдельные транзакции в трёх отдельных блоках.

Это ломает привычные паттерны. Атомарная операция «проверь баланс — переведи — обнови состояние» становится последовательностью сообщений с промежуточными состояниями. Нужна явная машина состояний в storage контракта. Нужны timeout-механизмы для незавершённых операций. Нужна обработка bounce-сообщений — когда целевой контракт не может принять сообщение и возвращает его отправителю.

Пропустить обработку bounce — типичная ошибка новичков в TON. Контракт отправляет TON другому контракту, тот реверсируется, coins возвращаются как bounce-сообщение. Если отправитель не обработал bounce — coins уходят в никуда (точнее, обрабатываются дефолтным receive-хендлером и теряются из логики).

Gas-модель в TON

В TON нет привычного gas limit на транзакцию в том же смысле. Есть storage fees — контракт платит за хранение своего состояния каждую секунду. Контракт с большим storage и нулевым балансом в какой-то момент будет заморожен. Это нужно учитывать при проектировании: контракты-хранилища данных (например, индивидуальные jetton-кошельки) должны иметь механизм пополнения или минимальный баланс.

Как мы пишем контракты на FunC

Стек разработки

Blueprint — стандартный инструмент для разработки и тестирования TON-контрактов. Предоставляет окружение для локального запуска TVM, написания тестов на TypeScript, деплоя через кастомизируемые скрипты.

toncli используем для быстрого прототипирования и работы с legacy-кодом. Для новых проектов — Blueprint предпочтительнее из-за лучшей интеграции с TypeScript.

Tact — высокоуровневый язык поверх FunC, который значительно снижает порог входа и количество ошибок при работе с Cell-структурами. Рассматриваем его для проектов, где скорость разработки важнее максимального контроля над байткодом. FunC — там, где нужна ручная оптимизация.

Официальные стандарты: TEP-74 (Jetton — аналог ERC-20), TEP-62 (NFT — аналог ERC-721), TEP-64 (метаданные токенов). OpenZeppelin-аналога в TON нет — есть референсные имплементации от команды TON Foundation, которые используем как базу.

Паттерны для асинхронных операций

State machine в storage. Каждая многошаговая операция имеет явный статус: pending, processing, completed, failed. Сообщения проверяют текущий статус перед переходом в следующее состояние. Без этого параллельные сообщения могут привести к непредсказуемому результату.

Timeout и cleanup. Операция в статусе processing более N секунд — автоматический rollback через отдельное сообщение от самого контракта (через send_raw_message с задержкой через внешние инструменты или хранение timestamp в storage).

Outgoing message routing. Все bounce-хендлеры явно задокументированы в коде. Паттерн: отдельная функция-диспетчер, которая по op-code определяет, что делать с bounce. Потеря средств из-за необработанного bounce — некомпенсируемая.

Типичная ошибка при работе с Jetton

Jetton-архитектура в TON шардированная: у каждого пользователя — отдельный контракт-кошелёк (Jetton Wallet), которым управляет Jetton Minter. Transfer — это два сообщения: от кошелька-отправителя к кошельку-получателю. Если получатель — контракт, который хочет «знать» о полученных jetton, он должен обработать transfer_notification сообщение.

Стандартная ошибка: контракт-получатель не реализует обработчик transfer_notification — jetton приходят, но контракт «не знает» об этом и не меняет состояния. Дальше — баг в бизнес-логике, который проявляется не сразу.

Сравнение TON и EVM для задач разработки

Характеристика TON / FunC EVM / Solidity
Модель выполнения Асинхронные сообщения Синхронные вызовы
Хранение данных Cell-деревья Key-value slots
Язык FunC / Tact Solidity / Vyper
Стандарты токенов TEP-74 (Jetton), TEP-62 (NFT) ERC-20, ERC-721, ERC-1155
Атомарность операций Нет (несколько транзакций) Да (одна транзакция)
Storage fees Да (periodic) Нет
Скорость транзакций <5 секунд 12-60 секунд (Ethereum)
Аудит-инструменты Ограниченный набор Slither, Mythril, Echidna

Таблица показывает, что TON не «лучше» или «хуже» — он другой. Для задач с высоким TPS и дешёвыми транзакциями (payments, gamefi, miniapps в Telegram) — архитектура TON оптимальна. Для сложной DeFi-логики с atomic composability — EVM-экосистема проще в реализации.

Процесс разработки TON-контракта

Проектирование message flow (3-5 дней). До написания кода — полная диаграмма всех сообщений: op-code, направление, что происходит при bounce. Это критически важно именно для TON из-за асинхронности.

Разработка на FunC + тесты на TypeScript (1-3 недели). Blueprint-тесты покрывают happy path и все bounce-сценарии. Эмуляция TVM локально даёт полную трассировку транзакций.

Ревью storage layout. Проверяем порядок сериализации/десериализации Cell, корректность обработки bounce, отсутствие хендлеров-«пустышек» для неизвестных op-code.

Деплой на testnet (Testnet TON) → mainnet. Верификация исходного кода через TON Verifier.

Ориентиры по срокам

Базовый Jetton-контракт (TEP-74 совместимый) — 3-5 дней. NFT-коллекция с кастомной логикой (TEP-62) — 1-2 недели. Сложный протокол с несколькими взаимодействующими контрактами и стейт-машиной — от 4 недель. Интеграция с Telegram Mini App через tonconnect — добавляет 3-7 дней на клиентскую часть.

Стоимость рассчитывается индивидуально после разбора архитектуры.