Допис
Діліться своїми знаннями.
+15
Помилка 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
Відповіді
19You 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
insplitCoins
, 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
- Ensure you have at least two SUI coins in your wallet.
- 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
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
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.
Ви стикаєтесь із загальним обмеженням дизайну транзакції Sui Moveтой самий об'єкт монети не може бути використаний як змінний вхід (наприклад, для поділу чи передачі), так і як газову монету в одній транзакції.
Чому це відбувається
- Коли ви використовуєте Tx.splitCoins (tx.object (PrimaryCoin.CoinObjectId),...), ви позначаєте PrimaryCoin як змінний вхід.
- Коли ви також встановлюєте її як газову монету за допомогою tx.setGasPayment (...), Суй бачить, що один і той же об'єкт використовується у двох ролах, що заборонено.
- Якщо ви знімаєте платіж за газ, Суй не може знайти дійсну газову монету, звідси помилка «Не знайдено дійсних газових монет для транзакції».
З контексту:
Статус ефектів транзакції: некоректне використання значення. Змінно запозичені значення вимагають унікального використання. Незмінно запозичені цінності не можуть бути прийняті або запозичені змінно. Взяті значення не можна використовувати повторно. (джерело)
Як виправити
Ви повинні використовувати іншу монету для газу, ніж ту, яку ви розщеплюєте або переводите.
Рішення: Майте у гаманці принаймні дві монети SUI. Використовуйте один для оплати (спліт/переказ), а інший - для газу.
Приклад потоку
- Виберіть дві монети:
- PrimaryCoin (для оплати)
- GasCoin (для газу)
- Розділіть та оплатіть за допомогою PrimaryCoin:
const [paymentCoin] = tx.splitCoins(
tx.object(primaryCoin.coinObjectId),
[tx.pure.u64(requiredPaymentAmount)]
);
- Встановіть оплату газу за допомогою GasCoin:
tx.setGasPayment([{
objectId: gasCoin.coinObjectId,
version: gasCoin.version,
digest: gasCoin.digest
}]);
tx.setGasBudget(10_000_000);
Не використовуйте один і той же об'єкт монети як для оплати, так і для газу.
Моя довідка
Помилка виникає через те, що ви намагаєтеся використатиоригінальний 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
Молодці!!!
Щоб вирішити проблему, з якою ви стикаєтесь із помилкою транзакції Sui щодо того, що не знайдено дійсних газових монет або змінних об'єктів, що відображаються більше одного разу, це тому, що ви не можете використовувати одну і ту ж монету як для розділення платежу, так і для покриття комісій за газ, оскільки газові монети повинні залишатися окремо від предметів, які ви налаштовуєте в угоді. Проста настройка полягає в тому, щоб розділити платіж прямо з джерела газу замість вашої основної монети, тому змініть його на щось на кшталт
const paymentCoin = tx.splitCoins(tx.gas(), [tx.pure.u64(requiredPaymentAmount)]);
потім взагалі відмовтеся від ручної лінії оплати газу, оскільки система забере її самостійно, і збереже ваш бюджет газу встановленим як зазвичай. Це дозволяє витягнути з газової монети без зіткнень, якщо у вашому гаманці є достатньо для обробки платежу 0.01 Sui плюс комісії.
Це відбувається тому, що ви намагаєтеся використовувати один і той же об'єкт монети (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, який може покрити газ, це буде працювати.
Ця проблема трапляється тому, що ви використовуєте одну і ту ж монету (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 },
});
Суй безпечно забере газову монету з вашого гаманця (поки вона є) і обробляє все за лаштунками
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.
Проблеми
Ви стикаєтеся з двома основними проблемами:
1.Помилка змінності: Спроба використовувати один і той же об'єкт монети як для оплати газу, так і для введення транзакції призводить до помилки: «Об'єкти, що змінюються, не можуть з'являтися більше одного разу в одній транзакції».
2.Відсутня газова монета: Без дійсної газової монети виникає помилка «Неможливо обробити транзакцію: для транзакції не знайдено дійсних газових монет».
Рішення
Щоб вирішити ці проблеми, виконайте такі дії:
1.Розділіть основну монету для платежу: Використовуйте для tx.splitCoins
створення нової монети для покупки NFT, переконавшись, що вона відокремлена від платежу за газ.
-
tx.setGasPayment
Встановіть окрему газову монету: Призначте іншу монету для оплати за допомогою газу. -
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);
Помилка виникає через те, що ви намагаєтесьрозділити та використати одну і ту ж монету як для оплати, так і для газу, порушуючи правило Sui щодо змінюваного дублювання об'єктів у транзакції. Коли ви розділяєтеprimaryCoin
, він створює нову монету, одночасно мутуючи оригінал - обидві не можуть з'являтися в одній транзакції. Щоб вирішити цю проблему,використовуйте дві окремі монети: одну для оплати газу, а іншу для операції розділеного платежу. Крім того,об'єднайте достатню кількість газу з іншої монетиprimaryCoin
до операції, щоб покрити обидві витрати, гарантуючи, що існує лише одне змінне посилання. Завжди перевіряйте, що газові монети відрізняються від тих, що розділяються або використовуються в контрактних дзвінках, щоб уникнути конфліктів.
Сподіваюся, у вас є рішення для цього, так?
Ви не можете використовуватиту саму монетуяк для оплати, так і для газу. Виправити:
1.Split Gas First— Створіть окрему газову монету:
const [gasCoin] = tx.splitCoins(tx.object(primaryCoinId), [tx.pure(10_000_000)]);
tx.setGasPayment([gasCoin]);
2.Потім розділіть платіж— Використовуйте залишок залишку для платежу NFT.
Ключове правило: ✔ Кожну монету можна використовувати лишеодин раз за транзакцію.
Альтернатива: Використовуйте дві окремі монети (якщо є).
- (Sui вимагає окремих монет для газу та платежів, щоб уникнути конфліктів. ) *
Помилка трапляється тому, що ви намагаєтеся використовувати один і той же об'єкт монети для двох різних речей: розщеплення для здійснення платежу та оплати за газ. Система розглядає це як спробу змінно використовувати один об'єкт двічі в одній транзакції, що не дозволяється.
Для оплати газу потрібна окрема монета. Ось виправлення:
gasPayment
Використовуйте іншу газову монету: Знайдіть іншу монету у списку монет SUI у вашому гаманці, яку потрібно вказати як. Не використовуйте те, щоprimaryCoin
ви розділяєте.
2.Або спочатку об'єднайте монети: Якщо у вас є лише одна монета, можливо, вам доведеться спочатку об'єднати в неї кілька менших монет, щоб створити окрему газову монету. Потім використовуйте один для спліту/оплати, а інший для газу.
Головне в тому, що монета, яку ви використовуєте, setGasPayment
повинна бути повністю відокремлена від будь-яких монет, які ви розділяєте або використовуєте в командах транзакції.
Молодці!!!
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
-
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.
-
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
-
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.
-
-
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?
Ви знаєте відповідь?
Будь ласка, увійдіть та поділіться нею.
Sui is a Layer 1 protocol blockchain designed as the first internet-scale programmable blockchain platform.
Зароби свою частку з 1000 Sui
Заробляй бали репутації та отримуй винагороди за допомогу в розвитку спільноти Sui.
- Як максимізувати прибуток від SUI: Sui Staking проти Liquid Staking615
- Чому BCS вимагає точного порядку полів для десеріалізації, коли структури Move мають названі поля?65
- Помилки перевірки кількох джерел» у публікаціях модуля Sui Move - автоматичне вирішення помилок55
- Помилка Sui Move - Неможливо обробити транзакцію Не знайдено дійсних газових монет для транзакції419
- Невдала операція Sui: об'єкти, зарезервовані для іншої транзакції410