Sui.

Publicación

Comparte tu conocimiento.

shamueely.
Jul 30, 2025
P&R expertos

Patrones de diseño y gestión de concurrencia para objetos compartidos en Sui Move

Estoy intentando entender el patrón arquitectónico correcto cuando trabajo con objetos compartidos en Sui Move, especialmente cuando varios usuarios necesitan interactuar con ellos al mismo tiempo (por ejemplo, en un campo de juego, en un rastreador de votos de DAO o en una bóveda de préstamos).

He leído que los objetos compartidos pueden provocar problemas de sincronización, pero aún no tengo claro qué es lo siguiente:

  • ¿Cuándo exactamente debo usar un sharedobjeto en comparación con cuándoowned?
  • ¿Cómo gestiona Sui los intentos de transacción simultáneos en el mismo objeto compartido? ¿Tengo que poner en cola o bloquear las cosas manualmente? ConflictTransaction* ¿Cuál es la mejor práctica para diseñar módulos que admitan una alta concurrencia pero eviten errores frecuentes?
  • ¿Debería hacer algo especial (como dividir los campos mutables en subobjetos) para reducir la controversia?
  • Sui
  • Architecture
  • NFT Ecosystem
  • Move
2
13
Cuota
Comentarios
.

Respuestas

13
theking.
Jul 30 2025, 10:21

Cuando estás creando una DApp en Sui en la que varios usuarios necesitan interactuar con el mismo estado, como en un campo de juego, un protocolo de préstamo o DAO, debes usarobjetos compartidosen lugar de objetos propios. Los objetos compartidos son mutables y de acceso público, lo que significa que cualquiera puede acceder a las funciones de entrada en ellos siempre que estén en el gráfico global de objetos. Por el contrario, los objetos propios son privados para el usuario y son ideales para sus activos personales, como carteras o inventarios. Por lo tanto, debes usar un objeto compartido cuando las actualizaciones de estado deban ser visibles y utilizables por muchos usuarios a la vez.

Sui gestiona las transacciones simultáneas en objetos compartidos mediante un mecanismo denominadovalidación de órdenes causales, que requiere que proporciones de forma explícita la versión más reciente conocida de un objeto compartido. ConflictTransactionSi dos usuarios intentan modificar el mismo objeto compartido al mismo tiempo con versiones desactualizadas, uno tendrá éxito y los demás fallarán y se producirá un error. Sui no pone en cola ni bloquea los objetos compartidos de forma nativa, por lo que debes diseñar tus módulos Move para minimizar la superposición de escrituras. Una de las mejores maneras de reducir los conflictos esdiseñar teniendo en cuenta el paralelismo. Por ejemplo, en lugar de almacenar todos los estados mutables en el objeto compartido raíz, puedesdividir los campos de alto contenido en objetos secundarios independientes. De este modo, cada uno de esos elementos secundarios se puede escribir de forma independiente, lo que reduce la probabilidad de que surjan conflictos entre transacciones.

Una buena práctica es mantener el objeto compartido principal como un directorio y mover los estados granulares que se actualizan con frecuencia (como las puntuaciones, los votos o los saldos de préstamos de los jugadores) a campos dinámicos o subobjetos más pequeños. De esta forma, los usuarios actualizan solo la parte específica que necesitan, y no todo el objeto compartido. También es inteligente separar los componentes que requieren mucha lectura y escritura. Además, debes crear flujos de transacciones claros y deterministas que utilicen siempre la versión más reciente de los objetos compartidos y reintentar la lógica para que los clientes gestionen las transacciones fallidas.

Puedes obtener más información sobre el diseño de objetos compartidos y la mitigación de conflictos en la documentación de Sui aquí: https://docs.sui.io/concepts/objects#shared-objects.

Si estás gestionando algo como un rastreador de votos, aquí tienes un ejemplo simplificado de bloques de transacciones para reducir los conflictos:

const tx = new TransactionBlock();
tx.moveCall({
  target: `$ {packageId} :vote_tracker: :cast_vote`,
 argumentos: [
 tx.sharedObject (VoteTrackerId),//referencia de objeto compartido
 tx.pure (voterID),//objeto propio o clave pública
 tx.pure (proposalID),//datos puros
 tx.pure (VoteChoice)
 ]
});
1
Mejor Respuesta
Comentarios
.
Benjamin XDV.
Jul 31 2025, 09:52

En Sui Move, losobjetos compartidos(marcados conkey + store) son esenciales para la interacción entre varios usuarios, pero requieren un diseño cuidadoso de concurrencia. Utilízalos cuando el estado deba ser mutable a nivel mundial (por ejemplo, en juegos, DAO), mientras que los objetos propios o inmutables se adaptan a situaciones de un solo usuario. Sui serializa automáticamente las transacciones por objeto compartido, pero las escrituras frecuentes pueden provocar ConflictTransactionerrores. Para mitigar este problema, puedes dividir los campos activosen objetos secundarios independientes (por ejemplo, uno por usuario) o realizar las actualizaciones por lotes. Para lograr un alto rendimiento, adoptapatrones de abastecimiento de eventos**: almacena las acciones como eventos inmutables y agrega el estado periódicamente. transfer::share_objectMinimice siempre los campos compartidos mutables y prefiera los intercambios atómicos a través de mutaciones directas.

8
Comentarios
.
Paul.
Paul4300
Jul 31 2025, 05:46

En Sui Move, el manejo eficaz de objetos compartidos y la concurrencia requiere un diseño cuidadoso para evitar condiciones de carrera y una gran contienda. Este es un desglose de las mejores prácticas y patrones arquitectónicos:

1.Cuándo usar objetos compartidos y objetos propios:

*Objetos compartidos: utilízalos cuando varios usuarios necesiten interactuar con el mismo objeto al mismo tiempo (por ejemplo, si comparten el estado de una partida o si tienen un registro de votos DAO). *Objetos propios: utilízalos cuando el objeto sea específico de un único usuario o cuenta, lo que evita compartir el estado y reduce los problemas de simultaneidad.

2.Gestión simultánea de transacciones en Sui:

  • Sui gestiona la simultaneidad automáticamente mediante el uso debloqueos de transaccionespara evitar la modificación simultánea del mismo objeto. *Noes necesario poner en cola o bloquear manualmente los objetos compartidos, ya que Sui impone un bloqueo a nivel de objeto. Sin embargo,es posible que aparezcan errores de transacciones conflictivassi varias transacciones entran en conflicto en el mismo objeto.

3.Mejores prácticas para una alta concurrencia:

*Minimiza la contención: divide los campos mutables en subobjetos independientes para permitir actualizaciones paralelas en diferentes partes del objeto. *Evite los puntos conflictivos: distribuya el estado que se modifica con frecuencia en varios objetos (por ejemplo, en lugar de tener un único registro compartido, divídalo en varios grupos o cuentas). *Control de versiones: utilice objetos versionados o cree objetos nuevos para realizar un seguimiento de las actualizaciones en lugar de mutar el mismo objeto repetidamente.

4.Gestión de la contención:

  • Considere la posibilidad de dividir los campos mutables en objetos más pequeños**para reducir la contención. Esto permite que diferentes partes del objeto se actualicen simultáneamente, lo que reduce la posibilidad de conflictos.
  • Usa lastransacciones atómicaspara agrupar las acciones relacionadas en una sola, garantizando la coherencia entre los objetos relacionados.

Ejemplo:

Si tienes unrastreador de votospara una DAO:

  • En lugar de almacenar todos los votos en un único objeto compartido, divídalos en varios objetos (por ejemplo, uno por propuesta), lo que permitirá actualizar en paralelo cada propuesta y reducir la controversia.

Conclusión:

Para lograr una alta concurrencia, minimice la controversia distribuyendo el estado, utilizando subobjetos y aprovechando la gestión automática de transacciones de Sui. Asegúrese de entender sus patrones de acceso y de estructurar los objetos para minimizar los puntos de conflicto.

7
Comentarios
.
Ashford.
Jul 31 2025, 07:37

Comprender los patrones de diseño y la gestión de concurrencia para objetos compartidos en Sui Move

Cuando se trata deobjetos compartidosenSui Move, la gestión de la simultaneidad se vuelve fundamental, ya que es posible que varios usuarios necesiten interactuar con el mismo objeto simultáneamente. Esto es especialmente cierto en casos de uso como losestadios de juegos, losrastreadores de votos DAOy losbóvedas de prestamiento, en los que se espera una alta concurrencia. La red Sui ofrece algunas funciones que ayudan a gestionar la simultaneidad, pero aun así requiere un diseño cuidadoso para evitar errores comunes, como loserrores de transacciones conflictivas.

1.Cuándo usar objetos compartidos frente a objetos poseídos

*Objetos propios:

  • Un objeto esde propiedadsi lo administra una sola dirección, que puede transferirlo o modificarlo. *Usa objetos en propiedadcuando esperas que una sola entidad controle un objeto e interactúe con él. Por ejemplo, si tienes un monedero con monedas, cada monedero es propietario de sus propias monedas. *Objetos compartidos:

  • Se puede acceder a los objetos compartidos y modificarlos desde varias direcciones simultáneamente. Sui te permite definir objetos comocompartidoshaciéndolos mutables y proporcionando acceso a múltiples partes. *Usa objetos compartidospara situaciones en las que varios usuarios o direcciones necesitan interactuar con el mismo objeto, como:

*Rastreadores de votos DAO: varios usuarios pueden votar por el mismo objeto. *Bóvedas de prestamiento: varios usuarios pueden prestar y pedir prestado desde la misma bóveda. *Campos de juego: varios usuarios interactúan con el estado del juego al mismo tiempo.

Consideración clave: Los objetos compartidos deben usarse con cuidado, ya que pueden provocar contenimiento**, es decir, situaciones en las que varias transacciones intentan acceder al mismo objeto y modificarlo a la vez.

2.Simultaneidad e intentos de transacción en objetos compartidos

Sui garantiza que lastransaccionessimultáneas en el mismoobjeto compartidose gestionen correctamente al aplicar elaislamiento transaccional. Si varias transacciones intentan mutar el mismo objeto compartido al mismo tiempo, una de ellasfallarádebido a unacontención.

Cuando una transacción intenta modificar un objeto compartido que ya está siendo modificado por otra transacción, Sui devolverá el errorConflictTransaction. Sin embargo,Sui gestiona la mayor parte de la gestión de la simultaneidad internayno es necesario poner en cola o bloquearobjetos manualmente. En su lugar, debe diseñar su contrato para minimizar las disputas y evitar situaciones en las que dos transacciones entren en conflicto con frecuencia.

3.Mejores prácticas para lograr una alta concurrencia y reducir los errores en las transacciones conflictivas

Paradiseñar módulosque puedan gestionar una alta concurrencia y evitar los frecuentes errores deConflictTransaction, sigue estas prácticas recomendadas:

a.Minimiza los puntos de conflicción:

*Limitar el acceso modificable: mantén la cantidad de campos mutables en los objetos compartidos lo más pequeña posible. Cada campo mutable introduce un posible punto de discordia. *Utilice objetos propios para obtener datos independientes: en lugar de compartir todo, almacene los datos independientes en objetos propios. Por ejemplo, si tienes datos específicos de un usuario (como el saldo), guárdalos en un objeto propio en lugar de en uno compartido.

b.Usa el patrón de «partición de estados»:

  • Divida su objeto compartido en**múltiples subobjetos para reducir la contención. Por ejemplo, en lugar de tener un objeto compartido que registre todo el estado del juego, puedes dividirlo en varios subobjetos:

  • Uno para cada estado deljugador.

  • Uno para losajustes del juego.

  • Uno para losdatos de la tabla clasificatoria.

  • De esta forma, las transacciones relacionadas con diferentes partes del sistema pueden realizarse simultáneamente sin bloquearse entre sí.

c.Operaciones por lotes:

  • Cuando trabajes con objetos compartidos, realiza las actualizaciones por lotes para reducir la cantidad de transacciones que necesitan interactuar con el objeto. Esto puede ayudar a evitar conflictos frecuentes. *Usa recopilacionescomo vectores o conjuntos para gestionar varias actualizaciones en una sola transacción.

d.Usa operaciones atómicas:

  • Siempre que sea posible, diseñe sus módulos para utilizar operaciones atómicas siempre que sea posible. Por ejemplo, en lugar de tener transacciones separadas para comprobar una condición y, a continuación, actualizar un campo, agrupe las comprobaciones y actualizaciones en una sola operación atómica.

e.Lógica de reintento:

  • Si bien Sui gestiona los reintentos internamente, puedes implementar la lógica de reintentos en el nivel de la aplicación para gestionar los errores de contención ocasionales. Por ejemplo, si ConflictTransactionse produce un error, basta con volver a intentar la transacción o ponerla en cola para ejecutarla más adelante.

4.**Reducir la contención dividiendo los campos mutables en subobjetos

Esta es una práctica muy recomendable. Cuando se trata de objetos compartidos, cuantos más camposmutableshaya en un objeto compartido**, mayor será la probabilidad de que dos transacciones intenten mutar el mismo campo al mismo tiempo.

*Ejemplo 1: Si tienes un objeto compartido que representa unabóveda de prestamiento, divídelo en subobjetos:

  • Uno paradepósitos: haz un seguimiento de los depósitos individuales por separado.
  • Uno paracréditos: haz un seguimiento de los préstamos individuales por separado.
  • Uno paravault state: realiza un seguimiento de la información general del estado (por ejemplo, el valor total o la tasa de interés).

De este modo, una transacción que modifica un subobjeto (p. ej., el subobjetocrédito) no entra en conflicto con una transacción que modifica otro (p. ej., el subobjetodepósito).

*Ejemplo 2: En unaarena de juego:

  • Divide el estado del juego en subobjetos para cada jugador, estado del juego y estadísticas de batalla. Esto reduce el riesgo de conflictos cuando diferentes jugadores interactúan con sus estados de juego individuales.

Al dividir los campos mutables ensubobjetos, se reduce la probabilidad de que varios usuarios intenten modificar el mismo objeto simultáneamente.

5.Otras técnicas para gestionar la concurrencia en Sui

*Bloqueo (bloqueos explícitos): Si bien Sui no requiere que gestiones los bloqueos manualmente, en algunos casos, es posible que desees aplicarbloqueos explícitosutilizandoobjetos de bloqueo(objetos separados que garantizan que solo una transacción pueda acceder a un recurso determinado a la vez).

*Aislamiento temporal: si tus objetos solo cambian de vez en cuando, considera la posibilidad de introducir elaislamiento temporal. Por ejemplo, si administras una bóveda o un sistema de votación, estableceperiodos de votaciónoventanas de transaccionespara limitar las interacciones en determinados momentos.

6.**Ejemplo de código para gestionar la concurrencia con subobjetos

Este es un ejemplo que ilustra cómo reducir la controversia dividiendo unabóveda de prestosen subobjetos más pequeños:

module LendingVault {

    struct Deposit has store {
        amount: u64,
        depositor: address,
    }

    struct Loan has store {
        amount: u64,
        borrower: address,
    }

    struct VaultState has store {
        total_value: u64,
        interest_rate: u64,
    }

    struct LendingVault has store {
        deposits: vector<Deposit>,
        loans: vector<Loan>,
        vault_state: VaultState,
    }

    // Function to add a deposit
    public fun add_deposit(vault: &mut LendingVault, depositor: address, amount: u64) {
        let deposit = Deposit { amount, depositor };
        Vector::push_back(&mut vault.deposits, deposit);
        vault.vault_state.total_value = vault.vault_state.total_value + amount;
    }

    // Function to add a loan
    public fun add_loan(vault: &mut LendingVault, borrower: address, amount: u64) {
        let loan = Loan { amount, borrower };
        Vector::push_back(&mut vault.loans, loan);
        vault.vault_state.total_value = vault.vault_state.total_value - amount;
    }
}

Resumen

*Usa objetos compartidoscuando varios usuarios necesiten interactuar con el mismo objeto al mismo tiempo (p. ej., votaciones de DAO, estado del juego, préstamos de bóvedas). *Minimiza la contencióndividiendo los objetos compartidos de gran tamaño en subobjetos más pequeños y reduciendo el número de campos mutables. *Evite los frecuentes errores de ConflictTransaccionsiguiendo las prácticas recomendadas, como la partición de estados, las operaciones por lotes y el uso de operaciones atómicas.

  • Lalógica de reintentosy elcontrol de concurrencia optimistase pueden utilizar para gestionar los conflictos con facilidad.
  • Elmodelo de transaccionesy laresolución de conflictosde Sui son sólidos, pero eldiseñode tus objetos compartidos es clave para garantizar un acceso simultáneo eficiente.

Si sigues estos principios de diseño, podrás gestionar una alta concurrencia en tus módulos basados en Move y, al mismo tiempo, evitar los errores típicos, como losconflictosy loserrores de transacción.

7
Comentarios
.
Evgeniy CRYPTOCOIN.
Jul 31 2025, 09:29

Utiliceobjetos compartidospara acceder a varios escritores (por ejemplo, juegos, DAO). Patrones clave:

1.De propiedad frente a compartido

  • En propiedad: de un solo escritor (más rápido).
  • Compartido: escrituras simultáneas (mayor velocidad).

2.Manejo de concurrencia

  • Las secuencias de Sui comparten los TX de los objetos automáticamente (sin bloqueos manuales).
  • Divide los datos más importantes en subobjetos (p. ej., 1 por jugador) para reducir los conflictos.

3.Mitigación de conflictos Table<ID, PlayerData>- Aísle los campos de alto tráfico (p. ej.,).

  • Utilice PTB para operaciones atómicas con múltiples objetos.

Esté atento a: -ConflictTransaction: Divida los datos o actualice por lotes.

  • Picas de gas en objetos compartidos.
  • (El tiempo de ejecución de Sui gestiona los conflictos y se optimiza mediante la fragmentación de datos). ) *
6
Comentarios
.
Alya.
Alya-14
Jul 30 2025, 17:38

Usashared objects(transfer::share_object) cuando varios usuarios deban mutar el mismo objeto (p. ej., bóveda, DAO, estado del juego). De lo contrario, usaposeido.

TransactionLockConflictSui gestiona la simultaneidad mediante elconsenso de Narwhal y Tusk: las transacciones conflictivas sobre un objeto compartido se serializan; solo una tiene éxito por ronda; las demás fallan con ella. No es necesario el bloqueo manual, perodebes diseñar para que se vuelvan a intentar.

Mejores prácticas:

  • Minimice el estado mutable de los objetos compartidos; divida las zonas activas en subobjetos independientes (por ejemplo, almacenes compartidos por usuario). VecMap- Úselo Tableo para mapeos escalables.
  • Evite los cálculos de larga duración en las funciones compartidas.
  • Emite eventos en lugar de almacenar el estado efímero.
  • Para sistemas con mucha contención, utilice esquemaspor lotesoconfirm-revelaciónpara reducir los conflictos.

Los objetos compartidos son accesibles desde cualquier parte del mundo, pero requieren más espacio y contención. Optimice para lograr la idempotencia y reintente la lógica en el código del cliente.

5
Comentarios
.
Arnold.
Arnold3036
Jul 31 2025, 08:34

Paraobjetos compartidosen Sui Move, usa estos patrones para gestionar la simultaneidad:

####1. ¿Compartido o propiedad? -Objeto compartido (key + store):

  • Utilízalo paraestado global(p. ej., juegos, DAO).
  • Permiteescrituras paralelas(a diferencia de las TX serializadas de EVM).
 struct GameArena has key, store { id: UID, players: vector<address> }

-Objeto propiedad:

  • Úselo paradatos específicos del usuario(por ejemplo, NFT, carteras).
 struct PlayerInventory has key { id: UID, items: vector<Item> }

2. Gestión de concurrencia*

-Sin bloqueos manuales: Suiresuelve los conflictos automáticamente(a diferencia de EVM). -Disminución dividida: divide los objetos compartidos ensubobjetos más pequeños(por ejemplo, por jugador o por fragmento).

 struct PlayerScore has key, store { id: UID, points: u64 } // Less contention

####3. Reduzca los ConflictTransactionerrores -Aislar escrituras: actualizadiferentes camposen diferentes TX. &mut-Utilízalo con sensate: evita las mutaciones generalizadas.

 public entry fun update_score(
     arena: &mut GameArena,
     player: address,
     points: u64
 ) { /* ... */ } // Only touches 1 player’s data

####4. Mejores prácticas -Actualizaciones por lotes: agrupa las operaciones que no sean conflictivas (por ejemplo, las votaciones en una DAO). -Impulsado por eventos: emite eventos en lugar de mutar en estado siempre que sea posible.

 struct VoteEvent has copy, drop { voter: address, choice: u8 }
5
Comentarios
.
JK spike.
Aug 15 2025, 12:39

Utilice objetos compartidos para acceder a varios escritores (por ejemplo, juegos, DAO). Patrones clave:

De propiedad frente a compartida

Propio: de un solo escritor (más rápido). Compartido: escrituras simultáneas (mayor velocidad). Manejo de concurrencia

Sui secuencia los TX de objetos compartidos automáticamente (sin bloqueos manuales). Divide los datos más importantes en subobjetos (p. ej., 1 por jugador) para reducir los conflictos. Mitigación de conflictos

Aísle los campos de alto tráfico (por ejemplo, la tabla<ID, PlayerData>). Utilice los PTB para operaciones atómicas con múltiples objetos. Esté atento a:

ConflictTransaction: datos divididos o actualizaciones por lotes. Picas de gas en los objetos compartidos. (El tiempo de ejecución de Sui gestiona los conflictos y se optimiza mediante la fragmentación de datos).

3
Comentarios
.
Jeff.
Jeff1911
Aug 23 2025, 06:03

In Sui Move, shared objects (marked with key + store) are essential for multi-user interaction but require careful concurrency design. Use them when state must be globally mutable (e.g., games, DAOs), while owned/immutable objects suit single-user scenarios. Sui serializes transactions per shared object automatically, but frequent writes may trigger ConflictTransaction errors—mitigate this by splitting hot fields into separate child objects (e.g., one per user) or batching updates. For high throughput, adopt event-sourcing patterns: store actions as immutable events and aggregate state periodically. Always minimize mutable shared fields and prefer atomic swaps via transfer::share_object over direct mutations

3
Comentarios
.
Bekky.
Bekky1762
Jul 31 2025, 12:26

Objetos compartidos frente a objetos propios: cuándo usar cada uno

Usa objetos compartidos cuando:

  • Es necesario que varios usuarios muten al mismo estado
  • El objeto representa un recurso público (como un campo de juego o un DAO)
  • Necesitas patrones de acceso sin permiso

Usa objetos propios cuando:

  • Solo una dirección debe controlar el objeto
  • Quieres aprovechar al máximo la ejecución en paralelo de Sui
  • Los objetos representan activos específicos del usuario

Estrategias de gestión de la concurrencia

1. Patrón de subobjetos (reduce la contención)

Divida los campos que se actualizan con frecuencia en objetos independientes:

struct GameArena has key {
    id: UID,
    // Immutable or rarely changed fields
    config: ArenaConfig,
    // Split mutable state
    player_state: Table<address, PlayerState>,
    leaderboard: Leaderboard
}

struct PlayerState has key, store {
    id: UID,
    health: u8,
    score: u64
}

###2. Actualizaciones por lotes con vectorios/tablas

struct DAOVault has key {
    id: UID,
    // Store multiple pending actions
    pending_votes: Table<ID, Vote>,
    pending_deposits: Table<address, Deposit>
}

public entry fun batch_process(
    vault: &mut DAOVault,
    ctx: &mut TxContext
) {
    // Process all pending items at once
    let votes = table::remove_all(&mut vault.pending_votes);
    process_votes(votes);
}

3. Procesamiento basado en la época

struct LendingPool has key {
    id: UID,
    current_epoch: u64,
    next_epoch_data: EpochData,
    current_epoch_data: EpochData
}

public entry fun advance_epoch(pool: &mut LendingPool) {
    let finished = pool.current_epoch_data;
    pool.current_epoch_data = pool.next_epoch_data;
    pool.next_epoch_data = new_epoch_data();
    process_finished_epoch(finished);
}

Técnicas para evitar conflictos

1.Partición a nivel de campo:

  struct HighTrafficObject has key {
      id: UID,
      // Split into separate objects per "hot" field
      stats_by_category: Table<u8, CategoryStats>
  }

2.Cola de ejecución retrasada:

  struct ActionQueue has key {
      id: UID,
      pending: VecMap<u64, Action>
  }
  
  public entry fun execute_ready_actions(
      queue: &mut ActionQueue,
      ready_up_to: u64
  ) {
      // Processes actions in batches
  }

3.Concurrencia optimista con el versión:

  struct Versioned has key {
      id: UID,
      version: u64,
      data: vector<u8>
  }
  
  public entry fun update(
      obj: &mut Versioned,
      new_data: vector<u8>,
      expected_version: u64
  ) {
      assert!(obj.version == expected_version, EBAD_VERSION);
      obj.data = new_data;
      obj.version = expected_version + 1;
  }

Ejemplos prácticos de CLI

Comprobar las dependencias de los objetos antes de enviarlos:

sui client inspect-transaction --serialize-unsigned <TX_BYTES>

Simulación de escenarios de contención:

sui move test --path <YOUR_PACKAGE> --gas-budget 10000

Resumen de mejores prácticas

1.Minimizar las mutaciones de objetos compartidos: diseño para escrituras poco frecuentes en objetos compartidos 2.Usa objetos infantiles: descompone el estado para reducir los puntos de discordia 3.Operaciones por lotes: agrupa los cambios relacionados en transacciones únicas 4.Considera los modelos híbridos: combina objetos propios con una coordinación compartida ocasional 5. sui-tool replaySupervisar puntos conflictivos: utilízalo para analizar la contención

Recuerda que el motor de ejecución de Sui gestiona automáticamente cierta concurrencia a través de su modelo de objetos, pero aun así necesitas diseñar tus estructuras de datos para minimizar los conflictos lógicos.

2
Comentarios
.
24p30p.
24p30p2038
Jul 31 2025, 05:25

Deberías usar unobjeto compartidoen Sui Move cuando varios usuarios necesiten interactuar con la misma parte del estado y esos usuarios no estén todos bajo el mismo propietario. Algunos ejemplos son un campo de juego abierto a todos los jugadores, un rastreador de votos de la DAO que recopila los votos de diferentes direcciones o una bolsa de préstamos en la que cualquiera puede depositar. Los objetos compartidos son accesibles en todo el mundo y se pueden actualizar mediante consenso, a diferencia de losobjetos propios, que están vinculados a una sola dirección y se modifican sin un consenso total.

Sui gestiona la simultaneidad en los objetos compartidos al exigir un consenso total para cualquier transacción que los modifique. ConflictTransactionCuando dos usuarios intentan mutar el mismo objeto compartido casi al mismo tiempo, solo una transacción se realiza correctamente; las demás son rechazadas con un error. Esto hace que los objetos compartidos sean eficaces, pero también introduce problemas de contención cuando no se diseñan con cuidado.

Para permitir una alta concurrencia sin ConflictTransactioncometer errores frecuentes, debes usarpatrones de diseño que aíslen el estado mutable. En lugar de almacenar todos los datos mutables en un único objeto compartido, divídalos en varios objetos secundarios, cada uno con su propiedad o estado compartido. Por ejemplo, en un campo de juego:

struct Arena has key, store {
    game_id: u64,
    players: vector<address>,
}

struct PlayerState has key, store {
    hp: u64,
    energy: u64,
}

Haga que sea Arenacompartido, pero asigne a cada uno PlayerStatesu propio objeto compartido. De esta forma, los diferentes jugadores pueden actualizar su estado de forma independiente sin conflictos.

Otro patrón es la estrategia «índice más depósito»**: mantener un objeto de índice compartido que apunte a grupos o entradas individuales. Acceda al índice únicamente para buscar la entrada correcta y, a continuación, opere en la propia entrada. Esto reduce la cantidad de superposición entre las transacciones de los usuarios.

Si necesitas un orden estricto (por ejemplo, para las subastas), implementa lacola manualutilizando vectores o mapas dentro del objeto compartido, pero ten en cuenta que cada mutación aún necesita consenso y podría fallar durante el proceso de carga. En esos casos, considera la posibilidad de transferir el orden a la interfaz o de escribir por lotes.

En resumen:

  • Utilice objetos compartidos cuando muchos usuarios independientes deban acceder al estado.
  • Evite colocar todos los campos mutables en un único objeto compartido: divídalos en subobjetos.
  • Usa objetos secundarios dinámicos y compartidos para reducir las tasas de conflicto.
  • Espere ConflictTransactionerrores en caso de alta contención y vuelva a intentarlo en la interfaz.
  • Siempre que sea posible, prefiera las actualizaciones que solo se adjuntan, en lugar de las mutaciones in situ.
0
Comentarios
.
yungrazac.
Aug 22 2025, 10:03

Cuando diseñas con objetos compartidos en Sui Move, básicamente estás eligiendo entrecomodidad para el acceso multiusuarioyriesgo de contención. Dado que Sui utiliza un modelo centrado en objetos y orientado a los recursos, el patrón correcto depende de si tu caso de uso exige un acceso colaborativo o un control aislado. Esta es una forma estructurada de pensarlo:


###Cuándo usar objetos compartidos y objetos de propiedad

*Los objetos propiosson mejores cuando un solo usuario necesita tener el control total de un activo (por ejemplo, las monedas de un monedero, el inventario de un jugador o un NFT único). Las transacciones que los involucren no entrarán en conflicto a menos que se vuelva a utilizar ese mismo objeto. *Los objetos compartidostienen sentido cuando varios usuarios necesitan leer o escribir en el mismo estado (por ejemplo, un registro de gobierno de una DAO, una tabla de clasificación de un campo de juego o una caja fuerte de préstamos). Permiten la accesibilidad global sin necesidad de transferencias autorizadas, pero conllevan desafíos de simultaneidad.


###Gestión de la concurrencia en Sui

ConflictTransactionEl motor de ejecución de Sui serializa automáticamente las transacciones que tocan el mismoobjeto compartido mutable, lo que significa que si dos usuarios intentan actualizar el mismo objeto compartido, uno tendrá éxito y el otro recibirá un error. No es necesario codificar manualmente los bloqueos o las colas; la resolución de conflictos se gestiona en la capa de ejecución. Sin embargo, los conflictos frecuentes pueden reducir el rendimiento, por lo que tu trabajo consiste endiseñar diseños de estados que minimicen las superposiciones.


###Mejores prácticas para evitar conflictos frecuentes

*Estado mutable dividido: en lugar de un único «megaobjeto», divídelo en objetos secundarios más pequeños. Por ejemplo, en una bóveda de préstamos, separa la posición de cada usuario según la posición de un objeto propio o parcialmente compartido, dejando la bóveda en sí misma prácticamente estática. Esto reduce la contención de escritura. *Utilice campos inmutables siempre que sea posible: almacene los metadatos o los datos de referencia en subobjetos inmutables para que las transacciones que solo leen no choquen con las que escriben. *Opere por lotes con cuidado: si el diseño de su contrato requiere varias escrituras en el mismo objeto compartido, considere la posibilidad de agruparlas en un solo bloque de transacciones para evitar múltiples conflictos. *Patrones de fragmentación: en el caso de tablas de clasificación o DAO, fragmenta el estado por grupo, ronda o identificador para que no todas las transacciones lleguen exactamente a la misma ruta de acceso al objeto.


###Dificultades a tener en cuenta

*Objetos compartidos monolíticos: Poner todo en un objeto compartido provoca una gran cantidad de conflictos y conflictos constantes bajo carga. *Uso excesivo de objetos compartidos: si los datos se pueden modelar como propios, prefiera esa ruta, ya que es más económica y tiene menos probabilidades de provocar atascos. *Ignorar los patrones de acceso: si la mayoría de las interacciones se leen con pocas escrituras, diseñe en torno a instantáneas inmutables en lugar de a un estado compartido mutable.


###Ejemplo Práctico

Imagina construir un rastreador de votos de la DAO:

*Patrón incorrecto: un único objeto compartido que almacena cada voto, actualizado por todos los participantes. *Patrón mejor: cada votante crea un objeto propio que Votehace referencia a la propuesta, mientras que el objeto DAO compartido solo agrega los resultados de forma periódica. De esta forma, las votaciones paralelas no chocan.


###Bloqueo de transacciones

Entradas → Los usuarios envían transacciones contra objetos compartidos o propios. Proceso → El tiempo de ejecución de Sui serializa las transacciones en el mismo objeto compartido mutable. Resultado → Las escrituras correctas se confirman, otras cometen errores de conflicto; la división de objetos reduce la posibilidad de conflictos.


0
Comentarios
.
Sato$hii.
Aug 23 2025, 00:02

Great questions—this is exactly the crux of building “high-fanout” apps on Sui. Here’s a practical playbook you can follow.

🧭 When to use a shared object (vs owned)

Use a shared object only when multiple independent parties must mutate the same piece of state and you need one canonical result (e.g., AMM pool reserves, an arena’s match registry, a DAO proposal’s tally). Prefer owned objects when the state is per-user, per-position, or per-item and can evolve independently (inventories, user balances, open positions).

Rule of thumb: put the coordination surface in a shared object, and everything else in owned objects that can run in parallel.


⚙️ What Sui does with concurrent access

  • Any tx that mutates a shared object goes through consensus and is totally ordered. Conflicting writes to the same fields are serialized; others proceed in parallel.
  • You don’t manually lock; you design to avoid hotspots. Conflicts show up as ConflictTransaction when many txs try to bump the same version.

🏗️ High-concurrency design patterns (with Move tips)

1) Root-manager + owned positions

Keep a minimal shared root; put user/position state in owned objects so deposits/claims mostly touch owned data.

module example::vault {
    use sui::tx_context::TxContext;

    struct Vault has key { /* config only; no growing vectors */ }
    struct Position has key { owner: address, /* state */ }

    /// Shared root only needed to mint/close positions or checkpoint.
    public entry fun open_position(v: &mut Vault, ctx: &mut TxContext): Position { /* ... */ }

    /// Hot path touches owned Position only → parallel.
    public entry fun deposit(pos: &mut Position, amount: u64) { /* ... */ }
}

Why it scales: most traffic avoids the shared root altogether.


2) Shard by key (dynamic fields / tables)

Instead of one big shared map, create N shard objects (shared) under a registry and route by hash(key) % N. Each shard is a separate contention domain.

/// registry is shared; it stores IDs of shard objects
struct Registry has key { shards: vector<ID> }

/// choose shard once and keep it stable for that key
fun shard_for(reg: &Registry, key: &vector<u8>): ID { /* hash(key) % len */ }

Tip: don’t update the registry on every user op; mutate only the target shard.


3) Dynamic fields on a shared “anchor”, not growing vectors

Avoid vector.push on a shared object (resizes = conflicts). Use dynamic fields (key → value) so each entry mutates independently.

SharedAnchor
  └─ df[key=user] = tiny record (or pointer to owned object)

Move APIs: sui::dynamic_field::{add, borrow_mut, remove}.


4) Two-phase “ticket” pattern

Have the shared object mint a ticket/capability (owned) that authorizes a later operation done off the hot path.

  1. Light touch on shared root → mint Ticket.
  2. User completes heavy work by presenting the Ticket and mutating only owned/child objects.

Reduces churn on the shared root, and gives you idempotency (ticket can be one-time-use).


5) Append-only events, deferred aggregation

If you’re tempted to keep a total_* counter on the shared root (a hotspot), emit events on each action and aggregate off-chain or in a periodic checkpoint entry that rolls up per-shard totals.


6) Split mutable fields into sub-objects

If one field changes much more frequently (e.g., queue head), peel it into its own child object (owned or shared as needed). Then updates don’t bump the root’s version.


🧪 Avoiding ConflictTransaction in practice

  • Keep the cut set small: Each entry function should touch as few objects as possible.
  • No growing vectors on shared roots; use dynamic fields or sharded children.
  • Stable routing: Deterministic key→shard mapping; never rehash live keys.
  • Idempotency: Use tickets/nonces so retries don’t double-apply.
  • Batch carefully: If you must touch multiple entries atomically, use a PTB—but keep it within a single shard when possible.
  • Backoff & retry: On the client, exponential backoff for known conflict aborts.

🔍 Minimal conflict checklist

  • Shared root is configuration + pointers only.
  • Hot paths mutate owned positions or sharded children.
  • Per-user/per-item state is not inside the root.
  • No vector.push on shared; use dynamic fields.
  • Periodic checkpoint function consolidates, not every tx.

🛡️ Security & correctness notes

  • Gate privileged ops with capabilities (e.g., AdminCap, MintCap); store caps in owned objects, not globals.
  • Validate invariants in shared entry points (sum of shard totals, proposal status transitions, etc.).
  • Emit events for auditability; they are cheap and conflict-free.

Quick templates by use case

  • Game arena: Shared Arena (config/match index) + owned Player / Loadout. Match joins go to Shard[hash(match_id)].
  • DAO voting: Shared Proposal (immutable metadata) + dynamic fields per voter or owned Ballot tickets. Tally via periodic checkpoint.
  • Lending vault: Shared Registry + owned Positions; price/oracle reads are immutable; rebalances via sharded pools.

0
Comentarios
.

Sabes la respuesta?

Inicie sesión y compártalo.

Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.

1166Publicaciones3581Respuestas
Sui.X.Peera.

Gana tu parte de 1000 Sui

Gana puntos de reputación y obtén recompensas por ayudar a crecer a la comunidad de Sui.

Campaña de RecompensasAgosto