Разработка смарт-контрактов на Clarity (Stacks)

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

Разработка смарт-контрактов на Clarity (Stacks)

Stacks — блокчейн, который работает поверх Bitcoin и использует Bitcoin как расчётный слой. Смарт-контракты на Stacks выполняются через консенсус Proof of Transfer (PoX), финальность обеспечивается Bitcoin-блоками. Это уникальная позиция: Turing-complete смарт-контракты с финальностью Bitcoin, без необходимости bridge'ить BTC.

Язык Clarity спроектирован намеренно непохожим на Solidity. Он интерпретируемый (не компилируется в байткод — код читается и исполняется напрямую), decidable (поведение полностью предсказуемо без выполнения), и намеренно не Turing-complete в части рекурсии (нет рекурсивных вызовов между контрактами в одной транзакции).

Что значит decidable — и почему это важно для аудита

В Solidity аудитор должен симулировать выполнение кода, чтобы понять, что произойдёт при данном вызове. В Clarity синтаксис написан так, что поведение функции можно вывести статически, без выполнения. Нет динамических вызовов через указатель, нет произвольной рекурсии, нет self-destruct.

На практике это означает: reentrancy атака в классическом понимании невозможна. Контракт A вызывает контракт B — B не может вызвать A обратно в той же транзакции. Это фундаментальное ограничение языка, не просто lint-правило. Целый класс уязвимостей, унёсших сотни миллионов долларов на EVM, здесь просто отсутствует.

Но у этого есть цена: паттерны, привычные по Solidity, не работают напрямую.

Синтаксис и типовая система Clarity

Clarity написан в Lisp-подобном синтаксисе (S-expressions). Для разработчиков с опытом Solidity/JavaScript это непривычно. Пример простейшей функции:

(define-public (transfer (amount uint) (sender principal) (recipient principal))
  (begin
    (asserts! (is-eq tx-sender sender) err-not-authorized)
    (try! (ft-transfer? my-token amount sender recipient))
    (ok true)
  )
)

principal — тип для адресов (Stacks-адрес или contract principal). uint — беззнаковое целое. Нет неявных конвертаций типов. try! разворачивает Result, реверт на ошибку.

Типы данных

Тип Аналог в Solidity Особенности
uint uint256 Только беззнаковые
principal address Включает contract principals
(buff N) bytes Фиксированная длина
(string-ascii N) string ASCII, фиксированная длина
(list N T) T[] Фиксированная максимальная длина
(optional T) нет прямого аналога Явная обработка отсутствия значения

Фиксированные длины — важный момент. В Clarity нет динамических массивов произвольной длины. (list 200 uint) — список максимум из 200 элементов. Это сделано осознанно: gas model в Stacks рассчитывается статически на основе максимальных размеров данных.

SIP-009 и SIP-010 — стандарты токенов

SIP-010 — стандарт Fungible Token (аналог ERC-20). Обязательные функции: transfer, get-balance, get-total-supply, get-decimals, get-name, get-symbol, get-token-uri.

SIP-009 — Non-Fungible Token (аналог ERC-721). Включает: get-last-token-id, get-token-uri, get-owner, transfer.

В отличие от ERC-20, SIP-010 требует, чтобы transfer принимал sender как явный параметр и проверял tx-sender == sender. Это предотвращает один из классических векторов: вызов transferFrom от имени другого адреса без проверки.

Trait система

В Clarity нет интерфейсов как в Solidity. Вместо этого — traits: именованные наборы функций, которым контракт обязуется соответствовать. При вызове функции с параметром типа <trait> рантайм проверяет, что переданный контракт реализует все функции trait'а. Это позволяет строить composable системы — например, marketplace, который принимает любой SIP-009-совместимый NFT-контракт.

Углублённо: работа с Bitcoin в Clarity

Это главная уникальная возможность Stacks. Через Clarity Bitcoin библиотеку контракт может читать Bitcoin-транзакции напрямую (без bridge). Функция get-burn-block-info? возвращает данные о Bitcoin-блоке. verify-merkle-proof позволяет on-chain верифицировать включение транзакции в Bitcoin-блок.

Это открывает паттерн: пользователь отправляет BTC на Bitcoin-адрес, Clarity-контракт верифицирует транзакцию через Merkle proof и минтит токены на Stacks. Без trust assumptions, без wrapped BTC, без bridge — чистая криптографическая верификация.

Реализация этого паттерна нетривиальна: нужно понимать структуру Bitcoin-транзакций (segwit vs. legacy), Merkle tree Bitcoin блоков, и правильно парсить (buff 1024) как UTXO-данные. Но это первоклассная функциональность языка, а не хак.

Инструменты разработки

  • Clarinet — CLI для разработки и тестирования Clarity контрактов (аналог Hardhat/Foundry для Stacks)
  • clarinet new — инициализация проекта
  • clarinet test — запуск тестов через Deno/TypeScript
  • clarinet console — REPL для интерактивного взаимодействия с контрактами
  • clarinet integrate — локальная сеть с симуляцией Bitcoin-блоков
  • Hiro Explorer — block explorer для Stacks (mainnet + testnet)
  • stacks.js — JavaScript-библиотека для взаимодействия с контрактами (аналог ethers.js)

Тесты пишутся на TypeScript с использованием Vitest или Jest. Clarinet предоставляет simnet — симулятор сети в памяти, позволяющий тестировать несколько блоков, advance time, симулировать Bitcoin-транзакции.

Типичные сложности при разработке

Нет msg.value/Payable функций. STX-платежи обрабатываются через stx-transfer?. Если контракт должен принимать STX, нужно явно обрабатывать трансфер в логике функции. Нет автоматического «ETH прикреплён к вызову».

Post-conditions на стороне клиента. stacks.js и кошельки (Leather, Xverse) поддерживают post-conditions: пользователь подписывает транзакцию с явным указанием максимального изменения баланса. Если контракт попытается изменить баланс больше указанного — транзакция отклоняется. Это защита от drain-атак, но требует правильной настройки в SDK.

Read-only функции и их ограничения. define-read-only функции не могут изменять state, но могут читать state других контрактов через contract-call?. При сложных read-only вычислениях упирается в cost limit для read-only calls (значительно ниже, чем для обычных транзакций).

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

Проектирование. Определяем структуры данных (maps, vars), функции с правами доступа, стандарты токенов. Рисуем граф вызовов между контрактами — важно для анализа reentrancy (которого нет) и порядка деплоя.

Разработка в Clarinet. Итеративная разработка с тестами. Clarinet console для проверки логики. Покрытие тестами через simnet.callPublicFn, simnet.callReadOnlyFn.

Аудит перед деплоем. Clarity позволяет формальный анализ — проверяем все пути выполнения, убеждаемся в корректности post-conditions в клиенте.

Деплой. clarinet deployments generate --testnetclarinet deployments apply. Контракты деплоятся в порядке зависимостей автоматически.

Сроки

Стандартный SIP-010 токен с кастомной логикой — 3-5 рабочих дней. Сложный протокол (DEX, lending, NFT marketplace с SIP-009) — от 2 до 4 недель. Контракты с Bitcoin-верификацией через Clarity Bitcoin — от 2 недель, зависит от сложности UTXO-логики.

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