Sui.

Publicación

Comparte tu conocimiento.

BigSneh.
Jul 30, 2025
P&R expertos

¿Puede un contrato inteligente poseer y mutar su propio estado objeto en Sui?

Intento entender este aspecto de la red Sui porque estoy creando, depurando o implementando algo que toca esta área. Quiero una explicación detallada de cómo funciona este mecanismo o función, junto con el uso relevante de la CLI, la estructura del código de Move o los conceptos arquitectónicos. Mi objetivo es obtener la suficiente claridad para aplicar este conocimiento en un proyecto real, ya sea un contrato inteligente personalizado, un sistema NFT, una integración de monederos o una herramienta DeFi. La red Sui tiene características únicas en comparación con las cadenas de EVM, por lo que me interesa especialmente saber qué la diferencia y cómo afecta eso a las mejores prácticas de desarrollo. Sería útil tener un código de ejemplo, ejemplos de líneas de comandos o errores típicos a los que prestar atención, especialmente cuando se utiliza la CLI o el SDK de Sui o se implementa en localnet/testnet. En última instancia, quiero evitar errores comunes, seguir los mejores principios de seguridad y asegurarme de que la funcionalidad en la que estoy trabajando se comporte como se espera en condiciones realistas.

  • Sui
  • Architecture
  • Move
7
15
Cuota
Comentarios
.

Respuestas

15
Paul.
Paul4340
Jul 31 2025, 05:35

En Sui, un contrato inteligente no puede poseer o mutar directamente su propio estado de objeto. En cambio, el contrato interactúa con los objetos mediante el modelo de propiedad, en el que los objetos pertenecen a direcciones específicas (por ejemplo, la billetera del usuario o una cuenta). Los contratos inteligentes en Sui pueden definir y modificar el estado de los objetos que pertenecen a otras partes (por ejemplo, los usuarios), pero no pueden ser propietarios de los objetos por sí mismos.

Conceptos clave:

*Propiedad de los objetos: los objetos son propiedad de direcciones, no de contratos. *Interacción con objetos: un contrato puede manipular el estado de un objeto, pero solo si tiene acceso a ese objeto mediante referencias mutables o de propiedad.

Código de ejemplo:

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;
    }
}

Uso de la CLI:

Durante la implementación, el contrato solo puede manipular objetos que pertenezcan a una dirección, no a sí misma.

Mejores prácticas:

  • Asegúrese de que los contratos respeten el modelo de propiedad de Sui, transfiriendo objetos entre los contratos y las cuentas de usuario.
  • Gestione siempre los permisos de forma segura para evitar el acceso no autorizado al estado del objeto.
8
Comentarios
.
Ashford.
Jul 31 2025, 06:34

¿Puede un contrato inteligente poseer y mutar su propio estado objeto en Sui?

No, en Sui,los contratos inteligentes no pueden poseer o mutar directamente su propio estado. La propiedad y la mutación de los recursos (como los objetos monetarios o los objetos personalizados) se rigen por las cuentas de usuario o las direcciones autorizadas, no por el contrato en sí.

Puntos clave:

*Propiedad: Los contratos inteligentes en Sui no son apátridas; definen la lógica pero no son propietarios ni almacenan el estado por sí mismos. *Propiedad de los recursos: los recursos (como monedas u objetos personalizados) deben pertenecer a una dirección o entidad, no a un contrato.

Flujo típico:

1.Titularidad de la cuenta: una dirección o un usuario son los propietarios del objeto (p. ej., una moneda). 2.Ejecución inteligente de contratos: el contrato puede modificar el estado de los objetos que le pasa el propietario.

Flujo de ejemplo:

1.El usuario crea un objeto(por ejemplo, una moneda). 2.El usuario pasa el objetoal contrato de mutación. 3. El contrato modifica el objeto pero no lo posee.

Ejemplo de código de movimiento:

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

Ejemplo de CLI:

Implemente un contrato e invoque una función para mutar el estado de un objeto:

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

Errores comunes:

*Confusión de propiedad: Intentar modificar o acceder a un estado que no sea propiedad del contrato generará errores. &mut*Mutabilidad incorrecta: asegúrese de que el objeto que se transfiere al contrato sea mutable ().

Mejores prácticas:

*Garantice la propiedad adecuada: asegúrese de que los objetos que se transfieren al contrato pertenezcan a la dirección correcta. *Realice una prueba con Localnet/Testnet: compruebe siempre la lógica del contrato y los cambios de estado antes de realizar la implementación en la red principal.

7
Comentarios
.
Benjamin XDV.
Jul 31 2025, 09:42

En Sui, los contratos inteligentes (paquetes de movimiento)no puedenposeer o mutar objetos directamente por sí mismos debido al modelo de propiedad centrado en objetos de Sui. Los objetos deben pertenecer a unadirección,a otro objetoo estar marcados comocompartidos/inmutables; los paquetes solo contienen lógica de código. Para la mutación autónoma, normalmente se utilizanobjetos compartidos(con consenso) ocampos dinámicosen los que los objetos principales controlan los objetos secundarios. Esto difiere fundamentalmente del almacenamiento por contrato de EVM, ya que requiere transferencias explícitas de propiedad mediante transacciones en lugar de mediante acciones contractuales internas. Los patrones más comunes incluyenempaquetar objetosen contenedores controlados por el administrador o usarun diseño basado en capacidadespara gestionar las mutaciones de estado de forma segura.

6
Comentarios
.
theking.
Jul 30 2025, 11:13

Sí, en Sui, un contrato inteligentepuede mutar su propio estado de objeto, perono puede poseer objetos de forma independiente. En el modelo centrado en objetos de Sui,cada objeto debe pertenecer a una dirección, a otro objeto o estar marcado como compartido. Los contratos inteligentes no tienen una dirección como en las cadenas de EVM (por ejemplo, Ethereum), por lo que debes confiar en patrones de «propiedad de objetos», como lasestructuras de datos envueltas en objetoso losobjetos compartidos, para persistir y cambiar el estado de las transacciones.

structPara actualizar el estado interno de un contrato, normalmente diseñas un contrato key(con la entrycapacidad) de almacenar datos de estado, pasarlos a tu función y realizar actualizaciones a través de referencias. La propiedad de esta estructura recae en un usuario o está marcada como compartida para permitir un acceso más amplio.

Ejemplo: mutación del estado interno a través de un objeto propio

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;
    }
}

En este ejemplo, createinicializa un Counterobjeto. incrementsolo se puede invocar pasando una referencia mutable a ese objeto. La propiedad recae en un usuario u otro objeto, no en el contrato en sí.

Objetos compartidos para el acceso global

sharedSi su contrato necesitaque varios usuarios interactúen con el mismo objeto, márquelo como. Ejemplos de casos de uso: DAO, contadores globales, juegos en cadena.

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

En el momento de la implementación o mediante una función explícita, debes compartir el objeto:

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

Consejos de CLI:

  • Para ver la propiedad: sui client object <object_id>
  • Para mutar: utilice la --mutbandera o defina &muten la función de entrada
  • Para una mutación compartida: asegúrese de que el objeto se publique como sharedantes de la mutación

Integración con el SDK (TS):

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

Mejores prácticas:

  • Evite intentar almacenar las referencias a objetos dentro de otros objetos, a menos que sea necesario.
  • Si necesita una mutabilidad global, losobjetos compartidosson el enfoque correcto.
  • Uso UIDy keycapacidad para garantizar que los objetos puedan persistir en todas las transacciones.
  • Compruebe siempre que la persona que llama tiene derecho a mutar, especialmente en el caso de objetos compartidos.

Errores comunes:

  • Cannot find mutable reference— Estás transfiriendo un objeto inmutable cuando se requiere mutable.
  • Object is not shared— Estás intentando mutar un objeto que no se ha compartido.
  • Type mismatch— Suele deberse a genéricos incorrectos o al uso indebido de referencias.

Puedes obtener más información sobre la propiedad y los objetos compartidos en la documentación para desarrolladores de Sui.

5
Comentarios
.
SuiLover.
Jul 30 2025, 11:30

En la red Sui, los contratos inteligentes no pueden «poseer» objetos en el sentido tradicional de EVM porque la propiedad siempre está vinculada a una dirección u otro objeto. Sin embargo, los contratos inteligentes redactados en Move pueden definir y mutar sus propios objetos de estado personalizados, que suelen ser objetos compartidos o propios que los usuarios transfieren.

Conceptos clave

  1. Propiedad del objeto en Sui: Cada objeto es propiedad de:

Una dirección de usuario (dirección),

Otro objeto (propiedad anidada),

Compartido (accesible para todos),

Inmutable (no puede cambiar después de la publicación).

  1. Estado de contrato inteligente: Para crear el estado del contrato, los desarrolladores definen las estructuras en los módulos Move y publican las instancias de estas estructuras como objetos. Luego, estos objetos se pasan a funciones de entrada donde se puede leer o modificar su estado.

  2. Estado mutante: Para mutar el estado del objeto de un contrato inteligente, debes:

Pase el objeto a la función como &mut.

Asegúrese de que sea mutable y de que sea de su propiedad o esté compartido, según sea necesario.

Tenga los derechos de acceso correctos.

  1. Objetos compartidos para el estado global: Si desea un estado global que abarque todo el contrato, utilice objetos compartidos:

struct Counter tiene la clave, almacena, copia { valor: u64, }

incremento de fondos de entrada pública (contador: &mut Counter) { counter.value = counter.value + 1; }

  1. Publicación de objetos compartidos:

Los objetos compartidos deben crearse y compartirse de forma explícita en el momento de la inicialización.

Usa move call o la CLI de Sui --gas-budget y --shared-object-inputs para interactuar con ellos.

  1. Ejemplo de flujo de implementación:

Implemente un módulo con sui move publish.

Llame a una función de entrada para crear un objeto compartido:

llamada de cliente sui
<PACKAGE_ID>--paquete
--contador de módulos
--función create_counter
--args 0
--presupuesto de gas 10000

A continuación, llame al incremento con el ID de objeto del objeto compartido.

  1. Limitaciones:

Los contratos inteligentes no almacenan el estado interno como en Solidity.

Operan sobre objetos que se les pasan de forma explícita.

No existe un «almacenamiento por contrato» persistente dentro del módulo.

  1. Seguridad y propiedad:

Debe validar la propiedad de forma manual o mediante funciones.

Es habitual utilizar patrones de control de acceso, como AdminCap o Whitelist, para controlar las mutaciones.

  1. Mejores prácticas:

Evite compartir objetos de forma innecesaria para limitar el consumo y la contención del gas.

Aproveche las capacidades o las comprobaciones de direcciones para gestionar el acceso de forma segura.

Utilice la clave y el almacenamiento adecuados para permitir la persistencia y la mutabilidad de los objetos.

  1. Comandos de la CLI a observar:

llamada de cliente sui para llamadas a funciones.

objeto de cliente sui para inspeccionar los datos o el estado del objeto.

sui move test para probar la lógica de estado de las pruebas unitarias.

4
Comentarios
.
shamueely.
Jul 30 2025, 11:38

En Sui, un contrato inteligente redactado en Move no puede realmente «poseer» su propio objeto, en el mismo sentido en que un contrato de EVM autorreferenciado podría mantener y mutar el estado interno de forma autónoma. La arquitectura centrada en objetos de Sui significa que todos los objetos deben transferirse explícitamente al contexto de la transacción y su propiedad se basa en la cuenta o es compartida. Los contratos inteligentes en sí mismos no tienen estado: solo definen la lógica. El estado actual existe en los objetos Move, que deben transferirse a las funciones para su lectura o mutación.

Para mutar el objeto de estado de un contrato, debes estructurar el módulo de forma que sus datos (normalmente almacenados en una has keyestructura) sean:

*Propiedad de una dirección de usuario(útil para la lógica de la cuenta), *Compartido a través de share_object()(para apoyar a varios actores, como en DeFi, DAOs, juegos, etc.).

entryCuando utilices objetos compartidos, debes marcar tus funciones con &mutel objeto compartido y pasarlo como referencia.

Este es un ejemplo de un estado compartido que se puede mutar:

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;
    }
}

En este ejemplo, Vaultdebe ser un objeto compartido si quieres que varios usuarios puedan acceder a él mediante entryfunciones. Al implementarlo, compartes el objeto de la siguiente manera:

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

Una vez compartido, cualquier entryfunción puede mutar el objeto, siempre que lo reciba como entrada. Sui garantiza la seguridad mediante las reglas de propiedad y el control de versiones para evitar que surjan condiciones de competencia.

Para obtener más información sobre cómo los contratos inteligentes en Sui interactúan con el estado de los objetos, el acceso compartido y la propiedad, visita: https://docs.sui.io/build/programming-model/object-basics

Este enfoque es lo que diferencia a Sui de las cadenas EVM. El almacenamiento interno por contrato no se muta directamente. En su lugar, mutas los objetos de Move que se transfieren de forma explícita a tus funciones lógicas, lo que mejora la simultaneidad y la verificabilidad.

4
Comentarios
.
Alya.
Alya-14
Jul 30 2025, 17:29

No, un contrato inteligente (módulo Move) no puede poseer o mutar directamente su propio estado de objeto en Sui.

Los objetos son entidades de primera clase que pertenecen a direcciones u otros objetos o que comparten (no) módulos. La mutación de estado se produce mediante funciones que toman los objetos como parámetros mutables, y las reglas de propiedad se aplican a nivel de transacción.

Ejemplo:

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

La incrementfunción Countersolo puede mutar cuando la transacción pasa una referencia mutable a un objeto propiedad del remitente. El módulo en sí no tiene ningún estado.

Usa sharedobjects (transfer::share_object) para obtener un estado persistente y accesible globalmente. Valide siempre la propiedad con object::is_owner()reglas de tipo lineal y sígalas.

4
Comentarios
.
Arnold.
Arnold3036
Jul 31 2025, 08:16

Sí, un contrato inteligente Sui (paquete Move) puede poseer y mutar su propio estado a través deobjetos compartidosocampos de objetos dinámicos, a diferencia del diseño sin estado de EVM.

####Mecanismos clave 1.Objetos compartidos:

  • Cualquier persona puede mutarlo globalmente (con reglas).
  • Definido con (dirección del paquete) key + storey propiedad de 0x0(dirección del paquete).
  struct ContractState has key, store {
      id: UID,
      value: u64,
  }

2.Campos de objetos dinámicos:

  • El paquete puede «poseer» objetos almacenando sus ID.
  fun add_state(ctx: &mut TxContext) {
      let state = ContractState { id: object::new(ctx), value: 42 };
      transfer::share_object(state); // Make it globally mutable
  }

###Por qué Sui es único -Sin «msg.sender": el control de acceso se realiza mediante el sistema de tipos de Move, no mediante EOAS. -Mutaciones paralelas: los objetos compartidos permiten escrituras simultáneas (a diferencia de los TX serializados de EVM).

###Ejemplo de 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

###Dificultades comunes 1.**Compartir en exceso: evítelo share_objecta menos que sea realmente necesario (úselo transfer::transferpara propiedad privada). 2. sui::lockCondiciones de carrera: Diseño para el acceso paralelo (por ejemplo, uso).

4
Comentarios
.
290697tz.
Jul 30 2025, 11:35

Sí, un contrato inteligente en Sui puede mutar su propio estado de objeto, pero debe hacerlo a través de objetos que pasen explícitamente a sus funciones. En el modelo de objetos de Sui, no existe un almacenamiento interno por contrato como en Ethereum; en cambio, el estado se mantiene mediante objetos mutables. Estos objetos pueden ser propiedad de los usuarios o compartirse en la red. Para cambiar el estado, se define una estructura con la capacidad clave has y, a continuación, se escriben funciones de entrada que acepten una referencia de &mut al objeto. Los objetos compartidos permiten el acceso global y son necesarios cuando varios usuarios necesitan interactuar con el mismo estado. La mutación de objetos compartidos requiere marcar la función como entrada pública y pasar el ID de objeto correcto durante las llamadas. Los contratos no «poseen» directamente al estado, sino que se basan en los datos que se les transmiten mediante argumentos. Puede reforzar el control de acceso mediante funciones o comprobando las direcciones de los remitentes. Este diseño admite un alto paralelismo, una mejor escalabilidad y permisos detallados. En general, los contratos inteligentes en Sui mutan al modificar los objetos definidos por Move bajo estrictas reglas de propiedad y acceso.

3
Comentarios
.
Evgeniy CRYPTOCOIN.
Jul 31 2025, 09:09

Sí, un contrato inteligente Sui (módulo Move) puede poseer y mutar sus propios objetos a través de:

1.Objetos propios: se crean durante el inicio del módulo (se almacenan en el ID del paquete). 2.Objetos compartidos: marcados sharedpara el acceso de varios escritores.

###Diferencias clave con respecto a EVM:Sin propietario externo: los objetos pueden pertenecer al propio paquete. ✔Mutación directa: no se necesita un sistema de aprobación (a diferencia del ERC-20).

Ejemplo de patrón:

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

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

Esté atento a:

  • Costos de almacenamiento de objetos propios.
  • Úselo sharedpara el estado global.
  • (El modelo de objetos de Sui permite contratos autónomos, sin necesidad de carteras proxy. ) *
3
Comentarios
.
Bekky.
Bekky1762
Jul 31 2025, 10:27

1. Concepto central: propiedad centrada en objetos**

A diferencia de las variables de almacenamiento de EVM, los contratos inteligentes de Sui funcionan a través deobjetos propiosque pueden mutarse en función de estrictas reglas de propiedad.

####Características clave | Características | Sui | EVM | ---------| -----| | -----| | Representación estatal | Objetos con UID | Variables de almacenamiento | | Propiedad | keyCapacidad explícita | Implícita para contratar | | Mutabilidad | &mutreferencias | Modificación directa |


2. Mueva los patrones de implementación**

####Contrato de autopropiedad

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;
    }
}

####Modelos de propiedad

ModeloPatrón de códigoCaso de uso
CompartidoEstado transfer::share_objectmutable global
transfer::freeze_objectInmutable
transfer::transferDe propiedad

3. Interacciones con la CLI**

####Implementación de contratos con estatal

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

####Estado mutante

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

###4. Consideraciones arquitectónicas**

####Control de concurrencia

// 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;
}

####Migración estatal (actualizaciones)

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. Patrones de seguridad**

####Acceso basado en capacidades

struct AdminCap has key, store {
    id: UID
}

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

####Protección de reentramiento

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. Dificultades y soluciones comunes**

ErrorCausaSolución
EInvalidSharedObjectUseMutabilidad incorrectaUsar &mutreferencia
EMissingOwnerObjeto que no pertenece al paquetetransfer::transfera la dirección del paquete
EImmutableshare_objectIntentando modificar un objeto congelado

###7. Optimización del rendimiento**

####Mutaciones por lotes

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;
    }
}

####Comparación de costos de gas

OperaciónGas (SUI)
Actualización única2.500
Actualización por lotes (10 artículos)3.800

###Diferenciadores clave de EVM 1.Propiedad explícita: los objetos deben transferirse deliberadamente 2. key + store``copy + dropMutabilidad minuciosa: contra habilidades 3.Procesamiento paralelo: los objetos independientes mutan simultáneamente

Para uso en producción:

  • Almacene el estado crítico comoobjetos compartidos
  • Utilicecapacidadespara operaciones privilegiadas
  • Implemente rutas demigración estatalpor adelantado
1
Comentarios
.

Sabes la respuesta?

Inicie sesión y compártalo.