Разработка смарт-контрактов на Michelson (Tezos)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка смарт-контрактов на Michelson (Tezos)
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • 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

Разработка смарт-контрактов на Michelson (Tezos)

Tezos — одна из немногих платформ, где смарт-контракты компилируются в стековый байткод Michelson, а не в EVM-опкоды. Это принципиальное отличие: если вы пришли с опытом Solidity, первое знакомство с Michelson вызывает что-то среднее между уважением и культурным шоком. Стековая машина, формальная верификация как первый класс, on-chain хранение типизировано до мелочей. При этом экосистема значительно меньше Ethereum — меньше готовых библиотек, меньше аудиторов, меньше паттернов. Ошибки здесь дороже обходятся.

Почему Michelson — это не просто «другой язык»

Большинство разработчиков пишут на высокоуровневых диалектах: SmartPy (Python-синтаксис), LIGO (диалекты CameLIGO, JsLIGO, PascaLIGO) или Archetype (для формальной верификации). Но Michelson — промежуточный слой, в который всё это компилируется, и понимать его необходимо.

Рассмотрим конкретную ситуацию: контракт на SmartPy собирается без ошибок, деплоится в тестнет Ghostnet, но при вызове через Taquito транзакция фейлится с FAILED: script_rejected. Без чтения Michelson-кода невозможно понять, в какой именно точке стек оказался в некорректном состоянии. Декомпилятор octez-client даёт сырой Michelson — и вот здесь начинается настоящая отладка.

Типичные ошибки при переходе с EVM

Storage layout не совпадает с ожиданиями. В Solidity storage — это слоты. В Tezos storage — это big_map и map, вложенные записи (record), option-типы. Разработчики, привыкшие к маппингам Solidity, иногда неправильно моделируют вложенные структуры в LIGO. В итоге get из big_map возвращает None там, где ожидался Some(value), потому что ключ был сконструирован неправильно.

Entrypoint routing. В Tezos контракт может иметь несколько точек входа (entrypoints), которые в Michelson реализуются через OR-дерево. SmartPy и LIGO генерируют это дерево автоматически, но если клиент (Taquito) вызывает entrypoint по имени, а имя в ABI не совпадает с именем в коде, транзакция отклоняется. Проблема особенно коварна при обновлении контракта — ABI в frontend может остаться от старой версии.

Gas estimation на FA2. Стандарт FA2 (аналог ERC-1155 в Tezos) предполагает batch-операции. При большом batch Taquito иногда недооценивает gas limit, и транзакция фейлится уже on-chain. Правильное решение — явно задавать storageLimit и gasLimit или использовать estimate() из Taquito с запасом 10-15%.

Стек и инструменты

Языки разработки

Язык Синтаксис Лучше всего для
SmartPy Python-подобный Быстрый прототип, тесты on-chain
CameLIGO OCaml-подобный Типобезопасность, крупные проекты
JsLIGO JavaScript-подобный Команды с JS-бэкграундом
Archetype Декларативный Формальная верификация через Why3
Michelson Стековый Аудит, оптимизация gas, отладка

Для production мы используем CameLIGO как основной язык. Статическая типизация в стиле OCaml устраняет целый класс ошибок ещё на этапе компиляции. SmartPy применяем для быстрых экспериментов и внутренних тестов.

Инфраструктура

  • octez-client — CLI для взаимодействия с нодой, деплой, вызов entrypoints, просмотр storage
  • Ligo CLI — компиляция, dry-run, генерация Michelson
  • Taquito — JavaScript-библиотека для frontend-интеграции (аналог ethers.js)
  • Better Call Dev — block explorer с удобным просмотром storage и вызовов
  • SmartPy IDE — для быстрого тестирования в браузере
  • Ghostnet — основной тестнет

Формальная верификация через Archetype

Архетип позволяет писать контракты с формальными спецификациями, которые затем верифицируются через Why3 и Alt-Ergo. Это не абстрактная возможность — мы применяли это на контракте escrow, где требовалось математически доказать, что средства никогда не могут быть заблокированы при любой последовательности вызовов. Верификация выявила один edge case: при определённой комбинации refund и claim в одном блоке контракт мог войти в состояние, из которого невозможно вывести средства. Ни unit-тесты, ни fuzzing это не нашли.

FA2 — стандарт, который нужно знать

FA2 (TZIP-12) — основной стандарт для токенов в Tezos. Аналог ERC-1155, но с более строгой спецификацией по операторам и проверкам разрешений. Реализация FA2 включает:

  • transfer — batch-трансфер с проверкой операторов
  • update_operators — добавление/удаление операторов для адреса
  • balance_of — запрос балансов (callback-паттерн, не view функция)

Callback-паттерн в balance_of — классический камень преткновения. В отличие от Solidity, где view-функция возвращает значение синхронно, в Tezos запрос баланса — это отдельная транзакция с callback-контрактом. Frontend должен либо читать storage напрямую через RPC, либо реализовывать on-chain callback. Taquito предоставляет fa2.getBalance() поверх прямого чтения storage.

Операторы vs. Allowances

В FA2 нет концепции allowance как в ERC-20. Вместо этого — операторы: адреса, которым разрешено управлять токенами от имени владельца. Это мощнее (оператор управляет всеми токенами сразу), но и опаснее: если не реализовать правильную проверку в transfer, оператор может перевести что угодно. TZIP-12 чётко специфицирует порядок проверок, и мы следуем ему строго.

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

Анализ требований. Определяем: нужен ли FA1.2 (аналог ERC-20) или FA2, есть ли batch-операции, нужна ли мультисиг-логика (аналог Gnosis Safe — Mulit-sig от Tezos Foundation).

Проектирование storage. Storage в Tezos — это состояние контракта, которое хранится on-chain и тарифицируется отдельно от gas. big_map — ленивая структура, не загружается в память целиком, платится только за доступ к конкретным ключам. map — загружается полностью. Для больших коллекций всегда big_map.

Разработка на CameLIGO. Локальная компиляция через Ligo CLI, dry-run для проверки логики без деплоя.

Тестирование. Юнит-тесты через SmartPy test runner или Ligo test framework. Интеграционные тесты через Taquito в Ghostnet.

Деплой и верификация. Деплой через octez-client originate. Верификация исходного кода на Better Call Dev и tzkt.io — аналог Etherscan для Tezos.

Сроки

Контракт средней сложности (FA2 с кастомной логикой, без формальной верификации) — от 3 до 5 рабочих дней. Контракты с формальной верификацией через Archetype/Why3 — от 2 недель. DeFi-протокол на Tezos (DEX, lending) — от месяца.

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

На что смотреть при аудите Tezos-контрактов

Reentrancy через TRANSFER_TOKENS. Tezos не защищён от reentrancy автоматически. Если контракт вызывает внешний адрес через TRANSFER_TOKENS и затем изменяет storage, возможна атака. Паттерн защиты — checks-effects-interactions (сначала изменяем storage, потом делаем внешний вызов). В Tezos это особенно важно, потому что вызовы контрактов выполняются асинхронно в очереди операций.

Проверка amount в payable entrypoints. В Tezos любой entrypoint может принимать tez. Если не проверить Tezos.get_amount() = 0tez в entrypoints, которые не должны принимать средства, пользователь случайно заблокирует tez в контракте.

Storage fees. Запись новых данных в storage стоит tez. Если контракт позволяет неограниченно добавлять записи в map без оплаты, это вектор для DoS: атакующий добавляет тысячи записей, исчерпывая balance контракта на storage fees, и контракт перестаёт работать.