Пост
Поделитесь своими знаниями.
Может ли смарт-контракт владеть собственным состоянием объекта в Sui и изменять его?
Я пытаюсь разобраться в этом аспекте сети Sui, потому что я создаю, отлаживаю или развертываю что-то, что касается этой области. Мне нужно подробное объяснение работы этого механизма или функции, а также соответствующего использования интерфейса командной строки, структуры кода Move или архитектурных концепций. Моя цель — получить достаточно ясности, чтобы применить эти знания в реальном проекте, будь то специальный смарт-контракт, система NFT, интеграция кошельков или инструмент DeFi. Сеть Sui обладает уникальными возможностями по сравнению с сетями EVM, поэтому мне особенно интересно, что её отличает и как это влияет на передовые практики разработки. Было бы полезно ознакомиться с образцами кода, примерами командной строки или типичными ошибками, особенно при использовании интерфейса командной строки Sui, SDK или развертывании в localnet/testnet. В конечном итоге я хочу избежать распространенных ошибок, следовать лучшим принципам безопасности и обеспечить, чтобы функциональность, над которой я работаю, работала должным образом в реальных условиях.
- Sui
- Architecture
- Move
Ответы
15В 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;
}
}
Использование интерфейса командной строки:
При развертывании контракт может манипулировать только объектами, принадлежащими адресу, а не ему самому.
Лучшие практики:
- Убедитесь, что контракты соответствуют модели собственности Sui, передавая объекты между контрактами и учетными записями пользователей.
- Всегда безопасно управляйте разрешениями, чтобы избежать несанкционированного доступа к состоянию объекта.
Может ли смарт-контракт владеть собственным состоянием объекта и изменять его в Sui?
Нет, в языке Sui,**смарт-контракты не могут напрямую владеть своим состоянием или изменять его. Владение ресурсами (например, монетами или специальными объектами) и их изменение регулируются учетными записями пользователей или авторизованными адресами, а не самим контрактом.
Ключевые моменты:
*Собственность: смарт-контракты в Sui не имеют гражданства; они определяют логику, но сами не владеют государством и не хранят его. *Право собственности на ресурсы: Ресурсы (например, монеты или предметы, изготовленные на заказ) должны принадлежать адресу или юридическому лицу, а не договору.
Типичный поток:
1.Владение аккаунтом: объект (например, монета) принадлежит адресу или пользователю. 2.Выполнение смарт-контракта: контракт может изменять состояние объектов, переданных ему владельцем.
Пример последовательности действий:
1.Пользователь создает объект(например, монету). 2.Пользователь передает объектконтракту на мутацию. 3. Контракт изменяет объект, но не владеет им.
Пример кода перемещения:
public fun mutate_object(owner: &mut Address, coin: &mut Coin) {
Coin::transfer(coin, &mut owner);
}
Пример интерфейса командной строки:
Разверните контракт и вызовите функцию для изменения состояния объекта:
sui client publish --gas-budget 10000 --module <module-path>
Распространенные ошибки:
*Неразбериха в сфере владения: попытка изменить или получить доступ к состоянию, не являющемуся собственностью контракта, приведет к ошибкам.
&mut
*Неверная изменчивость: убедитесь, что передаваемый в контракт объект является изменяемым ().
Лучшие практики:
*Обеспечьте надлежащее владение: убедитесь, что объекты, передаваемые по контракту, принадлежат по правильному адресу. *Протестируйте с помощью Localnet/Testnet: всегда проверяйте логику контракта и изменения состояния перед развертыванием в основной сети.
В Sui смарт-контракты (пакеты Move)не могутнапрямую владеть объектами или изменять их сами из-за объектно-ориентированной модели владения Sui. Объекты должны принадлежатьадресу,другому объектуили помечены каксовместно используемые/неизменяемые— пакеты содержат только логику кода. Для автономной мутации обычно используютсяобщие объекты(на основе консенсуса) илидинамические поля, где родительские объекты управляют дочерними объектами. Это в корне отличается от хранения контрактов в EVM, где требуется прямая передача прав собственности посредством транзакций, а не внутренних договорных действий. Как правило, объекты упаковываются в контейнеры, контролируемые администратором, или используются технологии проектирования, основанные на функциональных возможностях**, для безопасного управления изменениями состояния.
Да, в Sui смарт-контрактможет изменять собственное состояние объекта, ноон не может владеть объектами независимо. В объектно-ориентированной модели 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>
Советы по интерфейсу командной строки:
- Для просмотра информации о праве собственности:
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 для разработчиков.
В сети Sui смарт-контракты не могут «владеть» объектами в традиционном смысле EVM, поскольку право собственности всегда связано с адресом или другим объектом. Однако смарт-контракты, написанные в Move, могут определять и изменять собственные объекты состояния. Обычно это общие объекты или принадлежащие пользователям объекты.
Ключевые концепции
- Право собственности на объект в Суи: Каждый объект принадлежит:
Адрес пользователя (адрес),
Другой объект (вложенное владение),
Совместный (доступный для всех),
Неизменяемый (не может быть изменен после публикации).
-
Состояние смарт-контракта: Чтобы создать состояние контракта, разработчики определяют структуры в модулях Move и публикуют экземпляры этих структур в виде объектов. Затем эти объекты передаются в функции ввода, где их состояние можно прочитать или изменить.
-
Мутирующее состояние: Чтобы изменить состояние объекта смарт-контракта, необходимо:
Передать объект в функцию под именем &mut.
Убедитесь, что файл можно изменять, а также владеть им или делиться им по мере необходимости.
Имейте правильные права доступа.
- Общие объекты для глобального государства: Если вы хотите, чтобы состояние было глобальным, охватывающим весь контракт, вы используете общие объекты:
В struct Counter есть ключ, хранилище, копия { значение: u64, }
прибавка к фонду за публичные входы (счетчик: &mut Counter) { counter.value = счетчик+1; }
- Публикация общих объектов:
Общие объекты должны быть явно созданы и опубликованы при инициализации.
Используйте вызов move или используйте интерфейс командной строки --gas-budget и --shared-object-inputs для взаимодействия с ними.
- Пример процесса развертывания:
Разверните модуль с помощью sui move publish.
Вызовите функцию записи, чтобы создать общий объект:
вызов клиента sui
<PACKAGE_ID>--пакет
--счетчик модулей
--функция create_counter
--аргументы 0
--бюджет газа 1000
Затем вызовите команду increment, указав идентификатор общего объекта.
- Ограничения:
Смарт-контракты не хранят внутреннее состояние, как в Solidity.
Они работают с объектами, явно переданными им.
В модуле нет постоянного «хранилища контрактов».
- Безопасность и право собственности:
Подтвердить право собственности необходимо вручную или с помощью функциональных возможностей.
Для предотвращения мутаций обычно используются такие шаблоны управления доступом, как AdminCap или Whitelist.
- Лучшие практики:
Избегайте ненужного совместного использования объектов, чтобы ограничить потребление газа и борьбу с ним.
Используйте возможности или проверки адресов для безопасного управления доступом.
Правильно используйте ключ и хранилище, чтобы обеспечить постоянство и изменчивость объектов.
- Команды CLI для просмотра:
вызов клиента sui для вызовов функций.
объект клиента sui
sui move test для модульного тестирования логики состояния.
В Sui смарт-контракт, написанный на Move, не может по-настоящему «владеть» собственным объектом в том же смысле, в каком контракт EVM, ссылающийся на себя, может автономно сохранять и изменять внутреннее состояние. Объектно-ориентированная архитектура Sui означает, что все объекты должны быть явно переданы в контекст транзакции, а владение ими осуществляется либо на основе учетной записи, либо на основе совместного использования. Сами по себе смарт-контракты не имеют состояния — они определяют только логику. Фактическое состояние существует в объектах Move, которые необходимо передать функциям для чтения или изменения.
Чтобы изменить объект состояния контракта, вам необходимо структурировать модуль таким образом, чтобы его данные (обычно хранимые в 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, явно переданные в ваши логические функции, что улучшает параллелизм и проверяемость.
Нет, смарт-контракт (модуль 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
objects (transfer::share_object
) для постоянного и глобально доступного состояния. Всегда подтверждайте право собственности, следуя object::is_owner()
правилам линейного типа и соблюдайте их.
Да, смарт-контракт 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
}
###Почему Sui уникальна -Нет «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
Условия соревнования: конструкция, предусматривающая параллельный доступ (например, использование).
Да, смарт-контракт в Sui может изменять собственное состояние объекта, но это необходимо с помощью объектов, явно переданных в его функции. В объектной модели Sui нет внутреннего хранилища контрактов, как в Ethereum; вместо этого состояние поддерживается с помощью изменяемых объектов. Эти объекты могут принадлежать пользователям или совместно использоваться по сети. Чтобы изменить состояние, вы определяете структуру с помощью ключа has, а затем пишете функции ввода, принимающие ссылку &mut на объект. Общие объекты обеспечивают глобальный доступ и необходимы, когда нескольким пользователям приходится взаимодействовать с одним и тем же состоянием. Для изменения общих объектов необходимо пометить функцию как общедоступную и передать правильный идентификатор объекта во время вызовов. Контракты не «владеют» состоянием напрямую, а работают с данными, переданными им с помощью аргументов. Вы можете обеспечить контроль доступа, используя соответствующие функции или проверив адреса отправителей. Такая конструкция обеспечивает высокий уровень параллелизма, улучшенную масштабируемость и детальное предоставление разрешений. В целом, смарт-контракты в Sui изменяют состояние, изменяя определенные Move объекты в соответствии со строгими правилами владения и доступа.
Да, смарт-контракт 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 позволяет заключать автономные контракты — прокси-кошельки не требуются. ) *
###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. Взаимодействие с интерфейсом командной строки
####Развертывание контрактов с отслеживанием состояния
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) | -----------| | ----------| | Одно обновление | 2 500 | | Пакетное обновление (10 предметов) | 3800 |
###Ключевые отличия от EVM
1.Явное владение: объекты должны быть преднамеренно переданы
2. key + store``copy + drop
Мелкозернистая изменчивость: против способностей
3.Параллельная обработка: независимые объекты одновременно мутируют
Для использования в производстве:
- Храните критическое состояние в видеобщих объектов
- Используйтевозможностидля привилегированных операций
- Заранее внедрите путимиграции состояний
Знаете ответ?
Пожалуйста, войдите в систему и поделитесь им.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Заработай свою долю из 1000 Sui
Зарабатывай очки репутации и получай награды за помощь в развитии сообщества Sui.
- Почему BCS требует точного порядка полей для десериализации, когда структуры Move содержат именованные поля?65
- Как максимизировать прибыль, держа SUI: стейкинг и ликвидный стейкинг514
- «Ошибки проверки нескольких источников» в публикациях модуля Sui Move — автоматическое устранение ошибок55
- Ошибка Sui Move — невозможно обработать транзакцию Не найдено действительных газовых монет для транзакции416
- Сбой транзакции Sui: объекты, зарезервированные для другой транзакции49