Разработка dApp на TON blockchain

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка dApp на TON blockchain
Сложная
~2-4 недели
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка dApp на TON blockchain

TON — это не «Ethereum с другим синтаксисом». Это принципиально другая архитектурная модель, в которой большинство паттернов EVM не работают или работают наоборот. Разработчик, впервые переходящий с EVM, потратит неделю только на то, чтобы перестать думать категориями Solidity. Асинхронные сообщения между контрактами, cell-based хранилище, Actor model, отсутствие атомарных транзакций через несколько контрактов — это не ограничения, это дизайн.

Архитектурные особенности TON

Actor model и асинхронные сообщения

В EVM транзакция может вызвать N контрактов синхронно и атомарно. В TON каждый смарт-контракт — это Actor, принимающий сообщения. Вызов другого контракта — это отправка асинхронного сообщения, которое будет обработано в следующем блоке (или позже).

Последствия для разработки:

  • Нет понятия «atomic composability» между несколькими контрактами
  • Паттерн «check → effect → interact» (CEI) из EVM здесь не применяется напрямую
  • Ответ от другого контракта приходит через recv_internal как входящее сообщение
  • Ошибка во вложенном контракте не откатывает весь chain — нужно явно обрабатывать bounce messages
;; Отправка внутреннего сообщения с обработкой bounce
send_raw_message(
  begin_cell()
    .store_uint(0x18, 6)    ;; bounce flag = 1
    .store_slice(destination_address)
    .store_coins(amount)
    .store_uint(0, 107)     ;; default message flags
    .store_ref(message_body)
  .end_cell(),
  64  ;; mode: carry remaining gas
);

Bounce сообщения — это TON-специфичный механизм возврата: если целевой контракт не существует или вернул ошибку, отправителю приходит bounce с возвратом TON. Обрабатывать bounce обязательно, иначе TON просто «исчезнут».

FunC и Tact: выбор языка

FunC — нативный язык TON контрактов. Низкоуровневый, работает с cells и slices напрямую. Необходим для максимальной оптимизации газа или при написании нестандартных контрактов. Синтаксис непривычный — функции в стиле lisp, глобальный стек TVM.

Tact — высокоуровневый язык, компилируется в FunC. Появился в 2023, активно развивается. Для большинства dApp сегодня Tact — правильный выбор: знакомый синтаксис, типобезопасность, встроенные паттерны для jetton/NFT.

// Tact: jetton transfer с callback
message JettonTransfer {
    queryId: Int as uint64;
    amount: Int as coins;
    destination: Address;
    responseDestination: Address?;
    forwardTonAmount: Int as coins;
    forwardPayload: Slice as remaining;
}

contract JettonWallet {
    receive(msg: JettonTransfer) {
        // Проверка sender - только master контракт или другой wallet
        require(sender() == self.master || sender() == self.owner, "Unauthorized");
        // Отправка notify покупателю
        if (msg.forwardTonAmount > 0) {
            send(SendParameters{
                to: msg.destination,
                value: msg.forwardTonAmount,
                body: JettonNotification{ amount: msg.amount }.toCell()
            });
        }
    }
}

Cell-based хранилище

В EVM данные хранятся в storage slots (uint256 слоты). В TON — в cells: древовидная структура, где каждая cell содержит до 1023 бит данных и до 4 ссылок на другие cells. Это позволяет хранить произвольные структуры, но требует явной сериализации/десериализации.

Стандарт хранилища контракта — через load_data() / save_data():

;; FunC: загрузка состояния из cell
(slice owner, int balance, cell metadata) load_data() inline {
    slice ds = get_data().begin_parse();
    return (
        ds~load_msg_addr(),   ;; 267 бит - адрес
        ds~load_coins(),      ;; переменная длина - coins
        ds~load_ref()         ;; ссылка на cell с метаданными
    );
}

Важное ограничение: максимальный размер state контракта — 65536 cells. Для коллекций NFT или jetton с тысячами держателей данные хранятся в отдельных контрактах для каждого пользователя — паттерн, где master контракт деплоит child контракты (wallet контракты для jetton, item контракты для NFT).

TEP стандарты: Jetton и NFT

Jetton (TEP-74/TEP-89)

Jetton — аналог ERC-20 в TON. Но архитектура принципиально другая. В EVM один ERC-20 контракт хранит mapping(address → balance). В TON:

  • Jetton Master — хранит общие параметры (totalSupply, metadata, admin)
  • Jetton Wallet — отдельный контракт для каждого держателя, хранит его баланс

При переводе: отправитель отправляет сообщение transfer своему Jetton Wallet → тот отправляет internal_transfer Jetton Wallet получателя → тот уведомляет получателя через transfer_notification.

Три контракта, три асинхронных сообщения, три блока минимум. Gas распределяется между ними — нужно отправлять достаточно TON для покрытия gas на всех уровнях.

NFT (TEP-62/TEP-64)

Аналогично Jetton: NFT Collection контракт + отдельный NFT Item контракт для каждого токена. Item хранит owner, individual_content, collection_address. Минт — это деплой нового Item контракта.

// NFT Collection: минт нового item
receive(msg: Mint) {
    let itemAddress = contractAddress(initOf NftItem(
        self.nextItemIndex,
        myAddress(),   // collection address
        msg.owner,
        msg.content
    ));
    // Деплой через StateInit
    send(SendParameters{
        to: itemAddress,
        value: ton("0.05"),   // gas для деплоя и инициализации
        code: codeOf NftItem,
        data: NftItem.init(self.nextItemIndex, myAddress(), msg.owner, msg.content),
        body: "Deploy".asComment()
    });
    self.nextItemIndex += 1;
}

TON Connect и фронтенд

TON Connect 2.0

Аналог WalletConnect для TON. Поддерживается Tonkeeper, MyTonWallet, OpenMask. Реализация на React:

import { TonConnectUIProvider, TonConnectButton, useTonConnectUI, useTonAddress } from '@tonconnect/ui-react';

function App() {
  return (
    <TonConnectUIProvider manifestUrl="https://your-dapp.com/tonconnect-manifest.json">
      <DappContent />
    </TonConnectUIProvider>
  );
}

function DappContent() {
  const userAddress = useTonAddress();
  const [tonConnectUI] = useTonConnectUI();

  async function sendTransaction() {
    await tonConnectUI.sendTransaction({
      messages: [{
        address: CONTRACT_ADDRESS,
        amount: toNano('0.1').toString(),
        payload: beginCell()
          .storeUint(0x5fcc3d14, 32)  // op code transfer
          .storeUint(queryId, 64)
          .endCell()
          .toBoc()
          .toString('base64')
      }]
    });
  }
  // ...
}

tonconnect-manifest.json — обязательный файл, описывает dApp для кошелька. Должен быть доступен по публичному URL.

Telegram Mini Apps интеграция

Для TON экосистемы Telegram Mini Apps — первоклассный deployment target. Пользователи не устанавливают кошелёк отдельно — Tonkeeper встроен. Telegram Web App API предоставляет контекст пользователя:

import WebApp from '@twa-dev/sdk';

// Инициализация Telegram Mini App
WebApp.ready();
WebApp.expand(); // полноэкранный режим

// Данные пользователя из Telegram (не требуют wallet connection для базового UX)
const user = WebApp.initDataUnsafe.user;

// MainButton для primary action
WebApp.MainButton.setText('Подтвердить транзакцию');
WebApp.MainButton.onClick(() => sendTransaction());
WebApp.MainButton.show();

Архитектура Mini App: Vite + React + TON Connect UI React. Деплой на любой HTTPS хостинг. Bot создаётся через @BotFather, Mini App регистрируется через /newapp.

Тестирование и инфраструктура

Testnet и локальная среда

TON Testnet (testnet.toncenter.com) — для интеграционных тестов. Testnet TON получают через @testgiver_ton_bot. Важно: адреса mainnet и testnet несовместимы (разные workchain параметры).

Для unit тестов — @ton-community/sandbox (ton-core) позволяет запускать контракты локально без нод:

import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox';
import { JettonMaster } from '../wrappers/JettonMaster';

describe('Jetton', () => {
  let blockchain: Blockchain;
  let deployer: SandboxContract<TreasuryContract>;
  let jettonMaster: SandboxContract<JettonMaster>;

  beforeEach(async () => {
    blockchain = await Blockchain.create();
    deployer = await blockchain.treasury('deployer');
    jettonMaster = blockchain.openContract(
      await JettonMaster.fromInit(deployer.address, Cell.fromBase64(metadata))
    );
    await jettonMaster.send(deployer.getSender(), { value: toNano('0.5') }, 'Deploy');
  });

  it('should mint tokens', async () => {
    const result = await jettonMaster.send(deployer.getSender(), 
      { value: toNano('0.1') }, 
      { $$type: 'Mint', amount: toNano('1000'), receiver: deployer.address }
    );
    expect(result.transactions).toHaveTransaction({ success: true });
  });
});

Blueprint framework

Blueprint — официальный инструмент разработки TON контрактов. Аналог Hardhat/Foundry для TON:

npm create ton@latest
# Создаёт структуру: contracts/, wrappers/, tests/, scripts/

Wrappers — TypeScript обёртки над контрактами, генерируются из Tact или пишутся вручную для FunC. Используются и в тестах, и во фронтенде.

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

Контракты: Tact 1.x (preferred) или FunC. Blueprint для тестирования и деплоя.

Frontend: React + Vite (для Mini Apps) или Next.js (для web dApp). TON Connect UI React, @ton/ton, @ton/core для работы с блокчейном.

Backend (если нужен): TON API (toncenter.com) или TON HTTP API v2. Для production — собственная нода через mytonctrl или использование QuickNode/Tatum для TON.

Компонент Технология
Смарт-контракты Tact + Blueprint
Wallet connection TON Connect 2.0
Web frontend Next.js + TON Connect UI
Telegram Mini App Vite React + @twa-dev/sdk
Тесты @ton/sandbox + Jest/Vitest
Деплой контрактов Blueprint deploy scripts

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

Простой dApp: один контракт (Tact) + web frontend с TON Connect — 2-3 недели (с учётом кривой обучения TON архитектуры если команда с EVM бэкграундом). Telegram Mini App с jetton интеграцией, стейкингом и leaderboard — 4-6 недель. Полноценный DeFi протокол (AMM или lending) на TON с аудитом — 2-4 месяца. Асинхронная природа TON требует значительно большего тестирования message chains по сравнению с EVM.