帖子
分享您的知识。
+15
Sui Move 错误-无法处理交易未找到用于交易的有效汽油币
当我这样做时:
//从主币中拆分付款 const [PaymentCoin] = tx.SplitCoins ( tx.object (primaryCoin.coinObjectID), [tx.pure.u64(所需付款金额)] );
//使用原始硬币支付汽油 tx.setGasPayment ([{ ObjectID:primarycoin.coinObjectID, 版本:PrimaryCoin.Version, 摘要:Primarycoin.digest }]);
tx.setgasBudget (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 会看到同一个物品被用于两个角色,这是不允许的.
- 如果您取消汽油付款,Sui 找不到有效的汽油币,因此出现 “未找到用于交易的有效汽油币” 错误.
从上下文来看:
交易影响状态:价值使用无效. 可变的借用值需要独特的用法. 不可改变的借用值不能以可变方式取用或借用. 已获取的值不能再次使用. (来源)
如何修复
您必须使用与拆分或转移的硬币不同的硬币作为汽油.
解决方案:你的钱包里至少有两个 SUI 硬币. 使用一种进行付款(拆分/转账),另一种用于汽油.
示例流程
- 选择两枚硬币:
- PrimaryCoin(用于付款)
- GasCoin(用于汽油)
- 使用 PrimaryCoin 拆分并付款:
const [paymentCoin] = tx.splitCoins(
tx.object(primaryCoin.coinObjectId),
[tx.pure.u64(requiredPaymentAmount)]
);
3.使用 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 Sui的付款和费用,这就可以让你在不发生冲突的情况下从汽油币中提取资金.
之所以发生这种情况,是因为你试图使用相同的硬币对象 (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 将:
-自动选择一枚汽油币(可以是钱包中相同的一种或另一种 SUI 硬币).
-splitCoins
安全地处理.
-使用不同的硬币(有时是相同的硬币,但通过适当的对象版本控制在后台安全处理).
重要提示:只要你的钱包里有至少 1 美元的 SUI 可以支付汽油,这就行得通了.
之所以会出现这个问题,是因为你使用相同的硬币(PrimaryCoin)作为气体和SplitCoins的输入,Sui不允许使用这种硬币(PrimaryCoin),因为它有关于线性物体和安全突变的规则.
要修复这个问题,不要手动设置汽油支付. 让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.
问题
你遇到了两个主要问题:
-
可变性错误:尝试使用相同的硬币对象进行汽油支付和交易输入会导致错误:“可变对象在一次交易中不能出现超过一次. ”
-
缺少汽油币:如果没有有效的汽油币,则会出现 “无法处理交易:未找到用于交易的有效汽油币” 错误.
解决方案
要解决这些问题,请执行以下操作:
-
拆分主要硬币进行支付:用于
tx.splitCoins
为购买 NFT 创建新硬币,确保其与汽油付款分开. -
tx.setGasPayment
设置单独的汽油币:使用不同的硬币进行汽油支付.
3.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
交易前将来自另一枚硬币的足够气体合并到其中以支付这两项费用,从而确保仅存在一个可变引用. 务必验证汽油币与拆分或在合约看涨中使用的汽油币有区别,以避免冲突.
我希望你能解决这个问题对吧?
你不能使用相同的硬币来支付和汽油. 修复:
- 先拆分气体— 创建单独的汽油币:
const [gasCoin] = tx.splitCoins(tx.object(primaryCoinId), [tx.pure(10_000_000)]);
tx.setGasPayment([gasCoin]);
- 然后拆分付款— 使用剩余余额支付 NFT.
关键规则: ✔ 每枚硬币只能使用每笔交易一次.
**备选方案:**使用两个不同的硬币(如果有).
*(Sui 需要不同的硬币作为汽油和付款,以避免冲突. ) *
之所以发生错误,是因为你试图使用同一个硬币对象来做两件不同的事情:拆分付款和支付汽油费. 系统认为这是在单个事务中尝试两次可变地使用一个对象,这是不允许的.
你需要一枚单独的硬币来支付汽油费. 以下是解决方法:
-
gasPayment
**使用其他汽油币:**在钱包的SUI硬币清单中查找其他硬币,将其指定为.不要使用primaryCoin
你正在拆分的东西. -
**或者,先合并硬币:**如果您只有一枚硬币,则可能需要先将一些较小的硬币合并到其中,以创建单独的汽油币. 然后使用一个进行分割/支付,另一个用于汽油.
关键是您使用的硬币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.