Развёртывание смарт-контрактов на Sui: от написания до запуска
Мы занимаемся деплоем смарт-контрактов в Sui с момента запуска mainnet — за это время выпустили более 50 пакетов на разных сетях. Наш опыт: 10+ лет в блокчейн-разработке, включая Ethereum, Solana и Sui. В этом гайде разберём, как перенести dApp с EVM на Move, избежать типичных ошибок и выкатить контракт в mainnet.
Sui использует Move — язык, разработанный в Facebook для Diem. Официальная документация Sui: Move — это безопасный язык программирования для смарт-контрактов. Ключевое отличие от Solidity: ресурсы (objects) не могут быть скопированы или случайно уничтожены — это гарантируется системой типов на уровне компилятора. Если вы привыкли к EVM, первые дни будут неудобными: забудьте о маппингах address => uint256, здесь всё строится вокруг объектов с явным владельцем.
Благодаря оптимизации газа вы сможете сэкономить до 30% на комиссиях, а типовой проект окупается за 2 месяца.
Почему Move безопаснее Solidity?
В Solidity уязвимости вроде reentrancy, некорректной верификации адресов или переполнения — частая головная боль. Move решает это на уровне языка: объекты нельзя скопировать (нет dup), каждый объект имеет уникальный ID и владельца. Даже если разработчик захочет написать уязвимый код, компилятор не даст — например, нельзя случайно передать объект не тому адресу без явного вызова transfer::transfer. Это снижает потребность в дорогих аудитах, но не отменяет их полностью.
Объектная модель Sui
В Sui нет глобального стейта в классическом понимании. Всё — объекты. Каждый объект имеет уникальный ID, version и owner:
- Owned objects — принадлежат конкретному адресу, только он может их использовать в транзакциях
- Shared objects — доступны всем, но создают contention и требуют консенсус (медленнее)
- Immutable objects — навсегда заморожены, доступны всем для чтения
Это важно при архитектуре: если ваш контракт требует shared state (как AMM с общим пулом ликвидности) — shared objects неизбежны и транзакции идут через консенсус. Если state можно разнести по пользователям — используйте owned objects и получаете параллельную обработку без консенсуса.
Сравнение типов объектов:
| Тип объекта | Скорость транзакции | Стоимость газа | Риск contention |
|---|---|---|---|
| Owned | высокая | низкая | нет |
| Shared | средняя | средняя | да |
| Immutable | мгновенная | нулевая (чтение) | нет |
Какие сложности возникают при миграции с EVM на Move?
Первая — отказ от маппингов. Вместо mapping(address => uint256) нужно проектировать объекты с явным владельцем. Вторая — понимание init функции: она вызывается один раз при деплое, аналог constructor. Третья — привыкание к Capability pattern вместо msg.sender. Четвёртая — газ: в Sui нет газового оракла, стоимость зависит от типов объектов (owned дешевле shared). Пятая — сложность с отладкой: локальный фреймворк тестов хороший, но продакшн-логи требует Tenderly-подобных решений (у Sui есть Sui Explorer, но не так глубоко).
Инструментарий и структура проекта
Пошаговое руководство по началу работы:
- Установите Sui CLI из официального репозитория:
cargo install --locked --git https://github.com/MystenLabs/sui.git --branch mainnet sui - Создайте новый пакет и напишите код:
sui move new my_package sui move build sui move test Структура пакета включает Move.toml с настройками зависимостей и адресов, модули в sources/ и тесты в tests/.
Пример Move.toml:
[package] name = "my_package" version = "0.0.1" edition = "2024.beta" [dependencies] Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet" } [addresses] my_package = "0x0" Capability pattern — управление доступом
В Move нет msg.sender как в Solidity. Права передаются через объекты-capability:
module my_package::admin { use sui::object::{Self, UID}; use sui::tx_context::TxContext; /// Административный capability — кто держит объект, тот и admin public struct AdminCap has key, store { id: UID, } fun init(ctx: &mut TxContext) { transfer::transfer(AdminCap { id: object::new(ctx) }, tx_context::sender(ctx)) } /// Только держатель AdminCap может вызвать public fun privileged_action(_cap: &AdminCap, /* ... */) { // logic } } init функция — точка входа при деплое, аналог constructor. Вызывается один раз автоматически.
Деплой пакета
# Стандартный деплой или с офлайн-подписью sui client publish --gas-budget 100000000 --json sui client publish --gas-budget 100000000 --serialize-unsigned-transaction | sui keytool sign --address <ADDRESS> --data - После деплоя получаете packageId — неизменяемый адрес пакета. В транзакциях ссылаетесь на функции как <packageId>::<module>::<function>.
Апгрейдимость
Sui поддерживает апгрейды пакетов, но с ограничениями. Апгрейд контролируется через UpgradeCap объект. Команда:
sui client upgrade --upgrade-capability <UPGRADE_CAP_ID> --gas-budget 100000000 Политики апгрейда:
| Политика | Описание |
|---|---|
| compatible | Можно добавлять функции, нельзя менять существующие сигнатуры |
| additive | Только добавление новых модулей |
| dep_only | Только обновление зависимостей |
Для production: передайте UpgradeCap в timelock-контракт или multisig (Sui поддерживает multisig через MultiSig схему). Если обновления не планируются — сделайте UpgradeCap immutable через package::make_immutable.
Тестирование и инспекция
Move имеет встроенный тест-фреймворк, который позволяет писать модульные тесты с симуляцией транзакций. После деплоя верифицируйте объекты через блокчейн-эксплорер.
Что входит в нашу работу по деплою смарт-контрактов в Sui
Мы берём на себя полный цикл: от аудита вашего кода до деплоя с мониторингом.
- Аудит и рефакторинг — проверка на типичные Move-уязвимости, оптимизация газа
- Настройка CI/CD — автоматическая сборка, тесты и деплой через GitHub Actions
- Интеграция с multisig — настройка управления UpgradeCap через multisig или timelock
- Документация — описание всех функций, событий и объектов
- Техподдержка — помощь в первые недели после деплоя
Оцените ваш проект — напишите нам. Закажите деплой под ключ и получите консультацию инженера.
Чеклист перед mainnet-деплоем
- Тесты через
sui move testс покрытием edge cases - Проверка gas budget:
sui client dry-runперед фактическим деплоем -
UpgradeCapпередан в multisig или заморожен -
AdminCapи другие privileged objects — на multisig-адресе, не на EOA - Проверка что shared objects действительно нужны (owned — быстрее и дешевле)
- Ревью на типичные Move-уязвимости: missing
has keyabilities, некорректный transfer ownership







