Разработка безопасных Move-контрактов для Aptos и Sui

Отметим: когда Solidity-контракт с reentrancy опустошил The DAO на миллионы долларов, стало понятно: модель глобального мутабельного стейта плюс произвольные внешние вызовы — это фундаментальная архитектурная проблема. Move решает её иначе: ресурсы не копируются и не уничтожаются неявно, они перемещ

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Отметим: когда Solidity-контракт с reentrancy опустошил The DAO на миллионы долларов, стало понятно: модель глобального мутабельного стейта плюс произвольные внешние вызовы — это фундаментальная архитектурная проблема. Move решает её иначе: ресурсы не копируются и не уничтожаются неявно, они перемещаются. Отсюда и название языка.

Если вы пришли с опытом Solidity, первая неделя на Move будет болезненной. Не потому что сложно — а потому что многое, что Solidity позволяет по умолчанию, Move запрещает на уровне системы типов. Мы помогаем пройти этот переход с минимальными потерями: показываем типичные грабли и даём готовые шаблоны resource-моделей. За последние годы мы разработали более 30 контрактов на Move и каждый раз используем формальную верификацию для критических модулей.

Особенности безопасности Move: ресурсная модель и компилятор

Linear type system и ресурсная модель

В Solidity токен — это запись в mapping: mapping(address => uint256) balances. Ничто не мешает написать функцию, которая создаст токены из воздуха или «забудет» вычесть баланс. Move-ресурс существует в одном месте одновременно — это гарантируется верификатором байткода, не аудитором. Согласно документации Move Language, Move Language Book, атрибуты copy, drop, store, key — это возможности (abilities). Если у типа нет drop, компилятор не даст завершить функцию, не употребив значение. Забытый ресурс = ошибка компиляции, а не потерянные средства.

// Aptos Move: ресурс нельзя скопировать или потерять struct Coin<phantom CoinType> has store { value: u64, } 

Апробированные векторы атак на EVM, закрытые в Move

Вектор атаки (EVM) Статус в Move
Reentrancy Невозможен: нет произвольных внешних вызовов к неизвестным контрактам
Integer overflow Невозможен: арифметика abort'ит при переполнении по умолчанию
Неправильная инициализация прокси Значительно сложнее: storage model отличается
Access control через msg.sender Заменён на signer — нельзя подделать
Selfdestruct Нет аналога

Это не значит, что Move-контракты не содержат уязвимостей. Логические ошибки никуда не делись. Но класс атак, который поглощает 60-70% EVM-аудита, в Move просто не существует.

Выбор между Aptos и Sui

Оба чейна используют Move, но архитектуры хранения кардинально разные. Мы подготовили сравнение, чтобы вы могли принять решение.

Aptos: глобальное хранилище и account-centric модель

В Aptos ресурсы хранятся в аккаунте: move_to(account, resource). Для доступа к ресурсу другого аккаунта нужен acquires-аннотированный вызов: borrow_global<T>(addr). Это похоже на EVM-паттерн с mapping(address => struct), но типобезопасно.

// Aptos: читаем ресурс конкретного аккаунта public fun get_balance(owner: address): u64 acquires CoinStore { borrow_global<CoinStore>(owner).coin.value } 

Параллелизм в Aptos реализован через Block-STM — оптимистичное исполнение с откатом при конфликтах. Это работает хорошо, если транзакции касаются разных аккаунтов, и плохо, если все пишут в один ресурс (например, глобальный счётчик).

Sui: объектная модель и настоящий параллелизм

В Sui всё — объект с уникальным ObjectID. Транзакция явно объявляет, какие объекты использует (owned, shared, immutable). Scheduler видит граф зависимостей заранее — транзакции с непересекающимися объектами исполняются параллельно без оптимистичных откатов.

// Sui: объект существует независимо от аккаунта public struct NFT has key, store { id: UID, name: String, // ... } public fun transfer_nft(nft: NFT, recipient: address, ctx: &mut TxContext) { transfer::public_transfer(nft, recipient); } 

Для DeFi-протоколов с высоким TPS это принципиально. Shared objects — это shared мьютекс, они сериализуют транзакции. Хорошо спроектированный Sui-контракт максимизирует использование owned objects.

Сравнение Aptos и Sui

Параметр Aptos Sui
Модель хранения Ресурсы в аккаунте, глобальный доступ Объекты с ID, явное владение
Параллелизм Block-STM (оптимистичный) Объектная модель (предварительный граф)
Типичная сложность Средняя (account-centric) Высокая (объектные зависимости)
Инструменты Aptos CLI, Move Framework Sui CLI, Move Analyzer

Почему Move безопаснее Solidity?

Move запрещает целые классы уязвимостей на уровне языка: reentrancy, integer overflow, неявные копии. Это снижает нагрузку на аудит и уменьшает количество баунти. Экономия до 30% бюджета на безопасности достигается за счёт отсутствия необходимости в ручном анализе этих векторов.

Что входит в разработку Move-контракта?

Toolchain и инфраструктура

Для Aptos используем Aptos CLI и Aptos Framework (Move стандартная библиотека). Для Sui — Sui CLI, Move Analyzer (LSP-плагин для VS Code). Тесты пишем на Move Test Framework (#[test], #[test_only]) с покрытием через aptos move test --coverage или sui move test. Для форк-тестирования Aptos — Aptos Local Testnet через Docker. Для Sui — localnet режим Sui CLI. Интеграционные тесты с реальными протоколами (Thala, Cetus, Turbos) требуют деплоя на testnet.

Типичные проблемы при первом контракте на Move - **Generic type phantom**: параметр типа, не используемый в полях, нужно помечать `phantom`, иначе компилятор требует его наличие. - **Ability constraints**: для generic функций обязательно указывать нужные ability (store, copy, drop) — иначе компиляция не пройдёт. - **Event emission в Sui**: события не сохраняются on-chain, значит нельзя подписаться на события другого контракта. Архитектура должна быть другой.

Этапы работы над проектом

  1. Аналитика — проектируем ресурсную модель, описываем signer-логику.
  2. Разработка — пишем исходный код, unit-тесты, fuzz-тесты.
  3. Аудит — формальная верификация через Move Prover, ручное код-ревью.
  4. Деплой — multi-sig деплой, upgrade capability management, документация.
  5. Поддержка — 1 месяц гарантийного сопровождения после деплоя.

Наш опыт: более 50 успешных проектов на EVM и Move. Получите консультацию — оценим ваш проект и предложим оптимальную архитектуру на Move. Обсудите проект с нашим Web3-инженером.

Ориентиры по срокам и бюджету

Простой токен-контракт на Aptos (fungible asset стандарт) — 3-5 дней с тестами. Lending протокол с ценовыми оракулами и ликвидациями — 4-8 недель. Кросс-чейн бридж с проверками финальности — от 2 месяцев. Точная стоимость рассчитывается после брифинга.

Move — молодая экосистема с серьёзными техническими преимуществами. Инфраструктура для разработчиков отстаёт от EVM, документация местами устаревает быстрее, чем обновляется. Но если вам нужен протокол, где класс reentrancy-атак исключён на уровне языка — это именно то.

Свяжитесь с нами для обсуждения вашего проекта — оценим архитектуру и предложим оптимальное решение.