Розробка безпечних 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-атак виключено на рівні мови — це саме те.

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