Publication
Partagez vos connaissances.
+15
Échec de la transaction Sui : objets réservés pour une autre transaction
Je rencontre un problème persistant JsonRpcError
lorsque j'essaie d'exécuter des transactions sur Sui. L'erreur indique que les objets sont réservés pour une autre transaction, même si j'ai implémenté un traitement séquentiel des transactions avec des retards.
JsonRpcError: Failed to sign transaction by a quorum of validators because one or more of its objects is reserved for another transaction. Other transactions locking these objects:
- AV7coSQHWg5vN3S47xada6UiZGW54xxUNhRv1QUPqWK (stake 33.83)
- 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9
- 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9
- 0x1c20f15cbe780ee7586a2df90c1ab70861ca77a15970bea8702a8cf97bd3eed9
J'ai essayé :
- Exécution séquentielle des transactions (en attente de la fin de la transaction précédente)
- Ajout de délais de 3 secondes entre les transactions
Et j'obtiens toujours la même erreur.
Utilisation de Sui RPC pour la soumission des transactions. Le même identifiant d'objet apparaît plusieurs fois dans la liste de verrouillage. Une erreur se produit même avec un séquençage minutieux des transactions.
- Qu'est-ce qui fait que les objets sont « réservés » pour d'autres transactions ?
- Comment puis-je vérifier correctement si un objet est disponible avant de l'utiliser dans une transaction ?
- Existe-t-il des bonnes pratiques pour gérer les verrous d'objets dans Sui ?
- Cela pourrait-il être lié au calendrier de finalité de la transaction ?
Quelqu'un a-t-il déjà rencontré ce problème ? Toute information sur la gestion appropriée des objets dans les transactions Sui serait grandement appréciée !
- Sui
- Transaction Processing
- Move
Réponses
8Sui utilise uncontrôle de simultanéité optimiste, ce qui signifie que les objets sont verrouillés lorsqu'ils sont utilisés dans une transaction jusqu'à ce que cette transaction soit finalisée ou expire.
Même si vous attendez 3 secondes entre les transactions, si la précédente n'a pas été finalisée, l'objet reste verrouillé. Cela signifie que la transaction est toujours en attente et qu'elle détient un accès exclusif à l'objet.
Comment vérifier si un objet est disponible
Utilisez la méthode Sui RPC :
sui_getObject
Vérifiez la réponse pour "status": "Locked"
ou"owner": "locked"
.
Exemple de demande :
{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getObject",
"params": ["0x...object_id..."]
}
S'il est verrouillé, attendez plus longtemps et réessayez plus tard.
Hé, vous essayez de faire une transaction trop rapidement et les objets ont été verrouillés.
Essayez d'envoyer une transaction avec les mêmes objets à la fois. Si vous envoyez deux transactions, certains validateurs peuvent accepter la première, d'autres pourraient accepter la seconde et vos objets seront bloqués car chaque transaction nécessite 66,7 % de validateurs et vous n'en obtenez peut-être que 50 %.
=> attendez que l'époque soit réinitialisée, c'est bientôt
Pour en savoir plus : https://forums.sui.io/t/beginner-tutorial-error-when-deploying-simple-sui-package/44842
L'erreur signifie que les objets utilisés par votre transaction sont toujours bloqués par des transactions précédentes qui n'ont pas encore été finalisées. Malgré les retards, les objets restent réservés jusqu'à ce que ces transactions soient effectuées en chaîne.
Pour corriger :
- Vérifiez toujours que les transactions précédentes impliquant les objets ont été entièrement finalisées avant de les réutiliser.
- Vérifiez l'état des objets via Sui RPC pour vous assurer qu'ils sont déverrouillés.
- Évitez d'envoyer des transactions parallèles ou rapides sur les mêmes objets.
- Mettez en œuvre de nouvelles tentatives avec des contrôles d'annulation et de finalité au lieu de délais fixes.
Ce verrouillage empêche les mises à jour contradictoires et est normal dans le modèle d'objet de Sui. JsonRpcError
Un séquençage et une confirmation de finalité appropriés sont essentiels pour éviter.
Cette erreur se produit si vous essayez d'exécuter deux transactions simultanément (par exemple, en démarrer une avant la fin de la précédente). Si vous réessayez d'exécuter la transaction de publication, sans exécuter une autre transaction avant ou en même temps, elle devrait réussir. Vous devrez peut-être aussi vous procurer plus d'essence au robinet (ou attendre un jour, le temps que l'époque change, pour que les objets soient déverrouillés)
Lorsque vous exécutez une transaction impliquant des objets appartenant à votre adresse (comme les objets à gaz), les validateurs réservent la dernière version de l'objet à utiliser pour la transaction qu'il signe. Si vous essayez d'exécuter deux transactions simultanément et qu'elles font référence au même objet, elles se feront concurrence pour les signatures des validateurs. Dans le cas heureux, l'une des transactions gagne et s'exécute, tandis que l'autre ne parvient pas à obtenir suffisamment de signatures. Dans le cas malheureux, les deux transactions peuvent ne pas obtenir suffisamment de signatures (si les deux ont obtenu plus d'un tiers des signatures du validateur, aucune ne peut obtenir plus des deux tiers, ce qui est le seuil), c'est ce qu'on appelle une équivoque, et à partir de ce moment, les objets qui ont été entrés dans les deux transactions ne peuvent plus être utilisés pour aucune autre transaction.
À la fin de l'époque (ils durent environ une journée — vous pouvez vérifier la progression jusqu'au prochain changement d'époque sur https://suiexplorer.com), tous les verrous sont libérés, vous pouvez donc réutiliser les objets, mais si vous n'avez pas changé d'époque depuis votre dernière tentative, vous devrez vous procurer plus de gaz.
Sur le réseau Sui, lorsqu'une transaction tente d'accéder à un objet déjà impliqué dans une autre transaction en cours, le réseau renvoie une erreur de réservation. Il s'agit d'une conséquence directe du modèle d'exécution centré sur l'objet de Sui. Toute transaction qui modifie ou consomme un objet doit acquérir un verrou exclusif sur celui-ci. Une fois qu'une telle transaction est soumise, l'objet reste réservé jusqu'à ce que la transaction soit finalisée. Cette réserve empêche d'autres transactions d'interagir prématurément avec le même objet, garantissant ainsi l'atomicité et évitant les conditions de concurrence. Toutefois, si la finalité est retardée en raison de la latence du réseau, du décalage du validateur ou d'un comportement d'exécution inattendu, l'objet peut rester verrouillé plus longtemps que prévu.
Pour déterminer si un objet est dans un état utilisable, vous pouvez utiliser la sui_getObject
méthode via l'interface JSON-RPC de Sui ou la CLI Sui. L'examen du champ propriétaire de l'objet ou des métadonnées du verrouillage de transaction peut permettre de clarifier son statut. Si l'objet semble être en cours d'utilisation ou ne redevient pas propriétaire à l'adresse prévue, il est probablement toujours réservé. Une approche encore plus robuste consiste à interroger le réseau par programmation jusqu'à ce que le verrou de l'objet soit libéré, ce qui est particulièrement utile dans les flux automatisés ou lors de l'orchestration de plusieurs transactions séquentielles.
La manipulation efficace de ces verrous nécessite quelques pratiques clés. Il est essentiel d'éviter de réutiliser des objets mutables entre les transactions jusqu'à ce que les opérations précédentes les impliquant soient entièrement finalisées. Vous devriez envisager d'utiliser des pièces à gaz et des instances d'objets séparées ou rotatives dans la mesure du possible afin de réduire les conflits. En outre, l'intégration d'une logique de nouvelle tentative et de mécanismes d'interrogation intelligents, tels que le report exponentiel, peut minimiser les taux d'échec des transactions. Lorsque les transactions sont orchestrées en parallèle, l'isolation de l'utilisation des objets par processus ou thread améliore considérablement la fiabilité.
Il est important de noter que ce comportement est étroitement lié à la finalité de la transaction. Même si une transaction est acceptée dans le mempool et diffusée, les verrous d'objet associés restent en place jusqu'à ce que le quorum de validation du réseau confirme l'état final de la transaction. Toute tentative de réutilisation préalable de cet objet, indépendamment de l'utilisation de délais arbitraires, entraînera probablement une erreur de réservation.
Pour rationaliser la gestion du verrouillage des objets, voici un utilitaire Bash que vous pouvez utiliser dans votre flux de développement. Il interroge le fullnode et attend que les objets soient déverrouillés avant de procéder à une transaction. Cela garantit que l'objet peut être réutilisé en toute sécurité et limite les défaillances prématurées.
Script Bash : wait-for-unlock.sh
#!/bin/bash
# Sui Fullnode RPC endpoint (adjust as needed)
RPC_ENDPOINT="https://fullnode.testnet.sui.io:443"
# Checks if object is locked
is_locked() {
obj_id=$1
lock_info=$(curl -s -X POST $RPC_ENDPOINT \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "sui_getObject",
"params": ["'"$obj_id"'"],
"id": 1
}')
echo "$lock_info" | grep -q '"owner":{"AddressOwner"' && return 1 || return 0
}
# Waits until each object is no longer locked
wait_for_unlock() {
for obj_id in "$@"; do
echo "Checking object $obj_id..."
while is_locked $obj_id; do
echo "Object $obj_id is still locked. Retrying in 2s..."
sleep 2
done
echo "Object $obj_id is now unlocked."
done
}
# Main handler
main() {
if [ $# -eq 0 ]; then
echo "Usage: $0 <object_id_1> <object_id_2> ..."
exit 1
fi
wait_for_unlock "$@"
echo "All objects unlocked. Safe to proceed with transaction."
}
main "$@"
Pour utiliser le script, il vous suffit de le rendre exécutable et de fournir les ID d'objets que vous souhaitez suivre. Il effectuera un sondage jusqu'à ce que ces objets ne soient plus réservés par les transactions en attente, garantissant ainsi le bon déroulement de votre prochaine transaction.
chmod +x wait-for-unlock.sh
./wait-for-unlock.sh 0xYOUR_OBJECT_ID
Ce type d'automatisation est particulièrement efficace lorsqu'il est intégré à des scripts de déploiement ou à des pipelines CI/CD, fournissant une couche de résilience dans les applications à haut débit ou multi-utilisateurs.
Vous êtes simplement son erreur car vous essayez d'exécuter plus d'une transaction à la fois, probablement en essayant d'envoyer des transactions groupées.
1.Quelles sont les raisons pour lesquelles des objets sont « réservés » pour d'autres transactions ?
Réponse : Cette erreur signifie que votre transaction a essayé d'utiliser un objet (jeton, NFT, etc.), en l'occurrence, votre pièce de gaz (tx.gas
) qui est déjà « verrouillée » par une autre transaction en cours sur le réseau Sui.
Les objets Sui sont à usage unique par transaction, et jusqu'à ce que la transaction qui les bloque soit confirmée ou expire, vous ne pouvez pas les réutiliser immédiatement (par exemple, lorsque vous avez récemment envoyé une transaction, le réseau peut toujours la traiter, la pièce est donc temporairement réservée jusqu'à ce que la transaction soit complètement exécutée).
2.Comment puis-je vérifier correctement si un objet est disponible avant de l'utiliser dans une transaction ?
Réponse : vous attendez que votre première transaction soit terminée ou échoue, cela signifie que le gas coin (tx.gas
) réservé temporairement par le réseau a été libéré lorsque la transaction est terminée ou lorsqu'elle échoue. Vous pouvez vérifier l'état des transactions en utilisant :
bash
sui client tx-status <digest>
3.Existe-t-il des bonnes pratiques pour gérer les verrous d'objets dans Sui ?
Réponse : oui, attendez que la transaction précédente se termine ou échoue (cela peut prendre jusqu'à 20 secondes sur testnet) avant d'exécuter une nouvelle transaction, et vous pouvez toujours confirmer que votre transaction est déjà terminée avant d'exécuter une nouvelle transaction. Vous pouvez également essayer de SPLIT YOUR SUI INTO MULTIPLE GAS COINS
cette façon, même si une pièce est bloquée, vous pouvez en utiliser une autre immédiatement en utilisant
js
const tx = new Transaction();
const [newGas] = tx.splitCoins(tx.gas, [tx.pure.u64(1_000_000_000n)]); // 1 SUI
tx.transferObjects([newGas], tx.pure.address(ownAddress));
Lancez-le une fois et vous aurez plusieurs petites pièces d'essence sur votre compte.
4.Cela pourrait-il être lié au calendrier de finalité de la transaction ?
Réponse : Oui, cela est lié à la finalité de la transaction. Je suppose que les délais supplémentaires de 3 secondes entre les transactions ne suffisent pas pour qu'une transaction soit complètement finalisée. Vous pouvez toujours vérifier l'état de votre transaction en utilisant sui client tx-status <digest>
L'erreur que vous rencontrez est due au mécanisme de verrouillage des transactions de Sui, qui empêche les doubles dépenses et garantit des opérations atomiques. Permettez-moi de vous expliquer exactement ce qui se passe et comment y remédier.
Comprendre le verrouillage des transactions dans SUI Lorsqu'une transaction est soumise au réseau Sui, les validateurs verrouillent les objets détenus référencés pour empêcher les modifications simultanées. Ce mécanisme de verrouillage est fondamental pour éviter les doubles dépenses et garantir l'atomicité des transactions.
Pourquoi les solutions actuelles ne fonctionnent-elles pas Votre approche actuelle qui consiste à ajouter des délais de 3 secondes entre les transactions n'est pas efficace pour les raisons suivantes :
- La finalisation de la transaction peut prendre plus de 3 secondes.
- Plusieurs transactions peuvent être en concurrence pour les mêmes objets.
- Le réseau ne garantit pas la disponibilité immédiate des objets une fois la transaction terminée.
Solution étape par étape
- Mettre en œuvre une vérification appropriée de l'état des transactions ;
async function waitForTransaction(txDigest) {
const MAX_RETRIES = 30;
const RETRY_DELAY_MS = 1000;
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
try {
const result = await suiClient.transactionBlock({
digest: txDigest,
options: { showEffects: true }
});
if (result.status === 'SUCCESS') {
return result;
}
if (attempt === MAX_RETRIES - 1) {
throw new Error(`Transaction ${txDigest} failed`);
}
} catch (error) {
if (error.message.includes('not found')) {
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS));
continue;
}
throw error;
}
}
}
-
Vérifiez la disponibilité des objectifs avant les transactions ;
async function checkObjectAvailability(objectId) {
try {
const result = await suiClient.objects({
ids: [objectId],
options: { showPreviousVersion: true }
});
// Object is available if we can fetch it successfully
return result.details.length > 0;
} catch (error) {
return false;
}
}
-
Mettre en œuvre les nouvelles tentatives de transactions avec Backoff ;
async function executeTransactionWithRetry(txBuilder, signer) {
const MAX_RETRIES = 5;
const INITIAL_BACKOFF_MS = 500;
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
try {
const tx = await txBuilder.sign();
const result = await suiClient.submitTransaction(tx);
// Wait for transaction completion
await waitForTransaction(result.digest);
return result;
} catch (error) {
if (attempt === MAX_RETRIES - 1) {
throw error;
}
const backoffMs = INITIAL_BACKOFF_MS * Math.pow(2, attempt);
console.log(`Attempt ${attempt + 1} failed, retrying in ${backoffMs}ms`);
await new Promise(resolve => setTimeout(resolve, backoffMs));
}
}
}
Meilleures pratiques en matière de gestion des objets
1.Vérifiez toujours le statut des transactions
-
Attendez les certificats d'effets avant de considérer que les transactions sont terminées
-
Vérifiez régulièrement l'état des transactions pendant le traitement
-
Implémenter une gestion des erreurs appropriée pour les objets verrouillés
2.Contrôles de disponibilité des objets
-
Vérifiez la disponibilité des objets avant la création de la transaction
-
Manipulez les cas où les objets sont verrouillés pendant la préparation
-
Envisagez de mettre en œuvre des mécanismes de réservation d'objets dans les contrats intelligents
3.Séquencement des transactions
-
Utilisez les certificats d'effets comme confirmation de l'achèvement
-
Implémenter un backoff exponentiel pour les nouvelles tentatives
-
Maintenez l'ordre des transactions grâce à une gestion appropriée des dépendances
4.Gestion des erreurs
-
Distinguer les erreurs de verrouillage temporaires des défaillances permanentes
-
Implémentez une logique de nouvelle tentative appropriée avec backoff
-
Maintenir l'historique des transactions à des fins de débogage
Considérations supplémentaires
1.Changements d'époque
-
Les transactions peuvent échouer pendant les transitions d'époque
-
Implémentez une logique de nouvelle tentative spécifiquement pour les échecs liés à l'époque
-
Tenez compte du calendrier des transactions par rapport aux limites de l'époque
2.Congestion du réseau
-
Surveillez la charge du réseau pendant les périodes de pointe
-
Ajustez les stratégies de rétrogradation en fonction des conditions du réseau
-
Envisagez de mettre en place une limitation des taux pour les transactions à haute fréquence
En mettant en œuvre ces solutions et en suivant les meilleures pratiques décrites ci-dessus, vous devriez être en mesure de gérer efficacement les scénarios de verrouillage d'objets et d'empêcher l'erreur JSONRPCEerror que vous rencontrez. N'oubliez pas qu'une gestion des erreurs et des mécanismes de nouvelle tentative appropriés sont essentiels pour un traitement fiable des transactions sur la blockchain Sui.
Cette erreur signifie que les objets que vous utilisez sont toujours bloqués par des transactions antérieures qui n'ont pas encore été finalisées. Même en cas de retard, Sui les réserve jusqu'à ce que la chaîne confirme l'achèvement.
Pour résoudre ce problème, assurez-vous que toutes les transactions précédentes utilisant ces objets sont entièrement finalisées avant de les réutiliser. Vous pouvez vérifier leur statut via Sui RPC pour voir s'ils sont déverrouillés. Évitez d'envoyer des transactions multiples ou rapides impliquant les mêmes objets. Au lieu de vous fier à des délais fixes, utilisez les nouvelles tentatives avec annulation et confirmez le caractère définitif avant de réessayer.
Ce verrouillage fait partie de la façon dont Sui garantit la sécurité des mises à jour. Un séquençage et une finalité de vérification appropriés sont donc le moyen d'éviter JSONRPCEerror
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.
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.

- Pourquoi BCS exige-t-il un ordre de champs exact pour la désérialisation alors que les structures Move ont des champs nommés ?55
- « Erreurs de vérification de sources multiples » dans les publications du module Sui Move - Résolution automatique des erreurs45
- Échec de la transaction Sui : objets réservés pour une autre transaction48
- Erreur Sui Move - Impossible de traiter la transaction Aucune pièce de gaz valide n'a été trouvée pour la transaction29
- Comment les contraintes de capacité interagissent-elles avec les champs dynamiques dans des collections hétérogènes ?07