Sui.

Допис

Діліться своїми знаннями.

BigSneh.
Jul 30, 2025
Питання та відповіді експертів

Чи може смарт-контракт володіти та мутувати власний об'єктний стан у Sui?

Я намагаюся зрозуміти цей аспект мережі Sui, тому що я або будую, налагоджую або розгортаю щось, що стосується цієї області. Я хочу детальне пояснення того, як працює цей механізм або функція, разом із відповідним використанням CLI, структурою переміщення коду або архітектурними концепціями. Моя мета — отримати достатню ясність, щоб застосувати ці знання в реальному проекті — будь то спеціальний смарт-контракт, система NFT, інтеграція гаманця чи інструмент DeFi. Мережа Sui має унікальні особливості порівняно з мережами EVM, тому мене особливо цікавить, що її відрізняє та як це впливає на найкращі практики розробки. Це допомогло б мати зразок коду, приклади командного рядка або типові помилки, на які слід стежити, особливо під час використання Sui CLI, SDK або розгортання в localnet/testnet. Зрештою, я хочу уникнути поширених помилок, дотримуватися найкращих принципів безпеки та гарантувати, що функціональність, над якою я працюю, поводиться так, як очікувалося в реалістичних умовах.

  • Sui
  • Architecture
  • Move
7
15
Поділитися
Коментарі
.

Відповіді

15
Paul.
Paul4340
Jul 31 2025, 05:35

У Sui смарт-контракт не може безпосередньо володіти або мутувати власний об'єктний стан. Натомість контракт взаємодіє з об'єктами через модель власності, де об'єкти належать певним адресам (наприклад, гаманець користувача або обліковий запис). Розумні контракти в Sui можуть визначати та змінювати стан об'єктів, що належать іншим сторонам (наприклад, користувачам), але вони не можуть володіти об'єктами самі.

Ключові поняття:

*Власність об'єктам: Об'єкти належать за адресами, а не за договорами. *Взаємодія з об'єктами: Контракт може маніпулювати станом об'єкта, але лише якщо він має доступ до цього об'єкта через право власності або змінні посилання.

Приклад коду:

module MyModule {
    use sui::object::{Object, move_to};

    public fun update_object_state(obj: &mut Object) {
        // Modify the state of the object owned by someone else
        obj.some_field = 42;
    }
}

Використання CLI:

Під час розгортання контракт може маніпулювати лише об'єктами, якими володіє адреса, а не сама.

Найкращі практики:

  • Переконайтеся, що контракти дотримуються моделі власності Sui, передаючи об'єкти між контрактами та обліковими записами користувачів.
  • Завжди безпечно керуйте дозволами, щоб уникнути несанкціонованого доступу до стану об'єкта.
8
Коментарі
.
Ashford.
Jul 31 2025, 06:34

Чи може смарт-контракт володіти та мутувати власний об'єктний стан у Sui?

Ні, у Suiсмарт-контракти не можуть безпосередньо володіти або мутувати власний стан. Право власності та мутації ресурсів (таких як об'єкти монет або власні об'єкти) регулюються обліковими записами користувачів або авторизованими адресами, а не самим договором.

Ключові моменти:

*Власництво: смарт-контракти в Sui не мають громадянства; вони визначають логіку, але не володіють і не зберігають стан. *Власність ресурсів: Ресурси (наприклад, монети або спеціальні об'єкти) повинні належати адресі чи юридичній особі, а не контракту.

Типовий потік:

1.Власність обліковим запису: Адреса або користувач володіє об'єктом (наприклад, монета). 2.Виконання смарт-контракту: Договір може змінювати стан об'єктів, які йому передаються власником.

Приклад потоку:

1.Користувач створює об'єкт(наприклад, монету). 2.Користувач передає об'єктдо договору на мутацію. 3. Договір змінює об'єкт, але не володіє ним.

Зразок коду переміщення:

public fun mutate_object(owner: &mut Address, coin: &mut Coin) {
    Coin::transfer(coin, &mut owner);
}

Приклад CLI:

Розгорніть контракт і викликайте функцію для зміни стану об'єкта:

sui client publish --gas-budget 10000 --module <module-path>

Поширені помилки:

*Плутанина власності: спроба змінити або отримати доступ до стану, який не належить контракту, призведе до помилок. &mut*Неправильна змінність: Переконайтеся, що об'єкт, що передається до договору, є змінним ().

Найкращі практики:

*Забезпечити належне володіння: Переконайтеся, що об'єкти, що передаються до договору, належать правильна адреса. *Тест за допомогою Localnet/Testnet: Завжди перевіряйте логіку контракту та зміни стану перед розгортанням у основну мережу.

7
Коментарі
.
Benjamin XDV.
Jul 31 2025, 09:42

У Sui смарт-контракти (пакети Move)не можутьбезпосередньо володіти або мутувати об'єкти самі через об'єктно-орієнтовану модель власності Sui. Об'єкти повинні належатиадреса,іншому об'єктаабо позначатися якспільний/незмінний— пакунки містять лише логіку коду. Для автономної мутації ви зазвичай використовуєтеспільні об'єкти(з консенсусом) абодинамічні поля, де батьківські об'єкти керують дочірніми об'єктами. Це принципово відрізняється від зберігання контрактів EVM, що вимагає явної передачі права власності через транзакції, а не внутрішні дії контракту. Поширені шаблони передбачаютьзагортання об'єктіву контейнери, керовані адміністратором, або використаннядизайну на основі можливостідля безпечного управління мутаціями стану.

6
Коментарі
.
theking.
Jul 30 2025, 11:13

Так, у Sui смарт-контрактможе мутувати власний стан об'єкта, алевін не може володіти об'єктами самостійно. У об'єктно-центричній моделі Суякожен об'єкт повинен належати або адресі, іншому об'єкту або позначатися як спільний. Розумні контракти не мають адреси, як у ланцюгах EVM (наприклад, Ethereum), тому ви повинні покладатися на шаблонивласність об'єктах, якструктури даних, обгорнуті об'єктамиабоспільні об'єкти, щоб зберегти та мутувати стан між транзакціями.

Щоб оновити внутрішній стан контракту, ви зазвичай розробля structєте (з keyможливістю) зберігати дані стану, передавати їх вашій entryфункції та виконувати оновлення за допомогою посилань. Право власності на цю структуру належить користувачеві або позначено як спільне, щоб забезпечити ширший доступ.

Приклад - Мутація внутрішнього стану через об'єкт, що належить

module example::counter {
    use sui::object::{Self, UID};
    use sui::tx_context::{Self, TxContext};

    struct Counter has key {
        id: UID,
        value: u64,
    }

    public entry fun create(ctx: &mut TxContext): Counter {
        Counter { id: object::new(ctx), value: 0 }
    }

    public entry fun increment(counter: &mut Counter) {
        counter.value = counter.value + 1;
    }
}

createУ цьому прикладі Counterініціалізує об'єкт. incrementможна викликати лише шляхом передачі змінного посилання на цей об'єкт. Власність належить користувачеві або іншому об'єкту, а не самому договорі.

Спільні об'єкти для глобального доступу

sharedЯкщо ваш контракт потребуєкількох користувачів для взаємодії з одним об'єктом, позначте його як. Приклади використання: DAO, глобальні лічильники, мережеві ігри.

public entry fun increment_shared(counter: &mut Counter) {
    counter.value = counter.value + 1;
}

При розгортанні або за допомогою явної функції ви повинні поділитися об'єктом:

sui client call \
  --function share_object \
  --module counter \
  --package <package_id> \
  --args <counter_id>

Поради щодо CLI:

  • Щоб переглянути право власності: sui client object <object_id>
  • Для мутації: використовуйте --mutпрапор або визнач &mutте у функції введення
  • Для спільної мутації: переконайтеся, що об'єкт опублікований як sharedдо мутації

Інтеграція SDK (TS):

tx.moveCall({
  target: `${packageId}::counter::increment`,
  arguments: [tx.object(counterId)]
});

Найкращі практики:

  • Уникайте спроб зберігати посилання на об'єкти всередині інших об'єктів, якщо це не потрібно.
  • Якщо вам потрібна глобальна змінність,спільні об'єктиє правильним підходом.
  • Використання UIDта keyможливість гарантувати, що об'єкти можуть зберігатися між транзакціями.
  • Завжди перевіряйте, що абонент має право на мутацію, особливо для спільних об'єктів.

Поширені помилки:

  • Cannot find mutable reference— Ви передаєте незмінний об'єкт, де потрібно змінний.
  • Object is not shared— Ви намагаєтесь змінити об'єкт, який не був спільним.
  • Type mismatch— Часто викликано неправильними дженериками або неправильним використанням посилань.

Докладніше про право власності та спільні об'єкти можна прочитати в Документах розробника Sui.

5
Коментарі
.
SuiLover.
Jul 30 2025, 11:30

У мережі Sui смарт-контракти не можуть «володіти» об'єктами в традиційному сенсі EVM, оскільки право власності завжди прив'язане до адреси чи іншого об'єкта. Однак смарт-контракти, написані в Move, можуть визначати та змінювати власні об'єкти власного стану — це, як правило, спільні об'єкти або власні об'єкти, передані користувачами.

Ключові поняття

  1. Власність об'єкта в Sui: Кожен об'єкт належить:

Адреса користувача (адреса),

Інший об'єкт (вкладене право власності),

Спільний (доступний всім),

Незмінний (не може змінюватися після публікації).

  1. Стан смарт-контракту: Щоб створити стан контракту, розробники визначають структури в модулі Move і публікують екземпляри цих структур як об'єкти. Потім ці об'єкти передаються функціям введення, де їх стан можна прочитати або змінити.

  2. Мутуючий стан: Щоб змінити стан об'єкта смарт-контракту, необхідно:

Передайте об'єкт у функцію як &mut.

Переконайтеся, що його можна змінювати та володіти/поділитися за потреби.

Мати правильні права доступу.

  1. Спільні об'єкти для глобального стану: Якщо ви хочете отримати глобальний стан для всього контракту, ви використовуєте спільні об'єкти:

Struct Counter має ключ, сховище, копіювання { значення: u64, }

приріст веселощів для публічного входу (лічильник: & mut Counter) { лічильник.значення = лічильник.значення + 1; }

  1. Публікація спільних об'єктів:

Спільні об'єкти повинні бути явно створені та спільними при ініціалізації.

Використовуйте виклик переміщення або Sui CLI --gas-budget та --shared-object-input для взаємодії з ними.

  1. Приклад потоку розгортання:

Розгорнути модуль за допомогою sui move publish.

Викликаємо функцію входу, щоб створити спільний об'єкт:

дзвінок суі-клієнта
<PACKAGE_ID>--пакет\

  • лічильник модулів
    --функція створення_лічильника
    --аргс 0
    --газовий бюджет 10000

Потім викликаємо increment з ідентифікатором об'єкта спільного об'єкта.

  1. Обмеження:

Розумні контракти не зберігають внутрішній стан, як у Solidity.

Вони діють на об'єктах, явно переданих їм.

Постійного «зберігання контрактів» всередині модуля не існує.

  1. Безпека та право власності:

Ви повинні підтвердити право власності вручну або за допомогою можливостей.

Зазвичай використовують шаблони контролю доступу, такі як AdminCap або Whitelist, для перекриття мутацій.

  1. Кращі практики:

Уникайте непотрібного спільного використання об'єктів, щоб обмежити використання газу та суперечки.

Використовуйте можливості або перевірку адреси, щоб безпечно керувати доступом.

Використовуйте ключ і зберігайте належним чином, щоб увімкнути стійкість об'єкта та змінність.

  1. Команди CLI для перегляду:

виклик клієнта sui для викликів функцій.

клієнтський об'єкт sui для перевірки даних/стану об'єкта.

Тест sui move для логіки стану тестування одиниць.

4
Коментарі
.
shamueely.
Jul 30 2025, 11:38

У Sui смарт-контракт, написаний у Move, не може по-справжньому володіти* власнити* власним об'єктом у тому ж сенсі, що контракт EVM, що самопосилається, може утримувати та мутувати внутрішній стан автономно. Об'єктно-орієнтована архітектура Sui означає, що всі об'єкти повинні бути явно передані в контекст транзакції, і їх власність є або заснованою на обліковому записі, або спільною. Розумні контракти самі по собі є бездержавними — вони визначають лише логіку. Фактичний стан існує в об'єктах переміщення, які необхідно передати функціям для читання або мутації.

Щоб змінити об'єкт стану контракту, вам потрібно структурувати ваш модуль таким чином, щоб його дані (зазвичай зберігаються у has keyструктурі) були або:

*Власність адреси користувача(корисно для логіки облікового запису), *Спільний через share_object()(для підтримки кількох акторів, наприклад, у DeFi, DAO, іграх тощо).

Використовуючи спільні об'єкти, ви повинні позначити свої функції entryта передати спільний об'єкт як &mutпосилання.

Ось приклад спільного стану, який можна мутувати:

module my_app::vault {
    use sui::object::{UID, ID};
    use sui::tx_context::TxContext;

    struct Vault has key {
        id: UID,
        balance: u64,
    }

    public fun init(ctx: &mut TxContext): Vault {
        Vault { id: object::new(ctx), balance: 0 }
    }

    public entry fun deposit(vault: &mut Vault, amount: u64) {
        vault.balance = vault.balance + amount;
    }
}

У цьому прикладі Vaultоб'єкт повинен бути спільним, якщо ви хочете, щоб він був доступний декільком користувачам за допомогою entryфункцій. Під час розгортання ви ділитеся об'єктом так:

sui client call --function share_object --args <vault_id>

Після спільного використання будь-яка entryфункція може змінювати об'єкт за умови, що він отримує його як вхідний сигнал. Sui забезпечує безпеку за допомогою правил власності та версій, щоб запобігти умовам гонки.

Щоб дізнатися більше про те, як смарт-контракти в Sui взаємодіють зі станом об'єкта, спільним доступом та власністю, відвідайте: https://docs.sui.io/build/programming-model/object-basics

Цей підхід відрізняє Sui від ланцюгів EVM. Ви не змінюєте внутрішнє сховище контрактів безпосередньо. Натомість ви мутуєте об'єкти Move, явно передані у ваші логічні функції, що покращує одночасність та перевірку.

4
Коментарі
.
Alya.
Alya-14
Jul 30 2025, 17:29

Ні, смарт-контракт (модуль Move) не може безпосередньо володіти або мутувати власний стан об'єкта в Sui.

Об'єкти є першокласними сутностями, що належать адресам, іншим об'єктам або спільними, а не модулями. Мутація стану відбувається за допомогою функцій, які приймають об'єкти як змінні параметри, а правила власності застосовуються на рівні транзакції.

Приклад:

struct Counter has key { id: UID, value: u64 }
public entry fun increment(counter: &mut Counter) { counter.value = counter.value + 1 }

incrementФункція може мутувати Counterлише тоді, коли транзакція передає змінне посилання на об'єкт, що належить відправнику. Сам модуль не тримає стану.

Використовувати sharedоб'єкти (transfer::share_object) для постійного, глобально доступного стану. Завжди перевіряйте право власності за object::is_owner()правилами лінійного типу та дотримуйтесь їх.

4
Коментарі
.
Arnold.
Arnold3036
Jul 31 2025, 08:16

Так, смарт-контракт Sui (пакет Move) може володіти та мутувати власний стан за допомогоюспільних об'єктівабополів динамічних об'єктів, на відміну від дизайну без статусу EVM.

####Ключові механізми 1.Спільні об'єкти:

  • Глобально змінюється будь-ким (з правилами).
  • Визначен key + storeо та належить 0x0(адреса пакета).
  struct ContractState has key, store {
      id: UID,
      value: u64,
  }

2.Поля динамічних об'єктів:

  • Пакет може «володіти» об'єктами, зберігаючи їх ідентифікатори.
  fun add_state(ctx: &mut TxContext) {
      let state = ContractState { id: object::new(ctx), value: 42 };
      transfer::share_object(state); // Make it globally mutable
  }

###Чому Суй унікальний -Немає «msg.sender": Управління доступом здійснюється через систему типу Move, а не EOA. -Паралельні мутації: Спільні об'єкти дозволяють одночасно записувати (на відміну від серіалізованих TX EVM).

###Приклад CLI

# Call a function that mutates shared state
sui client call \
    --function update_state \
    --module your_module \
    --package 0xYOUR_PACKAGE \
    --args 0xSHARED_OBJECT_ID 100 \ # New value
    --gas-budget 10000000

###Загальні підводні камени 1.Надмірне ділення: Уникайте, share_objectякщо це справді не потрібно (використовуйте transfer::transferдля приватної власності). 2. sui::lockУмови гонок: Дизайн для паралельного доступу (наприклад, використання).

4
Коментарі
.
290697tz.
Jul 30 2025, 11:35

Так, розумний контракт у Sui може мутувати власний стан об'єкта, але він повинен робити це через об'єкти, явно передані в його функції. В об'єктній моделі Суї немає внутрішнього сховища контрактів, як в Ethereum; натомість стан підтримується за допомогою змінних об'єктів. Ці об'єкти можуть належати користувачам або ділитися ними по мережі. Щоб змінити стан, ви визначаєте структуру зі здатністю has key, а потім записуєте функції введення, які приймають посилання &mut на об'єкт. Спільні об'єкти дозволяють отримати глобальний доступ і потрібні, коли кілька користувачів повинні взаємодіяти з одним станом. Мутація спільних об'єктів вимагає позначення функції як загальнодоступного запису та передачі правильного ідентифікатора об'єкта під час викликів. Контракти не «володіють» державою безпосередньо; скоріше, вони оперують даними, переданими їм за допомогою аргументів. Ви можете примусити контроль доступу за допомогою можливостей або перевіряючи адреси відправників. Ця конструкція підтримує високу паралельність, кращу масштабованість та дрібнозернисті дозволи. Загалом, смарт-контракти в Sui змінюють стан, змінюючи визначені рухом об'єкти за суворими правилами власності та доступу.

3
Коментарі
.
Evgeniy CRYPTOCOIN.
Jul 31 2025, 09:09

Так, смарт-контракт Sui (модуль Move) може володіти та мутувати власні об'єкти за допомогою:

1.Власні об'єкти— Створено під час ініціації модуля (зберігається під ідентифікатором пакета). 2.Спільні об'єкти— Позначено для доступу до декількох записува sharedчів.

###Ключові відмінності проти EVM:Немає зовнішнього власника— Об'єкти можуть належати самому пакету. ✔Пряма мутація- Система затвердження не потрібна (на відміну від ERC-20).

Приклад візерунка:

struct MyState has key { id: UID, value: u64 }  

// Module can mutate its own object  
public fun update(self: &mut MyState) { self.value += 1 }  

Слідкуйте за:

  • Витрати на зберігання об'єктів, що перебувають у власності.
  • Використання sharedдля глобального стану.
  • (Об'єктна модель Sui забезпечує автономні контракти - не потрібні проксі-гаманці. ) *
3
Коментарі
.
Bekky.
Bekky1762
Jul 31 2025, 10:27

###1. Основна концепція: Об'єктно-орієнтоване володіння На відміну від змінних зберігання EVM, смарт-контракти Sui працюють за допомогоювласних об'єктів, які можна мутувати на основі суворих правил власності.

####Основні функції | Особливість | Суй | EVM | | --------------| -----| | Представлення стану | Об'єкти з UID | Змінні зберігання | | Власність | Яв keyна здатність | Неявна угода | | Змінюваність | &mutпосилання | Пряма модифікація |


###2. Переміщення шаблонів реалізації

####Договір про власність власності

module my_contract::state {
    use sui::object::{Self, UID};
    use sui::transfer;
    use sui::tx_context;

    // Contract's state object
    struct ContractState has key, store {
        id: UID,
        counter: u64
    }

    // Initialize and own the state
    public fun init(ctx: &mut tx_context::TxContext) {
        let state = ContractState {
            id: object::new(ctx),
            counter: 0
        };
        transfer::share_object(state); // Make shared for mutability
    }

    // Mutate owned state
    public entry fun increment(state: &mut ContractState) {
        state.counter = state.counter + 1;
    }
}

####Моделі власності | Модель | Шаблон коду | Випадок використання | | --------------------| ----------| |Спільний| | Глобальний змін transfer::share_objectний стан | transfer::freeze_object|Незмінний| | Конфігурація | |Власнити| | Активи transfer::transferкористувача |


###3. Взаємодії CLI

####Розгортання статусних контрактів

sui client publish --gas-budget 1000000000
# Output: 
# - Package ID: 0x123...
# - Shared Object ID: 0x456...

####Мутуючий стан

sui client call \
  --package 0x123 \
  --module state \
  --function increment \
  --args 0x456 \  # Shared object ID
  --gas-budget 100000000

###4. Архітектурні міркування

####Контроль паралельності

// Use `version` field for optimistic concurrency
struct ConcurrentState has key {
    id: UID,
    value: u64,
    version: u64
}

public fun update(
    state: &mut ConcurrentState,
    new_value: u64,
    expected_version: u64
) {
    assert!(state.version == expected_version, EVERSION);
    state.value = new_value;
    state.version = state.version + 1;
}

####Міграція штату (оновлення)

module my_contract::v2 {
    use my_contract::state::ContractState;

    // Migrate V1 state to V2
    public entry fun upgrade_state(
        old_state: ContractState,
        ctx: &mut tx_context::TxContext
    ) {
        let new_state = V2State {
            id: object::new(ctx),
            counter: old_state.counter,
            new_field: 0
        };
        transfer::share_object(new_state);
    }
}

###5. Патерни захисту

####Доступ на основі можливості

struct AdminCap has key, store {
    id: UID
}

public entry fun secure_update(
    state: &mut ContractState,
    _cap: &AdminCap
) {
    // Only callable with capability
    state.counter += 1;
}

####Захист від повторного в'їзду

struct Lock has key {
    id: UID,
    locked: bool
}

public entry fun guarded_update(
    state: &mut ContractState,
    lock: &mut Lock
) {
    assert!(!lock.locked, ELOCKED);
    lock.locked = true;
    state.counter += 1;
    lock.locked = false;
}

###6. Поширені підводні камені та рішення

| Помилка | Причина | Виправлення | | --------------| -----| | EInvalidSharedObjectUse| Неправильна змінність | Використовуйте &mutпосилання | | EMissingOwner| Об'єкт, який не належить пакету | transfer::transferдо адреси пакета | EImmutable| share_object| Спроба змінити заморожений об'єкт | Ініціалізувати як |


###7. Оптимізація продуктивності

####Пакетні мутації

public entry fun batch_update(
    states: vector<&mut ContractState>,
    delta: u64
) {
    let i = 0;
    while (i < vector::length(&states)) {
        let state = vector::borrow_mut(states, i);
        state.counter = state.counter + delta;
        i = i + 1;
    }
}

####Порівняння витрат на газ

ЕксплуатаціяГаз (SUI)
Одноразове оновлення2500
Пакетне оновлення (10 елементів)3,800

###Ключові диференціатори від EVM 1.Явне володіння: Об'єкти повинні бути навмисно передані 2. key + store``copy + dropДрібнозерниста змінність: проти здібностей 3.Паралельна обробка: Незалежні об'єкти мутують одночасно

Для виробництва використовують:

  • Зберігати критичний стан якспільні об'єкти
  • Використовуватиможливостідля привілейованих операцій
  • Реалізуйте шляхиміграціїштату заздалегідь
1
Коментарі
.

Ви знаєте відповідь?

Будь ласка, увійдіть та поділіться нею.