Розгортання смарт-контрактів на 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та інші привілейовані objects — на multisig-адресі, не на EOA - Перевірка, що shared objects дійсно потрібні (owned — швидше та дешевше)
- Рев'ю на типові Move-вразливості: missing
has keyabilities, некоректний transfer ownership







