Beitrag
Teile dein Wissen.
+15
Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert
JsonRpcError
Beim Versuch, Transaktionen auf Sui auszuführen, stoße ich auf eine persistente Störung. Der Fehler weist darauf hin, dass Objekte für eine andere Transaktion reserviert sind, obwohl ich eine sequentielle Transaktionsverarbeitung mit Verzögerungen implementiert habe.
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
Ich habe versucht:
- Sequentielle Transaktionsausführung (Warten auf den Abschluss der vorherigen Transaktion)
- Es wurden Verzögerungen von 3 Sekunden zwischen Transaktionen hinzugefügt
Und immer noch der gleiche Fehler.
Verwendung von Sui RPC für die Übermittlung von Transaktionen. Dieselbe Objekt-ID erscheint mehrfach in der Sperrliste. Selbst bei sorgfältiger Transaktionssequenzierung tritt ein Fehler auf.
- Was bewirkt, dass Objekte für andere Transaktionen „reserviert“ werden?
- Wie kann ich richtig überprüfen, ob ein Objekt verfügbar ist, bevor ich es in einer Transaktion verwende?
- Gibt es bewährte Methoden für den Umgang mit Objektsperren in Sui?
- Könnte das mit dem Zeitpunkt der Finalität der Transaktion zusammenhängen?
Ist jemand schon einmal auf dieses Problem gestoßen? Alle Einblicke in das richtige Objektmanagement bei Sui-Transaktionen wären sehr willkommen!
- Sui
- Transaction Processing
- Move
Antworten
8Sui verwendetOptimistic Concurrency Control, was bedeutet, dass Objekte gesperrt werden, wenn sie in einer Transaktion verwendet werden, bis diese Transaktion abgeschlossen ist oder abläuft.
Selbst wenn Sie zwischen den Transaktionen 3 Sekunden warten, bleibt das Objekt gesperrt, wenn die vorherige noch nicht abgeschlossen wurde. Das bedeutet, dass die Transaktion immer noch aussteht und exklusiven Zugriff auf das Objekt hat.
So überprüfen Sie, ob ein Objekt verfügbar ist
Verwenden Sie die Sui RPC-Methode:
sui_getObject
Überprüfen Sie die Antwort auf "status": "Locked"
oder"owner": "locked"
.
Beispiel für eine Anfrage:
{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getObject",
"params": ["0x...object_id..."]
}
Wenn gesperrt, warten Sie einfach länger und versuchen Sie es später erneut.
Hey, du versuchst zu schnell eine Transaktion durchzuführen und die Objekte wurden gesperrt.
Versuchen Sie, jeweils eine Transaktion mit denselben Objekten zu senden. Wenn Sie zwei Transaktionen senden, akzeptieren einige Validatoren möglicherweise die erste, einige akzeptieren die zweite und Ihre Objekte werden gesperrt, da jede Transaktion 66,7% der Validatoren benötigt und Sie möglicherweise nur 50% erhalten.
=> warte einfach auf den Epochen-Reset, es ist bald
Überprüfe mehr: https://forums.sui.io/t/beginner-tutorial-error-when-deploying-simple-sui-package/44842
Der Fehler bedeutet, dass die Objekte, die Ihre Transaktion verwendet, immer noch durch frühere Transaktionen gesperrt sind, die noch nicht abgeschlossen sind. Selbst bei Verzögerungen bleiben Objekte reserviert, bis diese Transaktionen in der Kette abgeschlossen sind.
Um das Problem zu beheben:
- Vergewissern Sie sich immer, dass frühere Transaktionen mit den Objekten vollständig abgeschlossen wurden, bevor Sie sie erneut verwenden.
- Überprüfen Sie den Objektstatus über Sui RPC, um sicherzustellen, dass sie entsperrt sind.
- Vermeiden Sie es, parallele oder schnelle Transaktionen auf denselben Objekten zu senden.
- Implementieren Sie Wiederholungsversuche mit Backoff- und Finalitätsprüfungen statt fester Verzögerungen.
Diese Sperrung verhindert widersprüchliche Aktualisierungen und ist im Objektmodell von Sui normal. JsonRpcError
Eine korrekte Sequenzierung und Bestätigung der Endgültigkeit sind der Schlüssel zur Vermeidung.
Dieser Fehler tritt auf, wenn Sie versuchen, zwei Transaktionen gleichzeitig auszuführen (z. B. eine starten, bevor die vorherige abgeschlossen ist). Wenn Sie erneut versuchen, die Veröffentlichungstransaktion auszuführen, ohne vorher oder gleichzeitig eine weitere Transaktion auszuführen, sollte sie erfolgreich sein. Möglicherweise müssen Sie auch mehr Gas aus dem Wasserhahn holen (oder einen Tag warten, bis sich die Epoche überschlägt — bis sich die Objekte entriegeln)
Wenn Sie eine Transaktion ausführen, die Objekte beinhaltet, die Ihrer Adresse gehören (wie die Gasobjekte), reservieren Validatoren die neueste Version des Objekts für die Transaktion, die gerade signiert wird. Wenn Sie versuchen, zwei Transaktionen gleichzeitig auszuführen und sie sich auf dasselbe Objekt beziehen, konkurrieren sie miteinander um Signaturen von Validatoren. Im glücklichen Fall gewinnt eine der Transaktionen und wird ausgeführt, und die andere Transaktion erhält nicht genügend Signaturen. Im unglücklichen Fall können beide Transaktionen nicht genügend Signaturen erhalten (wenn beide mehr als ein Drittel der Signaturen des Validators erhalten haben, kann keine der beiden Transaktionen mehr als zwei Drittel erreichen, was der Schwellenwert ist). Dies wird als Äquivokation bezeichnet, und ab diesem Zeitpunkt können die Objekte, die in beide Transaktionen eingegeben wurden, für keine anderen Transaktionen verwendet werden.
Am Ende der Epoche (sie dauern ungefähr einen Tag — du kannst den Fortschritt bis zum nächsten Epochenwechsel auf https://suiexplorer.com überprüfen) werden alle Sperren aufgehoben, sodass du die Objekte wieder verwenden kannst, aber wenn du seit deinem letzten Versuch keinen Epochenwechsel hattest, musst du mehr Gas erwerben.
Wenn im Sui-Netzwerk eine Transaktion versucht, auf ein Objekt zuzugreifen, das bereits an einer anderen laufenden Transaktion beteiligt ist, gibt das Netzwerk einen Reservierungsfehler zurück. Dies ist eine direkte Folge des objektzentrierten Ausführungsmodells von Sui. Jede Transaktion, die ein Objekt verändert oder verbraucht, muss eine exklusive Sperre für dieses Objekt erhalten. Sobald eine solche Transaktion eingereicht wurde, bleibt das Objekt reserviert, bis die Transaktion abgeschlossen ist. Dieser Vorbehalt verhindert, dass andere Transaktionen vorzeitig mit demselben Objekt interagieren, wodurch Atomarität gewährleistet und Wettlaufbedingungen vermieden werden. Wenn sich die Finalisierung jedoch aufgrund von Netzwerklatenz, Verzögerung bei der Validierung oder unerwartetem Ausführungsverhalten verzögert, kann das Objekt länger als erwartet gesperrt bleiben.
Um festzustellen, ob sich ein Objekt in einem verwendbaren Zustand befindet, können Sie die sui_getObject
Methode über die JSON-RPC-Schnittstelle von Sui oder die Sui-CLI verwenden. Wenn Sie das Eigentümerfeld oder die Metadaten der Transaktionssperre des Objekts untersuchen, können Sie Klarheit über seinen Status gewinnen. Wenn das Objekt in Gebrauch zu sein scheint oder das Eigentum nicht an die erwartete Adresse zurückgibt, ist es wahrscheinlich immer noch reserviert. Ein noch robusterer Ansatz besteht darin, das Netzwerk programmgesteuert abzufragen, bis die Objektsperre aufgehoben wird. Dies ist besonders hilfreich bei automatisierten Abläufen oder bei der Orchestrierung mehrerer sequenzieller Transaktionen.
Der effektive Umgang mit diesen Sperren erfordert einige wichtige Verfahren. Es ist wichtig zu vermeiden, veränderbare Objekte transaktionsübergreifend wiederzuverwenden, bis die vorherigen Operationen, an denen sie beteiligt waren, vollständig abgeschlossen sind. Sie sollten erwägen, wo immer möglich separate oder rotierende Gasmünzen und Objektinstanzen zu verwenden, um Konflikte zu vermeiden. Darüber hinaus können durch die Integration von Wiederholungslogik und intelligenten Abfragemechanismen — wie exponentielles Backoff — die Ausfallraten von Transaktionen minimiert werden. Wenn Transaktionen parallel orchestriert werden, verbessert die Isolierung der Objektnutzung pro Prozess oder Thread die Zuverlässigkeit erheblich.
Es ist wichtig zu beachten, dass dieses Verhalten eng mit der Endgültigkeit der Transaktion verknüpft ist. Selbst wenn eine Transaktion in den Mempool aufgenommen und übertragen wird, bleiben die zugehörigen Objektsperren bestehen, bis das Validator-Quorum des Netzwerks den endgültigen Status der Transaktion bestätigt. Jeder Versuch, dieses Objekt vorher wiederzuverwenden, führt wahrscheinlich zu einem Reservierungsfehler, unabhängig von der Verwendung willkürlicher zeitabhängiger Verzögerungen.
Um die Behandlung von Objektsperren zu optimieren, finden Sie hier ein Bash-Hilfsprogramm, das Sie in Ihrem Entwicklungsworkflow verwenden können. Es fragt den Fullnode ab und wartet, bis die Objekte entsperrt sind, bevor es mit einer Transaktion fortfährt. Dadurch wird sichergestellt, dass das Objekt sicher wiederverwendet werden kann, und ein vorzeitiger Ausfall wird vermieden.
Bash-Skript: 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 "$@"
Um das Skript zu verwenden, machen Sie es einfach ausführbar und geben Sie die Objekt-IDs an, die Sie verfolgen möchten. Es fragt ab, bis diese Objekte nicht mehr für ausstehende Transaktionen reserviert sind, um sicherzustellen, dass Ihre nächste Transaktion reibungslos abläuft.
chmod +x wait-for-unlock.sh
./wait-for-unlock.sh 0xYOUR_OBJECT_ID
Diese Art der Automatisierung ist besonders effektiv, wenn sie in Bereitstellungsskripts oder CI/CD-Pipelines integriert wird. Sie bietet eine Ebene der Widerstandsfähigkeit in Hochdurchsatz- oder Mehrbenutzeranwendungen.
Sie sind einfach sein Fehler, weil Sie versuchen, mehr als eine Transaktion gleichzeitig auszuführen, wahrscheinlich versuchen, gebündelte Transaktionen zu senden.
1.Was bewirkt, dass Objekte für andere Transaktionen „reserviert“ werden?
Antwort: Dieser Fehler bedeutet, dass Ihre Transaktion versucht hat, ein Objekt (Token, NFTs usw.) zu verwenden, in diesem Fall Ihre Gasmünze (tx.gas
), die bereits durch eine andere Transaktion während des Fluges im Sui-Netzwerk „gesperrt“ ist.
Sui-Objekte können pro Transaktion einmalig verwendet werden, und bis die Transaktion, die sie sperrt, bestätigt ist oder abläuft, können Sie sie nicht sofort wieder verwenden (d. h. wenn Sie kürzlich eine Transaktion gesendet haben, verarbeitet das Netzwerk sie möglicherweise immer noch, sodass die Münze vorübergehend reserviert ist, bis die Transaktion vollständig ausgeführt ist).
2.Wie kann ich richtig überprüfen, ob ein Objekt verfügbar ist, bevor ich es in einer Transaktion verwende?
Antwort: Sie warten, bis Ihre erste Transaktion abgeschlossen ist oder fehlgeschlagen ist. Dies bedeutet, dass die tx.gas
vom Netzwerk vorübergehend reservierte Gasmünze () freigegeben wurde, wenn die Transaktion abgeschlossen ist oder wenn sie fehlschlägt. Sie können den Transaktionsstatus überprüfen, indem Sie Folgendes verwenden:
bash
sui client tx-status <digest>
3.Gibt es bewährte Methoden für den Umgang mit Objektsperren in Sui?
Antwort: Ja, die gibt es. Warten Sie, bis die frühere Transaktion abgeschlossen ist oder fehlschlägt (kann im Testnetz bis zu 20 Sekunden dauern), bevor Sie eine neue Transaktion ausführen. Sie können jederzeit bestätigen, dass Ihre Transaktion bereits abgeschlossen ist, bevor Sie eine neue Transaktion ausführen. Du kannst es auch versuchen SPLIT YOUR SUI INTO MULTIPLE GAS COINS
Auf diese Weise kannst du, selbst wenn eine Münze gesperrt ist, sofort eine andere verwenden, indem du
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));
Wenn Sie es einmal ausführen, haben Sie mehrere kleine Gasmünzen auf Ihrem Konto.
4.Könnte das mit dem Zeitpunkt der Finalität der Transaktion zusammenhängen?
Antwort:Ja, das hängt mit der Finalität der Transaktion zusammen. Ich schätze, die zusätzlichen Verzögerungen von 3 Sekunden zwischen den Transaktionen reichen nicht aus, um eine Transaktion vollständig abzuschließen. Sie können Ihren Transaktionsstatus jederzeit überprüfen mit sui client tx-status <digest>
Der Fehler, auf den Sie stoßen, ist auf den Transaktionssperrmechanismus von Sui zurückzuführen, der doppelte Ausgaben verhindert und atomare Operationen gewährleistet. Lassen Sie mich genau erklären, was passiert und wie Sie es beheben können.
Grundlegendes zum Sperren von Transaktionen in Sui Wenn eine Transaktion an das Sui-Netzwerk übermittelt wird, sperren Validatoren die zugehörigen Objekte, auf die verwiesen wird, um gleichzeitige Änderungen zu verhindern. Dieser Sperrmechanismus ist von grundlegender Bedeutung, um doppelte Ausgaben zu verhindern und die Atomarität von Transaktionen sicherzustellen.
Warum aktuelle Lösungen nicht funktionieren Ihr derzeitiger Ansatz, Verzögerungen von 3 Sekunden zwischen Transaktionen hinzuzufügen, ist aus folgenden Gründen nicht effektiv:
- Die Finalisierung der Transaktion kann länger als 3 Sekunden dauern.
- Möglicherweise konkurrieren mehrere Transaktionen um dieselben Objekte.
- Das Netzwerk garantiert keine sofortige Verfügbarkeit der Objekte nach Abschluss der Transaktion.
Schrittweise Lösung
- Implementieren Sie eine ordnungsgemäße Überprüfung des Transaktionsstatus;
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;
}
}
}
-
Überprüfen Sie die objektive Verfügbarkeit vor Transaktionen;
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;
}
}
-
Implementieren Sie Transaktionswiederholungen mit 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));
}
}
}
Best Practices für das Objektmanagement
1.Überprüfen Sie immer den Transaktionsstatus
-
Warten Sie auf die Effektzertifikate, bevor Sie die Transaktionen als abgeschlossen betrachten
-
Überprüfen Sie den Transaktionsstatus regelmäßig während der Bearbeitung
-
Implementieren Sie eine korrekte Fehlerbehandlung für gesperrte Objekte
2.Prüfungen der Objektverfügbarkeit
-
Überprüfen Sie die Objektverfügbarkeit vor der Transaktionserstellung
-
Behandeln Sie Fälle, in denen Objekte während der Vorbereitung gesperrt werden
-
Erwägen Sie die Implementierung von Objektreservierungsmechanismen in intelligenten Verträgen
3.Transaktionssequenzierung
-
Verwenden Sie Effektzertifikate als Bestätigung des Abschlusses
-
Implementieren Sie einen exponentiellen Backoff für Wiederholungsversuche
-
Halten Sie die Reihenfolge der Transaktionen durch ein ordnungsgemäßes Abhängigkeitsmanagement aufrecht
4.Fehlerbehandlung
-
Unterscheiden Sie zwischen temporären Sperrfehlern und dauerhaften Ausfällen
-
Implementieren Sie eine korrekte Wiederholungslogik mit Backoff
-
Pflegen Sie den Transaktionsverlauf zu Debugging-Zwecken
Zusätzliche Überlegungen
1.Epochenänderungen
-
Transaktionen können bei Epochenübergängen fehlschlagen
-
Implementieren Sie eine Wiederholungslogik speziell für epochenbezogene Fehler
-
Berücksichtigen Sie den Transaktionszeitpunkt im Verhältnis zu den Epochengrenzen
2.Netzwerküberlastung
-
Überwachen Sie die Netzwerklast in Spitzenzeiten
-
Passen Sie Backoff-Strategien an die Netzwerkbedingungen an
-
Erwägen Sie die Einführung einer Ratenbegrenzung für hochfrequente Transaktionen
Wenn Sie diese Lösungen implementieren und die oben beschriebenen Best Practices befolgen, sollten Sie in der Lage sein, Szenarien zum Sperren von Objekten effektiv zu handhaben und den JSONRPCError zu verhindern, auf den Sie stoßen. Denken Sie daran, dass die richtige Fehlerbehandlung und Wiederholungsmechanismen für eine zuverlässige Transaktionsverarbeitung in der Sui-Blockchain unerlässlich sind.
Dieser Fehler bedeutet, dass die von Ihnen verwendeten Objekte immer noch durch frühere Transaktionen gesperrt sind, die noch nicht abgeschlossen wurden. Selbst bei Verzögerungen behält Sui sie für sich, bis die Kette den Abschluss bestätigt.
Um das Problem zu beheben, stellen Sie sicher, dass alle vorherigen Transaktionen, bei denen diese Objekte verwendet wurden, vollständig abgeschlossen sind, bevor Sie sie wiederverwenden. Du kannst ihren Status über Sui RPC überprüfen, um zu sehen, ob sie freigeschaltet sind. Vermeiden Sie es, mehrere oder schnelle Transaktionen mit denselben Objekten zu senden. Anstatt sich auf feste Verzögerungen zu verlassen, verwenden Sie Wiederholungsversuche mit Backoff und bestätigen Sie die Endgültigkeit, bevor Sie es erneut versuchen.
Dieses Sperren ist Teil der Art und Weise, wie Sui sichere Updates gewährleistet. Daher ist eine korrekte Sequenzierung und Überprüfung der Endgültigkeit der beste Weg, um JSONRPCError zu vermeiden
Weißt du die Antwort?
Bitte melde dich an und teile sie.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Verdiene deinen Anteil an 1000 Sui
Sammle Reputationspunkte und erhalte Belohnungen für deine Hilfe beim Wachstum der Sui-Community.

- Warum benötigt BCS eine genaue Feldreihenfolge für die Deserialisierung, wenn Move-Strukturen benannte Felder haben?55
- Fehler bei der Überprüfung mehrerer Quellen“ in den Veröffentlichungen des Sui Move-Moduls — Automatisierte Fehlerbehebung45
- Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert48
- Sui Move Error - Transaktion kann nicht verarbeitet werden Keine gültigen Gasmünzen für die Transaktion gefunden29
- Wie interagieren Fähigkeitsbeschränkungen mit dynamischen Feldern in heterogenen Sammlungen?07