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
10Dieser 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.
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
Sui 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.
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 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
That’s a great debugging question — I’ve run into this exact issue before when building staking flows on Sui. Let me answer in detail, step-by-step, from my perspective using Sui daily.
🔍 Why objects get “reserved” in Sui
In Sui, every transaction consumes specific object versions. Once you submit a transaction that references an object, the network puts a lock on that object version until the transaction is finalized (committed or fails).
So when you see:
JsonRpcError: Failed to sign transaction ... one or more of its objects is reserved
it means:
- The object version you’re trying to use is still “in flight” (reserved by another PTB),
- Or you’re re-using an outdated version without refreshing from the fullnode,
- Or the validator quorum hasn’t yet reached finality for the first transaction.
That’s why the same objectId
shows multiple times in the lock list — you’re trying to consume the same locked version repeatedly.
✅ How I check object availability before using
I always follow these steps:
-
After each transaction, re-fetch fresh object refs before building the next transaction block.
const fresh = await provider.getObject({ id: "0x1c20f15cbe780ee...", options: { showOwner: true, showPreviousTransaction: true, showContent: true }, }); const version = fresh.data.version; // must use this version in the next PTB
-
Wait for local execution / finality when submitting. Always request
WaitForLocalExecution
in yoursignAndExecuteTransactionBlock
. This ensures the object is unlocked before you try to use it again.const res = await signer.signAndExecuteTransactionBlock({ transactionBlock: tx, requestType: "WaitForLocalExecution", });
-
Implement a retry with exponential backoff when conflicts occur. Even with sequencing, there are cases where the fullnode lags. I use a
submitWithRetry
wrapper (like the one I showed earlier) that catchesObject version mismatch
and retries after re-fetching the object.
⚡ Best practices for handling object locks
- Never reuse old object references. Always fetch the latest state from the RPC before constructing each PTB.
- Design with parallelism in mind. If multiple independent flows need the same object, shard state across multiple owned objects (avoid a single global shared object).
- Batch operations when possible. Use a single
TransactionBlock
with multiple Move calls instead of sending sequential transactions that lock the same object repeatedly. - Add backoff + retries. I usually back off
100ms, 200ms, 400ms, 800ms … up to ~3s
before giving up. - Use checkpoints/finality awareness. Remember: an object isn’t truly free until the checkpoint is committed.
⏱️ Relation to finality timing
Yes, this is directly related. Even after a transaction appears “executed”, the object may remain reserved until:
- The local fullnode confirms execution,
- The consensus checkpoint includes it,
- The version updates propagate across validators.
That’s why adding a blind 3-second delay
isn’t reliable — network conditions and validator lag can extend this. The right way is fetch-after-execution instead of sleeping.
🛠️ Example: Safe sequential staking
Here’s how I do it in code (simplified):
async function safeStake(signer, validatorAddr, stakeAmountMist, stakeObjectId) {
let attempt = 0;
while (attempt < 5) {
try {
// 1. Fetch latest object version
const obj = await provider.getObject({ id: stakeObjectId, options: { showOwner: true } });
const version = obj.data.version;
// 2. Build PTB with fresh version
const tx = new TransactionBlock();
tx.moveCall({
target: "0x2::staking::request_add_stake",
arguments: [tx.pure(validatorAddr), tx.pure(stakeAmountMist.toString())],
typeArguments: [],
});
// 3. Execute with finality wait
const res = await signer.signAndExecuteTransactionBlock({
transactionBlock: tx,
requestType: "WaitForLocalExecution",
});
console.log("✅ success:", res.digest);
return res;
} catch (e) {
if (e.message.includes("reserved") || e.message.includes("Object version mismatch")) {
attempt++;
const backoff = 200 * 2 ** attempt;
console.warn(`conflict, retrying in ${backoff}ms`);
await new Promise(r => setTimeout(r, backoff));
continue;
}
throw e;
}
}
throw new Error("failed after retries");
}
This ensures:
- I always use the latest object version,
- I wait for finality,
- I retry on transient lock errors.
🧩 TL;DR
- Cause: Object locks happen because an object version is still reserved by an in-flight transaction.
- Fix: Always re-fetch latest object versions, wait for local execution, and retry on conflicts.
- Best practice: Shard state, batch operations, and use retries/backoff rather than fixed sleeps.
- Yes, finality timing matters. Blind delays won’t solve it — confirmation checks + re-fetching will.
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.
- So maximieren Sie Ihre Gewinnbeteiligung SUI: SUI Staking vs Liquid Staking615
- Warum benötigt BCS eine genaue Feldreihenfolge für die Deserialisierung, wenn Move-Strukturen benannte Felder haben?65
- Fehler bei der Überprüfung mehrerer Quellen“ in den Veröffentlichungen des Sui Move-Moduls — Automatisierte Fehlerbehebung55
- Sui Move Error - Transaktion kann nicht verarbeitet werden Keine gültigen Gasmünzen für die Transaktion gefunden419
- Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert410