Sui.

Beitrag

Teile dein Wissen.

Prämie+15

Bolke .
Aug 12, 2025
Experten Q&A

Sui Move Error - Transaktion kann nicht verarbeitet werden Keine gültigen Gasmünzen für die Transaktion gefunden

Wenn ich das mache:

//Zahlung von der Primärmünze trennen const [PaymentCoin] = tx.SplitCoins ( tx.object (PrimaryCoin.CoinObjectID), [tx.pure.u64 (erforderlicher Zahlungsbetrag)] );

//Verwende die Originalmünze für die Gaszahlung tx.setGasPayment ([{ ObjektID: PrimaryCoin.CoinObjectID, Version: PrimaryCoin.Version, verdauen: PrimaryCoin.digest }]);

tx.setGasBudget (10_000_000); Es beschwert sich darüber, dass veränderbare Objekte nicht mehr als eines in einer Transaktion vorkommen können. Wenn ich die Gaszahlung entferne, beschwert es sich: „Transaktion kann nicht verarbeitet werden Für die Transaktion wurden keine gültigen Gasmünzen gefunden.“. Meine Vertragsfunktion akzeptiert 0,01 Sui als Gegenleistung für eine NFT

  • Sui
  • Transaction Processing
  • Move
0
5
Teilen
Kommentare
.

Antworten

5
MiniBob.
Aug 12 2025, 19:33

Das passiert, weil du versuchst, dasselbe Münzobjekt (primaryCoin) sowohl als Gaszahlung als auch als Eingabe dafür zu verwendensplitCoins, was es zu einer veränderlichen Referenz macht, die in zwei verschiedenen Kontexten verwendet wird — und Sui erlaubt das aus Sicherheitsgründen und linearer Logik nicht (da Münzen lineare Objekte sind).

Meiner Meinung nach ist es so, dass man die Gaszahlung überhaupt nicht manuell festlegt. Lassen Sie einfach die Sui-Geldbörse/den Kunden automatisch eine geeignete Gasmünze auswählen. Verwenden Sie diese Option nur, setGasPaymentwenn Sie wirklich angeben müssen, mit welcher Münze Sie Benzin bezahlen können (z. B. Geldbörsen mit mehreren Münzen, spezielles Gasmanagement). Andernfalls vermeiden Sie es.

Versuche Folgendes:

// Split the primary coin to get a payment coin
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Do your call that sends .01 SUI and gets an NFT
tx.moveCall({
    target: `${packageId}::your_module::buy_nft`,
    arguments: [
        paymentCoin,
        // other args...
    ],
});

// DO NOT set gas payment manually
// tx.setGasPayment(...) ← Remove this line

// Optional: set budget
tx.setGasBudget(10_000_000);

// Send the transaction
const result = await signer.signAndExecuteTransactionBlock({
    transactionBlock: tx,
    options: { showEffects: true },
});

Sui wird:

  • Wählen Sie automatisch eine Gasmünze (es könnte dieselbe oder eine andere SUI-Münze in der Brieftasche sein).
  • Gehen Sie splitCoinssicher damit um.
  • Verwenden Sie eineandere Münze(oder manchmal dieselbe, aber unter der Haube durch eine korrekte Objektversionierung sicher gehandhabt).

Wichtig: Solange dein Portemonnaie mindestens 1$ SUI hat, mit dem Benzin gedeckt werden kann, funktioniert das.

0
Kommentare
.
0xduckmove.
Aug 13 2025, 03:14

Sie stoßen auf eine allgemeine Sui Move-Transaktionsdesign-Einschränkungdasselbe Münzobjekt kann nicht sowohl als veränderbare Eingabe (z. B. zum Teilen oder Übertragen) als auch als Gasmünze in einer einzigen Transaktion verwendet werden.

Warum passiert das

  • Wenn Sie tx.SplitCoins (tx.object (PrimaryCoin.CoinObjectID),...) verwenden, markieren Sie PrimaryCoin als veränderbare Eingabe.
  • Wenn Sie es auch mit tx.setGasPayment (...) als Gascoin festlegen, sieht Sui, dass dasselbe Objekt in zwei Rollen verwendet wird, was nicht erlaubt ist.
  • Wenn Sie die Gaszahlung entfernen, kann Sui keine gültige Gasmünze finden, daher der Fehler „Keine gültigen Gasmünzen für die Transaktion gefunden“.

Aus dem Kontext:

Status der Transaktionseffekte: Ungültige Verwendung des Werts. Veränderlich entliehene Werte erfordern eine eindeutige Verwendung. Unveränderlich geliehene Werte können nicht übernommen oder veränderlich geliehen werden. Übernommene Werte können nicht erneut verwendet werden. (Quelle)

Wie behebt man

Sie müssen eine andere Münze für Gas verwenden als die, die Sie teilen oder übertragen.

Die Lösung: Halten Sie mindestens zwei SUI-Münzen in Ihrer Brieftasche bereit. Verwende eine für die Zahlung (Aufteilen/Übertragen) und eine andere für Benzin.

Beispiel für einen Ablauf

  1. Wählen Sie zwei Münzen aus:
  • PrimaryCoin (zur Zahlung)
  • GasCoin (für Gas)
  1. Teilen und mit PrimaryCoin bezahlen:
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);
  1. Stellen Sie die Gaszahlung mit GasCoin ein:
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);
tx.setGasBudget(10_000_000);

Verwenden Sie nicht dasselbe Münzobjekt sowohl für die Zahlung als auch für das Benzin.

Meine Referenz

Sui Move: Ungültiges Entnehmen der Gasmünze. Es kann nur als Wert mit TransferObjects verwendet werden

0
Kommentare
.
Owen.
Owen4587
Aug 13 2025, 06:10

Der Fehler tritt auf, weil Sie versuchen, primaryCoindasOriginalobjekt(das während des splitCoinsVorgangs verbraucht wird) als Gaszahlung zu verwenden. Nach dem Teilen der Münze wird die Version/der Digest der Originalmünze ungültig. Bei erneuter Referenz wird der Fehler „Veränderbare Objekte können nicht mehr als ein Objekt vorkommen“ ausgelöst.

primaryCoinUm das Problem zu beheben, stellen Sie die Gaszahlung nicht manuell mithilfe des Pre-Split-Objekts ein. Und stellen Sie sicher, dass Ihr primaryCoinGuthaben ausreicht, um beides abzudecken:

  • Der Zahlungsbetrag (requiredPaymentAmount= 0,01 SUI)
  • Das Gasbudget (10_000_000= 0,01 SUI) → Benötigte Summe:≥ 0,02 SUI

Versuche es einfach

// Split payment from primary coin (leaves remaining balance in primaryCoin)
const [paymentCoin] = tx.splitCoins(
  tx.object(primaryCoin.coinObjectId),
  [tx.pure.u64(requiredPaymentAmount)]
);

// DO NOT setGasPayment manually - SDK auto-uses updated primaryCoin for gas
tx.setGasBudget(10_000_000); // Gas paid from primaryCoin's remaining balance
0
Kommentare
.
Paul.
Paul4180
Aug 13 2025, 08:48

Probleme

Sie stoßen auf zwei Hauptprobleme:

1.Mutabilitätsfehler: Der Versuch, dasselbe Münzobjekt sowohl für die Gaszahlung als auch für die Transaktionseingabe zu verwenden, führt zu dem Fehler: „Veränderbare Objekte können nicht mehr als einmal in einer Transaktion vorkommen.“

2.Fehlende Gasmünze: Ohne eine gültige Gasmünze tritt der Fehler „Transaktion kann nicht verarbeitet werden: Für die Transaktion wurden keine gültigen Gasmünzen gefunden“ auf.


Lösung

Um diese Probleme zu lösen:

1.Teilen Sie die primäre Münze für die Bezahlung: Verwenden Sie diese Optiontx.splitCoins, um eine neue Münze für den NFT-Kauf zu erstellen und sicherzustellen, dass sie von der Gaszahlung getrennt ist.

  1. tx.setGasPaymentStellen Sie eine separate Gasmünze ein: Weisen Sie der Gaszahlung mit einer anderen Münze zu.

  2. tx.setGasBudgetGasbudget definieren: Legen Sie ein geeignetes Gasbudget fest mit.


Kode

// Step 1: Split the primary coin for payment
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Step 2: Set a separate gas payment coin
const gasCoin = tx.object(gasCoinObjectId);
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);

// Step 3: Set the gas budget for the transaction
tx.setGasBudget(10_000_000);
0
Kommentare
.
casey.
Aug 14 2025, 03:40

AufSuiist ein einzelnes Münzobjekt veränderbar (sein Gleichgewicht ändert sich, wenn du es benutzt), und du kannst in einer Transaktion nicht zweimal auf dasselbe veränderbare Objekt verweisen — aus diesem Grund:

Du trennst dich von derselben PrimaryCoin

Und du verwendest es auch als Gaszahlung

→ Der Transaction Builder kennzeichnet dies als „veränderbares Objekt erscheint mehr als einmal“.

Warum passiert die Meldung „Keine gültigen Gasmünzen gefunden“, wenn Sie SetGasPayment entfernen

Wenn Sie keine Gasmünze angeben, wählt das Sui SDK automatisch eine Gasmünze aus Ihren eigenen Münzen aus, die noch nicht für die Transaktion verwendet wurde. Da Ihre Transaktion jedoch bereits die einzige Münze verbraucht, die Sie haben (über SplitCoins), ist keine zusätzliche Münze mehr übrig, um Benzin zu bezahlen.

So beheben Sie das Problem:

Sie benötigen zwei verschiedene Münzobjekte:

Münze A→ wird nur für Gas verwendet

Münze B→ aufgeteilt für deine .01 SUI Zahlung

Wenn Sie nur eine Münze in Ihrer Brieftasche haben, müssen Sie diese zunächst in einer vorläufigenTransaktion in zwei separate Münzobjekte aufteilen.

Der Schlüssel ist:

  • Sui verhindert, dass ein einzelnes Münzobjekt gleichzeitig Gas und veränderbare Eingabe in derselben Transaktion ist, da es als dieselbe veränderbare Referenz behandelt wird.
  • Aber in Move kannst du eine Münze gegen Bezahlung erhalten, ohne dass es dir egal ist, von welchem Objekt sie stammt — einschließlich einer Münze, die zuvor in derselben Transaktion von der Gasmünze getrennt wurde.

Das bedeutet, dass deine Move-Funktion nur die Zahlungsmünze akzeptieren sollte, nicht die ursprüngliche Münze, und du überlässt es dem Transaction Builder, sie aufzuteilen, bevor du sie übergibst.

move


module my_package::nft_market {

    use sui::coin::{Self, Coin};
    use sui::sui::{SUI};
    use sui::object::{UID};
    use sui::transfer;
    use sui::tx_context::{Self, TxContext};

    /// Simple function: take 0.01 SUI and give NFT
    public entry fun buy_nft(
        payment: Coin<SUI>,  // User provides exactly 0.01 SUI
        ctx: &mut TxContext
    ) {
        let amount = coin::value(&payment);
        let price = 10_000_000; // 0.01 SUI in MIST (1 SUI = 1_000_000_000 MIST)

        assert!(amount == price, 0);

        // Transfer the payment to the seller (hardcoded example)
        transfer::transfer(payment, tx_context::sender(ctx));

        // Mint NFT for buyer
        let nft = NFT {
            id: object::new(ctx),
            name: b"Special NFT".to_vec(),
        };
        transfer::transfer(nft, tx_context::sender(ctx));
    }

    struct NFT has key, store {
        id: UID,
        name: vector<u8>,
    }
}

Wie das Problem dadurch behebt wird

Wenn der Client die Transaktion erstellt:

1. Die Gasmünze (tx.gas) wird automatisch für Gas verwendet.

2. Vom Benzin getrennt, um einen neuen PaymentCoin zu erhalten:

js


const [paymentCoin] = tx.splitCoins(
    tx.gas, // mutable reference to gas coin
    [tx.pure.u64(requiredPaymentAmount)]
);

tx.moveCall({
    target: `${packageId}::nft_market::buy_nft`,
    arguments: [paymentCoin],
});

tx.setGasBudget(10_000_000);

3. Sui erlaubt das, weil:

  • tx.gasist das ObjektGaszahlung. -Der geteilte Ausgang(paymentCoin) ist einneues Objekt.
  • Sie sind jetztverschiedene veränderbare Objektein derTransaktion.

✅ Vorteil: Du brauchst das Wallet nicht mehr, um vorher zwei separate Münzobjekte aufzubewahren — die Move-Funktion kümmert sich nur noch um die Zahlungsmünze, und der Kunde kann sie jederzeit von der Gasmünze trennen, bevor er anruft.

0
Kommentare
.

Weißt du die Antwort?

Bitte melde dich an und teile sie.