Sui.

Publication

Partagez vos connaissances.

shamueely.
Jul 30, 2025
Questions et Réponses avec des Experts

Modèles de conception et gestion de la simultanéité pour les objets partagés dans Sui Move

J'essaie de trouver le bon modèle architectural lorsque je travaille avec des objets partagés dans Sui Move, en particulier lorsque plusieurs utilisateurs doivent interagir avec eux simultanément (par exemple, dans une arène de jeu, un outil de suivi des votes DAO ou un coffre de prêt).

J'ai lu que les objets partagés peuvent entraîner des problèmes de synchronisation, mais je ne suis toujours pas clair sur :

  • À quel moment dois-je utiliser un sharedobjet exactement owned?
  • Comment Sui gère-t-il les tentatives de transaction simultanées sur le même objet partagé ? Dois-je mettre les objets en file d'attente et les verrouiller manuellement ?
  • Quelle est la meilleure pratique pour concevoir des modules qui prennent en charge une simultanéité élevée tout en évitant les ConflictTransactionerreurs fréquentes ?
  • Dois-je faire quelque chose de spécial (comme diviser des champs mutables en sous-objets) pour réduire les conflits ?
  • Sui
  • Architecture
  • NFT Ecosystem
  • Move
2
13
Partager
Commentaires
.

Réponses

13
theking.
Jul 30 2025, 10:21

Lorsque vous créez une DApp sur Sui où plusieurs utilisateurs doivent interagir avec le même État, comme dans une arène de jeu, un protocole de prêt ou un DAO, vous devez utiliser desobjets partagésau lieu de ceux que vous possédez. Les objets partagés sont accessibles au public et modifiables, ce qui signifie que tout le monde peut y appeler des fonctions de saisie tant qu'ils se trouvent dans le graphe d'objets global. En revanche, les objets possédés sont privés pour un utilisateur et sont idéaux pour les actifs personnels tels que les portefeuilles ou les stocks. Vous devez donc utiliser un objet partagé lorsque les mises à jour d'état doivent être visibles et utilisables par de nombreux utilisateurs à la fois.

Sui gère les transactions simultanées sur des objets partagés via un mécanisme appelévalidation de l'ordre causal, qui vous oblige à fournir explicitement la dernière version connue d'un objet partagé. Si deux utilisateurs tentent de modifier le même objet partagé en même temps avec des versions obsolètes, l'un d'eux y parviendra tandis que les autres échoueront avec une ConflictTransactionerreur. Sui ne met pas en file d'attente ni ne verrouille les objets partagés de manière native. Vous devez donc concevoir vos modules Move de manière à minimiser les écritures qui se chevauchent. L'un des meilleurs moyens de réduire les conflits est deconcevoir en fonction du parallélisme. Par exemple, au lieu de stocker tous les états modifiables dans l'objet partagé racine, vous pouvezdiviser les champs à forte contention en objets enfants distincts. Chacun de ces enfants peut ensuite être écrit indépendamment, ce qui réduit le risque de conflits de transactions.

Une bonne pratique consiste à conserver l'objet partagé principal sous forme de répertoire et à déplacer des états granulaires et fréquemment mis à jour, tels que les scores des joueurs, les votes ou les soldes des prêts, vers des champs dynamiques ou des sous-objets plus petits. De cette façon, les utilisateurs mettent à jour uniquement la partie spécifique dont ils ont besoin, et non l'ensemble de l'objet partagé. Il est également judicieux de séparer les composants lourds en lecture et en écriture. En outre, vous devez créer des flux de transactions clairs et déterministes qui utilisent toujours la version la plus récente des objets partagés et réessayez la logique permettant aux clients de gérer les transactions échouées.

Pour en savoir plus sur la conception d'objets partagés et l'atténuation des conflits, consultez la documentation Sui ici : https://docs.sui.io/concepts/objects#shared-objects.

Si vous gérez quelque chose comme un outil de suivi des votes, voici un exemple de bloc de transactions simplifié pour réduire les conflits :

const tx = new TransactionBlock();
tx.moveCall({
  target: `$ {packageId} ::vote_tracker : :cast_vote`,
 arguments : [
 tx.SharedObject (VoteTrackerID),//référence à un objet partagé
 tx.pure (voterId),//objet possédé ou clé publique
 tx.pure (ProposalId),//données pures
 tx.pure (Choix de vote)
 ]
}) ;
1
Meilleure réponse
Commentaires
.
Benjamin XDV.
Jul 31 2025, 09:52

Dans Sui Move, lesobjets partagés(marqués d'unkey + store) sont essentiels pour l'interaction multi-utilisateurs mais nécessitent une conception minutieuse de la simultanéité. Utilisez-les lorsque l'état doit être globalement modifiable (par exemple, jeux, DAO), tandis que les objets possédés/immuables conviennent à des scénarios mono-utilisateur. Sui sérialise automatiquement les transactions par objet partagé, mais des écritures fréquentes peuvent provoquer des ConflictTransactionerreurs. Réduisez ce problème endivisant les champs activésen objets enfants distincts (par exemple, un par utilisateur) ou en effectuant des mises à jour par lots. Pour un débit élevé, adoptez desmodèles de source d'événements : stockez les actions sous forme d'événements immuables et agrégez l'état périodiquement. Minimisez toujours les champs partagés mutables et préférez les échanges atomiques aux transfer::share_objectmutations directes.

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

Dans Sui Move, la gestion efficace des objets partagés et de la simultanéité nécessite une conception minutieuse pour éviter les conditions de concurrence et les conflits. Voici un aperçu des meilleures pratiques et des modèles architecturaux :

1.Quand utiliser des objets partagés par rapport à des objets possédés :

*Objets partagés : à utiliser lorsque plusieurs utilisateurs doivent interagir simultanément avec le même objet (par exemple, état de jeu partagé, suivi des votes DAO). *Objets possédés : à utiliser lorsque l'objet est spécifique à un seul utilisateur ou à un seul compte, ce qui permet d'éviter l'état partagé et de réduire les problèmes de simultanéité.

###2.Gestion simultanée des transactions dans Sui :

  • Sui gère automatiquement la concurrence en utilisantTransaction Lockspour empêcher les modifications simultanées du même objet.
  • Vousn' avez pasbesoin de mettre en file d'attente ou de verrouiller manuellement les objets partagés, car Sui applique un verrouillage au niveau de l'objet. Cependant,vous risquez d'obtenir des erreurs ConflictTransactionsi plusieurs transactions entrent en conflit sur le même objet.

3.Meilleures pratiques pour une simultanéité élevée :

*Minimiser les contentions : divisez les champs mutables en sous-objets distincts pour permettre des mises à jour parallèles de différentes parties de l'objet. *Évitez les hotspots : répartissez l'état fréquemment modifié sur plusieurs objets (par exemple, au lieu d'avoir un seul registre partagé, divisez-le en plusieurs compartiments ou comptes). *Versioning : utilisez des objets versionnés ou créez de nouveaux objets pour suivre les mises à jour au lieu de muter le même objet à plusieurs reprises.

##4.Gestion des contentions :

  • Envisagez dediviser les champs mutables en objets plus petitspour réduire les conflits. Cela permet de mettre à jour simultanément différentes parties de l'objet, réduisant ainsi les risques de conflits.
  • Utiliseztransactions atomiquespour regrouper les actions associées en une seule, en garantissant la cohérence entre les objets associés.

Exemple :

Si vous avez unoutil de suivi des votespour un DAO :

  • Au lieu de stocker tous les votes dans un seul objet partagé, divisez-les en plusieurs objets (par exemple, un par proposition), ce qui permet des mises à jour parallèles pour chaque proposition tout en réduisant les conflits.

Conclusion :

Pour une simultanéité élevée, minimisez les conflits en distribuant l'état, en utilisant des sous-objets et en tirant parti de la gestion automatique des transactions de Sui. Assurez-vous de bien comprendre vos modèles d'accès et de structurer les objets afin de minimiser les points de conflit.

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

Comprendre les modèles de conception et la gestion de la simultanéité pour les objets partagés dans Sui Move

Lorsque vous traitez desobjets partagésdansSui Move, la gestion de la simultanéité devient essentielle, car plusieurs utilisateurs peuvent avoir besoin d'interagir simultanément avec le même objet. Cela est particulièrement vrai pour des cas d'utilisation tels queles arènes de jeu, lesoutils de suivi des votes DAOet lescoffres-forts de prêt, où une forte simultanéité est attendue. Le réseau Sui fournit certaines fonctionnalités qui aident à gérer la simultanéité, mais il nécessite tout de même une conception minutieuse pour éviter les pièges courants, tels que leserreurs de transaction Conflict.

1.Quand utiliser des objets partagés par rapport à des objets possédés

*Objets possédés :

  • Un objet estpossédés'il est géré par une seule adresse, qui peut le transférer ou le modifier. *Utilisez des objets possédéslorsque vous vous attendez à ce qu'une seule entité contrôle un objet et interagisse avec lui. Par exemple, si vous avez un portefeuille contenant des pièces, chaque portefeuille est propriétaire de ses propres pièces. *Objets partagés :

  • Les objets partagés peuvent être consultés et modifiés par plusieurs adresses simultanément. Sui vous permet de définir des objets commepartagésen les rendant modifiables et en fournissant un accès à plusieurs parties. *Utilisez des objets partagéspour les scénarios dans lesquels plusieurs utilisateurs ou adresses doivent interagir avec le même objet, tels que :

*Suivi des votes DAO : plusieurs utilisateurs peuvent voter pour le même objet. *Coffres-forts de prêt : plusieurs utilisateurs peuvent prêter et emprunter dans le même coffre-fort. *Arènes de jeu : plusieurs utilisateurs interagissent avec l'état du jeu en même temps.

Considération principale : Les objets partagés doivent être utilisés avec précaution, car ils peuvent introduire unecontention, c'est-à-dire des situations dans lesquelles plusieurs transactions tentent d'accéder au même objet et de le modifier en même temps.

###2.Tentatives de simultanéité et de transaction sur des objets partagés

Sui garantit que lestransactionssimultanées sur le mêmeobjet partagésont gérées correctement en appliquant l'isolation transactionnelle. Si plusieurs transactions tentent de muter le même objet partagé en même temps, l'une d'entre elleséchoueren raison d'unecontention.

Lorsqu'une transaction tente de modifier un objet partagé qui est déjà modifié par une autre transaction, Sui renvoie une erreurConflictTransaction. Cependant,Sui gère la majeure partie de la gestion de la simultanéité en interne, et vousn' avez pas besoin de mettre en file d'attente ou de verrouillermanuellement les objets. Vous devez plutôt concevoir votre contrat de manière à minimiser les litiges et à éviter les situations où deux transactions entrent fréquemment en conflit.

3.Meilleures pratiques pour une simultanéité élevée et la réduction des erreurs de transaction conflictuelles

Pourconcevoir des modulescapables de gérer une simultanéité élevée et d'éviter les fréquentes erreursConflictTransaction, suivez ces bonnes pratiques :

a.Minimiser les points de contention :

*Limiter l'accès modifiable : limitez autant que possible le nombre de champs modifiables dans les objets partagés. Chaque champ mutable introduit un point de discorde potentiel. *Utilisez des objets détenus pour des données indépendantes : au lieu de tout partager, stockez les données indépendantes dans des objets détenus. Par exemple, si vous disposez de données spécifiques à l'utilisateur (comme le solde), stockez-les dans un objet qui vous appartient plutôt que dans un objet partagé.

b.Utilisez le modèle de « partitionnement par État » :

  • Divisez votre objet partagé enplusieurs sous-objetspour réduire les conflits. Par exemple, au lieu d'avoir un seul objet partagé qui suit l'intégralité de l'état du jeu, vous pouvez le diviser en plusieurs sous-objets :

  • Un pour l'état de chaquejoueur.

  • Un pour lesparamètres du jeu.

  • Un pourles données du leaderboard.

  • De cette façon, les transactions liées à différentes parties du système peuvent être effectuées simultanément sans se bloquer les unes les autres.

c.Opérations par lots :

  • Lorsque vous travaillez avec des objets partagés, regroupez vos mises à jour afin de réduire le nombre de transactions devant interagir avec l'objet. Cela peut permettre d'éviter de fréquents conflits. *Utilisez des collectionscomme des vecteurs ou des ensembles pour gérer plusieurs mises à jour en une seule transaction.

d.Utilisez les opérations atomiques :

  • Dans la mesure du possible, concevez vos modules de manière à utiliser les opérations atomiques dans la mesure du possible. Par exemple, au lieu d'avoir des transactions distinctes pour vérifier une condition puis mettre à jour un champ, regroupez les vérifications et les mises à jour en une seule opération atomique.

e.Réessayez Logique :

  • Bien que Sui gère les nouvelles tentatives en interne, vous pouvez implémenter une logique de nouvelle tentative au niveau de l'application pour gérer les erreurs de contention occasionnelles. Par exemple, si une ConflictTransactionerreur survient, vous pouvez simplement réessayer la transaction ou la mettre en file d'attente pour une exécution ultérieure.

##4.Réduire les conflits en divisant les champs mutables en sous-objets

Il s'agit d'une pratique hautement recommandée. Lorsqu'il s'agit d'objets partagés, plusil y a de champsmutablesdans un objet partagé, plus il y a de chances que deux transactions tentent de muter le même champ en même temps.

*Exemple 1 : Si vous avez un objet partagé représentant uncoffre de prêt, divisez-le en sous-objets :

  • Un pour lesdépôts : suivez les dépôts individuels séparément.
  • Un pour lesprêts : suivez les prêts individuels séparément.
  • Un pourl'état du coffre : suivez les informations générales sur l'état (par exemple, la valeur totale, le taux d'intérêt).

Ainsi, une transaction qui modifie un sous-objet (par exemple, le sous-objetprêt) n'entre pas en conflit avec une transaction qui en modifie un autre (par exemple, le sous-objetdépôt).

*Exemple 2 : Dans unearène de jeu :

  • Divisez l'état du jeu en sous-objets pour chaque joueur, l'état du jeu et les statistiques de combat. Cela réduit le risque de conflits lorsque différents joueurs interagissent avec leurs états de jeu individuels.

En divisant les champs modifiables ensous-objets, vous réduisez la probabilité que plusieurs utilisateurs tentent de modifier le même objet simultanément.

##5.Autres techniques pour gérer la simultanéité dans Sui

*Verrouillage (verrous explicites) : Bien que Sui ne vous oblige pas à gérer manuellement les verrous, dans certains cas, vous souhaiterez peut-être appliquer desverrouillageà l'aide d'objets de verrouillage(objets séparés qui garantissent qu'une seule transaction peut accéder à une ressource particulière à la fois).

*Isolation temporale : Si vos objets ne changent que de temps en temps, pensez à introduire uneisolation temporelle. Par exemple, si vous gérez un coffre-fort ou un système de vote, définissez despériodes de voteou desfenêtres de transactionpour limiter les interactions pendant certaines périodes.

##6.Exemple de code pour gérer la simultanéité avec des sous-objets

Voici un exemple illustrant comment réduire les conflits en divisant uncoffre de prêten sous-objets plus petits :

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

Résumé

*Utilisez des objets partagéslorsque plusieurs utilisateurs doivent interagir simultanément avec le même objet (par exemple, votes DAO, état du jeu, coffres de prêt). *Minimisez les contentionsen divisant les grands objets partagés en sous-objets plus petits et en réduisant le nombre de champs modifiables. *Évitez les erreurs ConflictTransactionfréquentes en suivant les meilleures pratiques telles que le partitionnement d'état, les opérations par lots et l'utilisation d'opérations atomiques.

  • LaLogique des réessayeset lecontrôle de simultanéité optimistepeuvent être utilisés pour gérer les conflits avec élégance. Lemodèle transactionnelet larésolution des conflitsde * Sui sont robustes, mais laconceptionde vos objets partagés est essentielle pour garantir un accès simultané efficace.

En suivant ces principes de conception, vous serez en mesure de gérer une simultanéité élevée dans vos modules basés sur Move tout en évitant les pièges habituels tels que lesconflitset leserreurs de transaction.

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

Utilisezobjets partagéspour accéder à plusieurs rédacteurs (par exemple, jeux, DAO). Principaux modèles :

1.Détenu ou partagé

  • Possédé : rédacteur unique (plus rapide).
  • Partagé : écritures simultanées (gaz plus élevé).

2.Gestion de la simultanité

  • Sui séquence automatiquement les TX des objets partagés (pas de verrouillage manuel).
  • Divisez les données sensibles en sous-objets (par exemple, un par joueur) pour réduire les conflits.

3.Atténuation des conflits

  • Isolez les zones à fort trafic (par exempleTable<ID, PlayerData>).
  • Utilisez des PTB pour les opérations atomiques multi-objets.

Surveillez :ConflictTransaction: Données fractionnées ou mises à jour par lots.

  • Des pics de gaz sur les objets partagés.
  • (L'environnement d'exécution de Sui gère les conflits : optimisez via le partitionnement des données. ) *
6
Commentaires
.
Alya.
Alya-14
Jul 30 2025, 17:38

Utilisezobjets partagés(transfer::share_object) lorsque plusieurs utilisateurs doivent muter le même objet (par exemple, coffre, DAO, état du jeu). Utilisezpossédédans le cas contraire.

TransactionLockConflictSui gère la simultanéité viaNarwhal & Tusk : les transactions conflictuelles sur un objet partagé sont sérialisées : une seule réussit par tour ; les autres échouent avec. Aucun verrouillage manuel n'est nécessaire, maisvous devez concevoir pour les récupérations.

Meilleures pratiques :

  • Minimisez l'état modifiable des objets partagés ; divisez les hotspots en sous-objets distincts (par exemple, des partages de coffres-forts par utilisateur).
  • Utilisez VecMapou Tablepour des mappages évolutifs.
  • Évitez les longs calculs dans les fonctions partagées.
  • Émet des événements au lieu de stocker des états éphémères.
  • Pour les systèmes à forte contention, utilisez des schémasbatchingoucommit-reveal pour réduire les conflits.

Les objets partagés sont accessibles dans le monde entier mais génèrent plus de gaz et de conflits. Optimisez l'idempotence et réessayez la logique dans le code client.

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

Pour lesobjets partagésdans Sui Move, utilisez ces modèles pour gérer la simultanéité :

####1. Partagé ou possédé ? -Objet partagé (key + store) :

  • À utiliser pourétat global(par exemple, jeux, DAO).
  • Permet lesécritures parallèles(contrairement aux TX sérialisés d'EVM).
 struct GameArena has key, store { id: UID, players: vector<address> }

-Objet possédé :

  • À utiliser pourles données spécifiques à l'utilisateur(par exemple, les NFT, les portefeuilles).
 struct PlayerInventory has key { id: UID, items: vector<Item> }

####2. Gestion de la simultanité -Pas de verrouillage manuel : Suirésout les conflits automatiquement(contrairement à EVM). -Diviser la contention : divisez les objets partagés ensous-objets plus petits(par exemple, par joueur ou par fragment).

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

####3. Réduire les ConflictTransactionerreurs -Isoler les écritures : mettez à jourles différents champsdans des TXs séparés. -À utiliser &mutjudicieux : évitez les mutations générales.

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

####4. Meilleures pratiques -Mises à jour par lots : regroupez les opérations non conflictuelles (par exemple, les votes dans un DAO). -Event-Driven : émettez des événements au lieu de modifier l'état lorsque cela est possible.

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

Utilisez des objets partagés pour accéder à plusieurs rédacteurs (par exemple, des jeux, des DAO). Principaux modèles :

Détenu ou partagé

Propriétaire : rédacteur unique (plus rapide). Partagé : écritures simultanées (gaz plus élevé). Gestion de la simultanéité

Sui séquence automatiquement les TX des objets partagés (pas de verrouillage manuel). Divisez les données sensibles en sous-objets (par exemple, un par joueur) pour réduire les conflits. Atténuer les conflits

Isolez les champs à fort trafic (par exemple, Tableau<ID, PlayerData>). Utilisez des PTB pour les opérations atomiques multi-objets. Surveillez :

ConflictTransaction : données fractionnées ou mises à jour par lots. Des pics de gaz sur des objets partagés. (L'environnement d'exécution de Sui gère les conflits : optimisez via le partitionnement des données.)

3
Commentaires
.
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
Commentaires
.
Bekky.
Bekky1762
Jul 31 2025, 12:26

Objets partagés et objets possédés : quand utiliser chacun

Utilisez des objets partagés lorsque :

  • Plusieurs utilisateurs doivent muter le même état
  • L'objet représente une ressource publique (comme une arène de jeu ou un DAO)
  • Vous avez besoin de modèles d'accès sans autorisation

Utilisez les objets que vous possédez lorsque :

  • Une seule adresse doit contrôler l'objet
  • Vous souhaitez tirer pleinement parti de l'exécution parallèle de Sui
  • Les objets représentent des actifs spécifiques à l'utilisateur

Stratégies de gestion de la simultanéité

1. Modèle de sous-objet (réduire la contention)

Divisez les champs fréquemment mis à jour en objets distincts :

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. Mises à jour par lots avec vecteurs/tableaux

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. Traitement basé sur Epoch

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

Techniques d'évitement des conflits

1.Partitionnement au niveau du champ :

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

2.File d'attente d'exécution différée :

  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.Concurrence optimiste avec la gestion des versions :

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

Exemples pratiques de CLI

Vérification des dépendances des objets avant la soumission :

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

Simulation de scénarios de contention :

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

Résumé des meilleures pratiques

1.Minimiser les mutations d'objets partagés : conception pour les écritures peu fréquentes sur des objets partagés 2.Utiliser des objets enfants : état de décomposition pour réduire les points de contention 3.Opérations par lots : Regroupez les modifications liées en transactions uniques 4.Envisagez des modèles hybrides : combinez des objets que vous possédez avec une coordination partagée occasionnelle 5. sui-tool replaySurveiller les hotspots : à utiliser pour analyser les conflits

N'oubliez pas que le moteur d'exécution de Sui gère automatiquement une certaine concurrence via son modèle objet, mais que vous devez tout de même concevoir vos structures de données pour minimiser les conflits logiques.

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

Vous devez utiliser unobjet partagédans Sui Move lorsque plusieurs utilisateurs doivent interagir avec le même élément d'état et que ces utilisateurs ne sont pas tous sous le même propriétaire. Les exemples incluent une arène de jeu ouverte à tous les joueurs, un outil de suivi des votes DAO qui collecte les votes à différentes adresses ou un pool de prêt dans lequel tout le monde peut effectuer des dépôts. Les objets partagés sont accessibles dans le monde entier et peuvent être mis à jour par consensus, contrairement auxobjets possédés, qui sont liés à une adresse unique et modifiés sans consensus total.

Sui gère la simultanéité sur les objets partagés en exigeant un consensus total pour toute transaction qui les modifie. ConflictTransactionLorsque deux utilisateurs tentent de muter le même objet partagé à peu près en même temps, une seule transaction aboutit ; les autres sont rejetées avec une erreur. Cela rend les objets partagés puissants, mais crée également des problèmes de contention lorsqu'ils ne sont pas conçus avec soin.

Pour prendre en charge la haute simultanéité sans rencontrer d'ConflictTransactionerreurs fréquentes, vous devez utiliserdes modèles de conception qui isolent l'état mutable. Au lieu de stocker toutes les données modifiables dans un seul objet partagé, divisez-le en plusieurs objets enfants, chacun ayant sa propre propriété ou son propre statut partagé. Par exemple, dans une arène de jeu :

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

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

Faites en sorte qu'il soit Arenapartagé, mais donnez à chacun PlayerStateson propre objet partagé. De cette façon, les différents joueurs peuvent mettre à jour leur état indépendamment sans entrer en conflit.

Un autre modèle est la stratégie** « index + compartiment »** : conservez un objet d'index partagé qui pointe vers des compartiments ou des entrées individuels. Accédez à l'index uniquement pour récupérer la bonne entrée, puis opérez sur l'entrée elle-même. Cela réduit le chevauchement entre les transactions des utilisateurs.

Si vous avez besoin d'un ordre strict (par exemple, pour les enchères), implémentez lamise en file d'attente manuelleà l'aide de vecteurs ou de cartes à l'intérieur de l'objet partagé, mais sachez que chaque mutation nécessite toujours un consensus et peut échouer en cas de chargement. Dans ces cas, envisagez de décharger la commande vers le frontend ou de regrouper les écritures par lots.

En résumé :

  • Utilisez des objets partagés lorsque de nombreux utilisateurs indépendants doivent accéder à l'état.
  • Évitez de placer tous les champs modifiables dans un seul objet partagé, divisez-les en sous-objets.
  • Utilisez des objets enfants partagés et dynamiques pour réduire les taux de conflit.
  • Attendez-vous à ConflictTransactiondes erreurs en cas de forte contention et réessayez sur le frontend.
  • Préférez les mises à jour uniquement en ajout dans la mesure du possible, plutôt qu'une mutation sur place.
0
Commentaires
.
yungrazac.
Aug 22 2025, 10:03

Lorsque vous concevez avec des objets partagés dans Sui Move, vous devez essentiellement choisir entrela commodité d'un accès multi-utilisateuret lerisque de contention. Étant donné que Sui utilise un modèle centré sur les objets et orienté vers les ressources, le bon modèle dépend de la question de savoir si votre cas d'utilisation nécessite un accès collaboratif ou un contrôle isolé. Voici une façon structurée d'y penser :


###Quand utiliser des objets partagés par rapport à des objets possédés

  • Lesobjets possédéssont préférables lorsqu'un seul utilisateur a besoin du contrôle total d'un actif (par exemple, les pièces d'un portefeuille, l'inventaire d'un joueur ou un NFT unique). Les transactions les impliquant n'entreront pas en conflit à moins que le même objet ne soit réutilisé. *Les objets partagésont du sens lorsque plusieurs utilisateurs doivent lire ou écrire dans le même état (par exemple, un enregistrement de gouvernance DAO, un classement d'une arène de jeu, un coffre de prêt). Ils permettent un accès mondial sans avoir besoin de transferts autorisés, mais ils présentent des problèmes de simultanéité.

###Gestion de la simultanéité dans Sui

ConflictTransactionLe runtime de Sui sérialise automatiquement les transactions qui touchent le mêmeobjet partagé mutable, ce qui signifie que si deux utilisateurs essaient de mettre à jour le même objet partagé, l'un réussira et l'autre obtiendra une erreur. Il n'est pas nécessaire de coder manuellement les verrous ou les files d'attente : la résolution des conflits est gérée au niveau de la couche d'exécution. Cependant, des conflits fréquents peuvent dégrader le débit. Votre travail consiste donc àconcevoir des dispositions d'état qui minimisent les chevauchements.


###Meilleures pratiques pour éviter les conflits fréquents

*État mutable divisé : au lieu d'un seul « méga-objet », décomposez-le en objets enfants plus petits. Par exemple, dans un coffre de prêt, séparez la position de chaque utilisateur en fonction de son propre objet ou d'un objet partiellement partagé, laissant le coffre-fort lui-même pratiquement statique. Cela réduit les conflits d'écriture. *Utilisez des champs immuables dans la mesure du possible : stockez les métadonnées ou les données de référence dans des sous-objets immuables afin que les transactions qui ne font que lire n'entrent pas en collision avec celles qui écrivent. *Opérations par lots soigneusement : Si la conception de votre contrat nécessite plusieurs écritures sur le même objet partagé, pensez à les regrouper dans un seul bloc de transactions pour éviter de multiples conflits. *Modèles de partition : pour des éléments tels que les classements ou les DAO, répartissez l'état des fragments par groupe, tour ou identifiant afin que toutes les transactions n'atteignent pas exactement le même chemin d'objet.


###Les pièges à surveiller

*Objets partagés monolithiques : Tout placer dans un seul objet partagé entraîne de fortes tensions et des conflits constants lors de la charge. *Utilisation excessive d'objets partagés : si les données peuvent être modélisées comme si elles étaient détenues, privilégiez cette voie, car elle est moins coûteuse et moins susceptible de provoquer un engorgement. *Ignorer les modèles d'accès : si la plupart des interactions sont lues avec peu d'écritures, concevez autour d'instantanés immuables plutôt que d'un état partagé mutable.


###Exemple pratique

Imaginez créer un outil de suivi des votes DAO :

*Mauvais modèle : un seul objet partagé stockant chaque vote, mis à jour par tous les participants. *Meilleur modèle : chaque électeur crée un Voteobjet appartenant faisant référence à la proposition, tandis que l'objet DAO partagé ne fait qu'agréger les résultats périodiquement. De cette façon, le vote parallèle n'entre pas en conflit.


###Bloc de transaction

Entrées → Les utilisateurs soumettent des transactions pour des objets partagés ou détenus. Processus → Le runtime de Sui sérialise les transactions sur le même objet partagé mutable. Résultat → Les écritures réussies sont validées, d'autres génèrent des erreurs de conflit ; le fractionnement des objets réduit les risques de conflits.


0
Commentaires
.
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
Commentaires
.

Connaissez-vous la réponse ?

Veuillez vous connecter et la partager.

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

1166Publications3581Réponses
Sui.X.Peera.

Gagne ta part de 1000 Sui

Gagne des points de réputation et obtiens des récompenses pour avoir aidé la communauté Sui à se développer.

Campagne de RécompensesAoût