Пост
Поделитесь своими знаниями.
+15
Ошибка Sui Move — невозможно обработать транзакцию Не найдено действительных газовых монет для транзакции
Когда я это сделаю:
//Отделите платеж от основной монеты константа [PaymentCoin] = TX.SplitCoins ( объект tx.object (идентификатор объекта PrimaryCoin.coin), [tx.pure.u64 (обязательная сумма платежа)] );
//Используйте оригинальную монету для оплаты газа tx.Установите оплату газа ([{ Идентификатор объекта: идентификатор объекта PrimaryCoin.coin, версия: версия PrimaryCoin, дайджест: PrimaryCoin.Дайджест }]);
Налогообложение бюджета на газ (10_000_000); Он жалуется на то, что изменяемые объекты не могут появляться более одного в одной транзакции. Когда я удаляю платеж за газ, оно жалуется: «Невозможно обработать транзакцию» Для транзакции не найдено действительных газовых монет». Моя контрактная функция принимает сумму 0,01 евро в обмен на 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 SUI) → Всего необходимых сумм:≥ 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 суя плюс комиссии.
Это происходит потому, что вы пытаетесь использовать один и тот же монетный объект (primaryCoin
) как для оплаты газа, так и для вводаsplitCoins
, поэтому его можно использовать в двух разных контекстах, а Sui не допускает этого из соображений безопасности и линейной логики (поскольку монеты — это линейные объекты).
Имхо, вообще не нужно настраивать оплату за газ вручную. Просто позвольте кошельку/клиенту 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
безопасно. - Используйтедругую монету(а иногда и ту же самую, но при правильном управлении версиями объектов ее можно безопасно хранить под капотом).
Важно: если в вашем кошельке есть SUI стоимостью не менее 1 доллара США, который может покрыть бензин, это сработает.
Эта проблема возникает из-за того, что вы используете одну и ту же монету (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 },
});
Sui безопасно выберет из вашего кошелька газовую монету (если она есть) и разберется со всем за кулисами
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);
Ошибка возникает из-за того, что вы пытаетесьразделить и использовать одну и ту же монету как для оплаты, так и для газа, нарушая правило Суи, запрещающее дублирование изменяемых объектов в транзакции. При разделении монеты primaryCoin
образуется новая монета, а оригинальная монета изменяется. Обе монеты не могут быть включены в одну транзакцию. Чтобы решить эту проблему,используйте две отдельные монеты: одну для оплаты газа, а другую — для операции раздельного платежа. В качестве альтернативного варианта: primaryCoin
перед транзакцией добавьте достаточное количество газа из другой монеты**, чтобы покрыть обе эти расходы, убедившись, что существует только одна изменчивая ссылка. Чтобы избежать конфликтов, всегда проверяйте, отличаются ли монеты за газ от монет, которые используются для обмена или использования при заключении контрактов.
Надеюсь, у вас есть решение этой проблемы, да?
Вы не можете использовать одну и ту же монету**как для оплаты, так и для оплаты газа. Исправление:
1.Сначала разделите газ— создайте отдельную газовую монету:
const [gasCoin] = tx.splitCoins(tx.object(primaryCoinId), [tx.pure(10_000_000)]);
tx.setGasPayment([gasCoin]);
2.Затем раздельный платеж— используйте оставшийся остаток для платежа NFT.
Ключевое правило: ✔ Каждую монету можно использовать толькоодин раз за транзакцию.
Альтернатива: Используйте две отдельные монеты (если есть).
- (Чтобы избежать конфликтов, Суй требует разных монет для оплаты бензина и оплаты. ) *
Ошибка возникает из-за того, что вы пытаетесь использовать одну и ту же монету для двух разных целей: для разделения монеты для оплаты и оплаты газа. Система видит в этом попытку дважды использовать один и тот же объект за одну транзакцию, что недопустимо.
Для оплаты газа нужна отдельная монета. Вот исправление:
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: стейкинг и ликвидный стейкинг615
- Почему BCS требует точного порядка полей для десериализации, когда структуры Move содержат именованные поля?65
- «Ошибки проверки нескольких источников» в публикациях модуля Sui Move — автоматическое устранение ошибок55
- Ошибка Sui Move — невозможно обработать транзакцию Не найдено действительных газовых монет для транзакции419
- Сбой транзакции Sui: объекты, зарезервированные для другой транзакции410