Sui.

Beitrag

Teile dein Wissen.

Prämie+15

Xavier.eth.
Jun 27, 2025
Experten Q&A

Sui-Transaktion schlägt fehl: Objekte sind für eine andere Transaktion reserviert

JsonRpcErrorBeim 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.

  1. Was bewirkt, dass Objekte für andere Transaktionen „reserviert“ werden?
  2. Wie kann ich richtig überprüfen, ob ein Objekt verfügbar ist, bevor ich es in einer Transaktion verwende?
  3. Gibt es bewährte Methoden für den Umgang mit Objektsperren in Sui?
  4. 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
4
10
Teilen
Kommentare
.

Antworten

10
harry phan.
Jun 30 2025, 15:00

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.

12
Kommentare
.
0xduckmove.
Jun 30 2025, 07:04

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

6
Kommentare
.
Owen.
Owen4662
Jun 30 2025, 11:03

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.

5
Kommentare
.
MiniBob.
Jun 30 2025, 11:50

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:

  1. Vergewissern Sie sich immer, dass frühere Transaktionen mit den Objekten vollständig abgeschlossen wurden, bevor Sie sie erneut verwenden.
  2. Überprüfen Sie den Objektstatus über Sui RPC, um sicherzustellen, dass sie entsperrt sind.
  3. Vermeiden Sie es, parallele oder schnelle Transaktionen auf denselben Objekten zu senden.
  4. 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. JsonRpcErrorEine korrekte Sequenzierung und Bestätigung der Endgültigkeit sind der Schlüssel zur Vermeidung.

4
Kommentare
.
BigDev.
Aug 15 2025, 16:24

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

2
Kommentare
.
0xF1RTYB00B5.
Sep 18 2025, 16:25

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:

  1. 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
    
  2. Wait for local execution / finality when submitting. Always request WaitForLocalExecution in your signAndExecuteTransactionBlock. This ensures the object is unlocked before you try to use it again.

    const res = await signer.signAndExecuteTransactionBlock({
      transactionBlock: tx,
      requestType: "WaitForLocalExecution",
    });
    
  3. 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 catches Object 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.
0
Kommentare
.

Weißt du die Antwort?

Bitte melde dich an und teile sie.