Sui.

Допис

Діліться своїми знаннями.

Винагорода+15

Bolke .
Aug 12, 2025
Питання та відповіді експертів

Помилка Sui Move - Неможливо обробити транзакцію Не знайдено дійсних газових монет для транзакції

Коли я роблю це:

//Розділіть платіж з основної монети конст [PaymentCoin] = TX.спліткойни ( tx.object (первинний Coin.CoinObjectID), [tx.pure.u64 (Обов'язкова сума платежу)] );

//Використовуйте оригінальну монету для оплати газу tx.setGasPayment ([{ Об'єктID: первинний Coin.CoinObjectID, версія: первинна коін.версія, дайджест: первинний коїн.дайджест }]);

ТК.сетгасБюджет (10_000_000); Він скаржиться на об'єкти, що змінюються, не можуть з'являтися більше одного в одній транзакції. Коли я знімаю платіж за газ, він скаржиться «Не вдається обробити транзакцію Для транзакції не знайдено дійсних газових монет». Моя функція контракту приймає .01 sui в обмін на NFT

  • Sui
  • Transaction Processing
  • Move
4
19
Поділитися
Коментарі
.

Відповіді

19
MoonBags.
Sep 4 2025, 03:43

You are running into a core Sui Move and Sui transaction model restriction: the same coin object cannot be used both as a gas coin and as an input to another command in the same transaction. This is enforced to prevent double-spending and ensure transaction safety.

Why this happens

  • When you use primaryCoin in splitCoins, it becomes a mutable input to the transaction.
  • When you also set it as the gas coin (setGasPayment), you are trying to use the same object in two roles.
  • Sui does not allow a mutable object (like a coin being split) to also be used as the gas coin in the same transaction.

This is confirmed by the error in your context:

mutatable objects cannot appear more than one in one transaction

And in the Sui Move test context:

Invalid taking of the Gas coin. It can only be used by-value with TransferObjects
(see source)

What you need to do

You must use a different coin for gas than the one you are splitting or otherwise mutating in the transaction.

Solution

  1. Ensure you have at least two SUI coins in your wallet.
  2. Use one coin for splitting/payment, and another for gas.

Example Flow

Suppose you have two coins: primaryCoin and gasCoin.

// Split payment from primary coin (not used for gas)
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);

// Set a different coin for gas payment
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);

tx.setGasBudget(10_000_000);
  • primaryCoin is used for splitting and payment.
  • gasCoin is used only for gas.

If you only have one coin, you must first split it in a separate transaction, so you have two coins for the next transaction.


References

8
Коментарі
.
0xduckmove.
Sep 4 2025, 04:52

This is a fundamental design choice in Sui to ensure transaction safety and prevent double-spending. It can be confusing at first, but once you get used to always keeping at least two coins in your wallet (one for gas, one for other operations), it becomes second nature. If you ever run into this error, just remember: never use the same coin for both gas and as a mutable input in the same transaction

Carnelian.
Sep 4 2025, 05:01

Always select a distinct coin object for gas payment, separate from any coin you intend to mutate or transfer. If you only have one coin, split it in a prior transaction to create a second coin object for subsequent operations.

0xduckmove.
Aug 13 2025, 03:14

Ви стикаєтесь із загальним обмеженням дизайну транзакції Sui Moveтой самий об'єкт монети не може бути використаний як змінний вхід (наприклад, для поділу чи передачі), так і як газову монету в одній транзакції.

Чому це відбувається

  • Коли ви використовуєте Tx.splitCoins (tx.object (PrimaryCoin.CoinObjectId),...), ви позначаєте PrimaryCoin як змінний вхід.
  • Коли ви також встановлюєте її як газову монету за допомогою tx.setGasPayment (...), Суй бачить, що один і той же об'єкт використовується у двох ролах, що заборонено.
  • Якщо ви знімаєте платіж за газ, Суй не може знайти дійсну газову монету, звідси помилка «Не знайдено дійсних газових монет для транзакції».

З контексту:

Статус ефектів транзакції: некоректне використання значення. Змінно запозичені значення вимагають унікального використання. Незмінно запозичені цінності не можуть бути прийняті або запозичені змінно. Взяті значення не можна використовувати повторно. (джерело)

Як виправити

Ви повинні використовувати іншу монету для газу, ніж ту, яку ви розщеплюєте або переводите.

Рішення: Майте у гаманці принаймні дві монети SUI. Використовуйте один для оплати (спліт/переказ), а інший - для газу.

Приклад потоку

  1. Виберіть дві монети:
  • PrimaryCoin (для оплати)
  • GasCoin (для газу)
  1. Розділіть та оплатіть за допомогою PrimaryCoin:
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);
  1. Встановіть оплату газу за допомогою GasCoin:
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);
tx.setGasBudget(10_000_000);

Не використовуйте один і той же об'єкт монети як для оплати, так і для газу.

Моя довідка

Sui Move: Недійсне взяття монети «Газ». Його можна використовувати лише за значенням за допомогою TransferObjects

5
Коментарі
.
Owen.
Owen4662
Aug 13 2025, 06:10

Помилка виникає через те, що ви намагаєтеся використатиоригінальний primaryCoinоб'єкт(який споживається під час splitCoinsоперації) як платіж за газ. Після поділу версія/дайджест оригінальної монети стає недійсною, що спричиняє помилку «об'єкти, що змінюються, не можуть відображатися більше одного» при повторному посиланні.

Для виправлення не встановлюйте вручну оплату газу за допомогою primaryCoinоб'єкта попереднього спліту. І переконайтеся, що у primaryCoinвас є достатній баланс для покриття обох:

  • Сума платежу (requiredPaymentAmount= 0,01 SUI)
  • Газовий бюджет (10_000_000= 0,01 СУІ) → Всього необхідних:≥ 0,02 SUI

Просто спробуйте

// 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
4
Коментарі
.
Gifted.eth.
Aug 22 2025, 00:57

Молодці!!!

Redterror.
Aug 15 2025, 10:50

Щоб вирішити проблему, з якою ви стикаєтесь із помилкою транзакції Sui щодо того, що не знайдено дійсних газових монет або змінних об'єктів, що відображаються більше одного разу, це тому, що ви не можете використовувати одну і ту ж монету як для розділення платежу, так і для покриття комісій за газ, оскільки газові монети повинні залишатися окремо від предметів, які ви налаштовуєте в угоді. Проста настройка полягає в тому, щоб розділити платіж прямо з джерела газу замість вашої основної монети, тому змініть його на щось на кшталт

const paymentCoin = tx.splitCoins(tx.gas(), [tx.pure.u64(requiredPaymentAmount)]);

потім взагалі відмовтеся від ручної лінії оплати газу, оскільки система забере її самостійно, і збереже ваш бюджет газу встановленим як зазвичай. Це дозволяє витягнути з газової монети без зіткнень, якщо у вашому гаманці є достатньо для обробки платежу 0.01 Sui плюс комісії.

4
Коментарі
.
MiniBob.
Aug 12 2025, 19:33

Це відбувається тому, що ви намагаєтеся використовувати один і той же об'єкт монети (primaryCoin) як як платіж за газ, так і як вхід доsplitCoins, що робить його змінним посиланням, що використовується у двох різних контекстах - і Sui не дозволяє цього для безпеки та лінійної логіки (оскільки монети є лінійними об'єктами).

Спосіб IMHO полягає в тому, щоб взагалі не встановлювати оплату за газ вручну. Просто нехай гаманець/клієнт Sui автоматично вибере відповідну газову монету. Використовуйте лише в тому setGasPaymentвипадку, якщо вам дійсно потрібно вказати, яка монета платить за газ (наприклад, гаманці з кількома монетами, конкретне управління газом). В іншому випадку уникайте цього.

Спробуйте наступне:

// 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 в гаманці).
  • Поводьтеся splitCoinsбезпечно.
  • Використовуйтеіншу монету(або іноді ту саму, але безпечно обробляйте під капотом за допомогою належного редагування об'єктів).

Важливо: Поки у вашому гаманці є принаймні 1 $SUI, який може покрити газ, це буде працювати.

3
Коментарі
.
BigDev.
Aug 15 2025, 16:20

Ця проблема трапляється тому, що ви використовуєте одну і ту ж монету (PrimaryCoin) як для газу, так і як вхід у SplitCoins, що заборонено в Sui через його правила навколо лінійних об'єктів та безпечної мутації.

Щоб виправити це, не встановлюйте вручну платіж за газ. Нехай гаманець Sui або клієнт автоматично вибере відповідну газову монету. Вам потрібен SetGasPayment лише в запущених випадках (наприклад, точний контроль монет). Ось чистий підхід:


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

// Call your function using the new coin
tx.moveCall({
  target: ${packageId}::your_module::buy_nft,
  arguments: [paymentCoin],
});

// No manual gas setting — remove tx.setGasPayment(...)

// Set your gas budget
tx.setGasBudget(10_000_000);

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

Суй безпечно забере газову монету з вашого гаманця (поки вона є) і обробляє все за лаштунками

3
Коментарі
.
Carnelian.
Aug 30 2025, 15:10

This error happens because you’re trying to use the same coin both as the gas object and for a split operation, which breaks Sui’s rule against having two mutable references to the same object in one transaction. Splitting primaryCoin modifies it while also producing a new coin, and both can’t coexist in the same transaction. To fix this, you should:

* Use separate coins: one dedicated for gas, another for splitting or payments.
* Or, merge enough balance from another coin into primaryCoin before the transaction so it can cover all costs without duplication.

In short: always ensure that the coin used for gas is different from the one being split or passed into contract calls to prevent conflicts.

3
Коментарі
.
Paul.
Paul4340
Aug 13 2025, 08:48

Проблеми

Ви стикаєтеся з двома основними проблемами:

1.Помилка змінності: Спроба використовувати один і той же об'єкт монети як для оплати газу, так і для введення транзакції призводить до помилки: «Об'єкти, що змінюються, не можуть з'являтися більше одного разу в одній транзакції».

2.Відсутня газова монета: Без дійсної газової монети виникає помилка «Неможливо обробити транзакцію: для транзакції не знайдено дійсних газових монет».


Рішення

Щоб вирішити ці проблеми, виконайте такі дії:

1.Розділіть основну монету для платежу: Використовуйте для tx.splitCoinsстворення нової монети для покупки NFT, переконавшись, що вона відокремлена від платежу за газ.

  1. tx.setGasPaymentВстановіть окрему газову монету: Призначте іншу монету для оплати за допомогою газу.

  2. tx.setGasBudgetВизначте бюджет газу: Встановіть відповідний бюджет газу за допомогою.


Код

// 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);
2
Коментарі
.
Benjamin XDV.
Aug 22 2025, 11:08

Помилка виникає через те, що ви намагаєтесьрозділити та використати одну і ту ж монету як для оплати, так і для газу, порушуючи правило Sui щодо змінюваного дублювання об'єктів у транзакції. Коли ви розділяєтеprimaryCoin, він створює нову монету, одночасно мутуючи оригінал - обидві не можуть з'являтися в одній транзакції. Щоб вирішити цю проблему,використовуйте дві окремі монети: одну для оплати газу, а іншу для операції розділеного платежу. Крім того,об'єднайте достатню кількість газу з іншої монетиprimaryCoinдо операції, щоб покрити обидві витрати, гарантуючи, що існує лише одне змінне посилання. Завжди перевіряйте, що газові монети відрізняються від тих, що розділяються або використовуються в контрактних дзвінках, щоб уникнути конфліктів.

2
Коментарі
.
Gifted.eth.
Aug 22 2025, 15:01

Сподіваюся, у вас є рішення для цього, так?

Evgeniy CRYPTOCOIN.
Aug 22 2025, 11:19

Ви не можете використовуватиту саму монетуяк для оплати, так і для газу. Виправити:

1.Split Gas First— Створіть окрему газову монету:

  const [gasCoin] = tx.splitCoins(tx.object(primaryCoinId), [tx.pure(10_000_000)]);  
  tx.setGasPayment([gasCoin]);  

2.Потім розділіть платіж— Використовуйте залишок залишку для платежу NFT.

Ключове правило: ✔ Кожну монету можна використовувати лишеодин раз за транзакцію.

Альтернатива: Використовуйте дві окремі монети (якщо є).

  • (Sui вимагає окремих монет для газу та платежів, щоб уникнути конфліктів. ) *
1
Коментарі
.
Arnold.
Arnold3036
Aug 22 2025, 12:00

Помилка трапляється тому, що ви намагаєтеся використовувати один і той же об'єкт монети для двох різних речей: розщеплення для здійснення платежу та оплати за газ. Система розглядає це як спробу змінно використовувати один об'єкт двічі в одній транзакції, що не дозволяється.

Для оплати газу потрібна окрема монета. Ось виправлення:

  1. gasPaymentВикористовуйте іншу газову монету: Знайдіть іншу монету у списку монет SUI у вашому гаманці, яку потрібно вказати як. Не використовуйте те, що primaryCoinви розділяєте.

2.Або спочатку об'єднайте монети: Якщо у вас є лише одна монета, можливо, вам доведеться спочатку об'єднати в неї кілька менших монет, щоб створити окрему газову монету. Потім використовуйте один для спліту/оплати, а інший для газу.

Головне в тому, що монета, яку ви використовуєте, setGasPaymentповинна бути повністю відокремлена від будь-яких монет, які ви розділяєте або використовуєте в командах транзакції.

1
Коментарі
.
Gifted.eth.
Aug 22 2025, 14:57

Молодці!!!

chaincrafter.
Sep 13 2025, 22:05

That error on Sui:

“Unable to process transaction – No valid gas coins found for the transaction”

means your wallet doesn’t currently have any SUI tokens that can be used as gas fees. Every transaction on Sui — whether sending tokens, minting NFTs, or interacting with dApps — requires a small amount of SUI to pay for gas.


🔍 Why It Happens

  • No SUI balance: You don’t have any SUI in your wallet.
  • Coin is too small: Sometimes SUI is “locked” in very tiny amounts (dust coins) that are not enough to cover gas.
  • Wrong network: You may be on Testnet or Devnet but don’t have test SUI loaded.
  • Wallet not refreshed: Rarely, the wallet UI lags behind and doesn’t recognize available coins.

✅ How to Fix It

If You’re on Mainnet

  1. Get some SUI tokens

    • Buy SUI from an exchange (Binance, KuCoin, OKX, etc.) and withdraw to your wallet.
    • Or receive SUI from a friend/wallet that already has some.
  2. Check for Coin Splitting

    • Sometimes you have SUI, but it’s fragmented into unusable “dust.”
    • Use the “Merge Coins” feature in Sui Wallet (found under your SU
  3. Use a Faucet

    • Go to the official Sui faucet: https://faucet.sui.io

    • Or, on Discord (in the Sui Discord server), go to the #testnet-faucet channel and type:

      !faucet <your_sui_address>
      
    • This will send you free testnet SUI.

  4. Switch Networks Properly

    • In your Sui Wallet extension → click profile icon → select Testnet or Devnet depending on where you’re working.

⚠️ Tip

Always keep a small reserve of SUI in your wallet for gas (like 0.05–0.1 SUI). If you send your entire balance out, you won’t have gas left to make the next transaction.


Do you want me to walk you through getting testnet SUI from the faucet right now, or are you running into this issue on mainnet with real tokens?

0
Коментарі
.

Ви знаєте відповідь?

Будь ласка, увійдіть та поділіться нею.