Sui.

Bài viết

Chia sẻ kiến thức của bạn.

Tiền thưởng+15

Bolke .
Aug 12, 2025
Hỏi đáp Chuyên Gia

Lỗi Sui Move - Không thể xử lý giao dịch Không tìm thấy đồng xu gas hợp lệ cho giao dịch

Khi tôi làm điều này:

//Chia thanh toán từ đồng tiền chính const [PaymentCoin] = TX.SplitCoins ( tx.object (primarycoin.coinObjectID), [tx.pure.u64 (Mức thanh toán bắt buộc)] );

//Sử dụng đồng tiền gốc để thanh toán gas tx.setGasPayment ([{ ObjectID: primarycoin.coinObjectID, phiên bản: PrimaryCoin.version, bản tóm tắt: PrimaryCoin.Digest }]);

tx.setgasBudget (10_000_000); Nó phàn nàn về các đối tượng có thể đột biến không thể xuất hiện nhiều hơn một trong một giao dịch. Khi tôi xóa thanh toán gas, nó phàn nàn “Không thể xử lý giao dịch Không tìm thấy đồng xu gas hợp lệ cho giao dịch.”. Chức năng hợp đồng của tôi chấp nhận .01 sui để đổi lấy NFT

  • Sui
  • Transaction Processing
  • Move
0
5
Chia sẻ
Bình luận
.

Câu trả lời

5
MiniBob.
Aug 12 2025, 19:33

Điều này xảy ra bởi vì bạn đang cố gắng sử dụng cùng một đối tượng coin (primaryCoin) cả làm thanh toán gas và đầu vàosplitCoins, điều này làm cho nó trở thành một tham chiếu có thể thay đổi được sử dụng trong hai bối cảnh khác nhau - và Sui không cho phép điều đó vì tính an toàn và logic tuyến tính (vì tiền xu là đối tượng tuyến tính).

Cách IMHO là hoàn toàn không đặt thanh toán gas theo cách thủ công. Chỉ cần để ví Sui/khách hàng tự động chọn một đồng xu gas thích hợp. Chỉ sử dụng setGasPaymentnếu bạn thực sự cần xác định đồng tiền nào trả tiền cho gas (ví dụ: ví đa coin, quản lý gas cụ thể). Nếu không, tránh nó.

Hãy thử như sau:

// 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 sẽ:

  • Tự động chọn một đồng xu gas (có thể là cùng một hoặc một đồng SUI khác trong ví).
  • Xử lý an splitCoinstoàn.
  • Sử dụngđồng tiền khác(hoặc đôi khi cùng một đồng tiền, nhưng được xử lý an toàn dưới mui xe thông qua phiên bản đối tượng thích hợp).

Quan trọng: Miễn là ví của bạn có ít nhất 1 $SUI có thể trang trải gas, điều này sẽ hoạt động.

0
Bình luận
.
0xduckmove.
Aug 13 2025, 03:14

Bạn đang gặp phải một ràng buộc thiết kế giao dịch Sui Move phổ biến** cùng một đối tượng coin không thể được sử dụng làm đầu vào có thể thay đổi (ví dụ: để tách hoặc chuyển) và làm đồng xu gas trong một giao dịch duy nhất.**

Tại sao điều này xảy ra

  • Khi bạn sử dụng TX.SplitCoins (tx.object (PrimaryCoin.CoinObjectID),...), bạn đang đánh dấu PrimaryCoin là một đầu vào có thể thay đổi.
  • Khi bạn cũng đặt nó làm đồng xu gas với tx.setGasPayment (...), Sui sẽ thấy cùng một đối tượng được sử dụng trong hai vai trò, điều này không được phép.
  • Nếu bạn xóa thanh toán gas, Sui không thể tìm thấy đồng xu gas hợp lệ, do đó có lỗi “Không tìm thấy đồng xu gas hợp lệ cho giao dịch”.

Từ ngữ cảnh:

Trạng thái hiệu ứng giao dịch: Sử dụng giá trị không hợp lệ. Các giá trị vay mượn có thể thay đổi đòi hỏi cách sử dụng duy nhất. Các giá trị mượn bất biến không thể được lấy hoặc mượn một cách đột biến. Các giá trị đã lấy không thể được sử dụng lại. (nguồn)

Cách khắc phục

Bạn phải sử dụng một đồng tiền khác để lấy gas so với đồng tiền bạn đang chia hoặc chuyển.

Giải pháp: Có ít nhất hai đồng SUI trong ví của bạn. Sử dụng một cái để thanh toán (tắt/chuyển nhượng) và một cái khác cho gas.

Lưu lượng ví dụ

  1. Chọn hai đồng xu:
  • PrimaryCoin (để thanh toán)
  • GasCoin (đối với gas)
  1. Chia và thanh toán bằng PrimaryCoin:
const [paymentCoin] = tx.splitCoins(
    tx.object(primaryCoin.coinObjectId),
    [tx.pure.u64(requiredPaymentAmount)]
);
  1. Đặt thanh toán gas với GasCoin:
tx.setGasPayment([{
    objectId: gasCoin.coinObjectId,
    version: gasCoin.version,
    digest: gasCoin.digest
}]);
tx.setGasBudget(10_000_000);

Không sử dụng cùng một đối tượng tiền xu cho cả thanh toán và gas.

Tài liệu tham khảo của tôi

Sui Move: Việc lấy đồng xu Gas không hợp lệ. Nó chỉ có thể được sử dụng theo giá trị với TransferObjects

0
Bình luận
.
Owen.
Owen4587
Aug 13 2025, 06:10

Lỗi xảy ra do bạn đang cố gắng sử dụngđối tượng ban đầ primaryCoinu(được tiêu thụ trong quá trình splitCoinshoạt động) làm thanh toán gas. Sau khi tách, phiên bản/bản tổng hợp của đồng tiền gốc trở nên không hợp lệ, gây ra lỗi “các đối tượng có thể thay đổi không thể xuất hiện nhiều hơn một” khi được tham chiếu lại.

Để khắc phục, đừng đặt thủ công thanh toán gas bằng cách sử dụng primaryCoinđối tượng chia trước. Và đảm bảo bạn primaryCoincó đủ số dư để trang trải cả hai:

  • Số tiền thanh toán (requiredPaymentAmount= 0.01 SUI)
  • Ngân sách khí đốt (10_000_000= 0,01 SUI) → Tổng số cần thiết:** ≥ 0,02 SUI**

Chỉ cần thử

// 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
Bình luận
.
Paul.
Paul4180
Aug 13 2025, 08:48

Vấn đề

Bạn đang gặp phải hai vấn đề chính:

1.Lỗi khả năng thay đổi: Cố gắng sử dụng cùng một đối tượng đồng xu cho cả thanh toán gas và đầu vào giao dịch dẫn đến lỗi: “Các đối tượng có thể thay đổi không thể xuất hiện nhiều hơn một lần trong một giao dịch.”

2.** Thiếu đồng xu gas**: Nếu không có đồng xu gas hợp lệ, lỗi “Không thể xử lý giao dịch: Không tìm thấy đồng xu gas hợp lệ cho giao dịch” xảy ra.


Giải pháp

Để giải quyết các vấn đề này:

1.** Chia đồng tiền chính để thanh toán**: Sử dụng tx.splitCoinsđể tạo một đồng tiền mới cho giao dịch mua NFT, đảm bảo nó tách biệt với khoản thanh toán gas.

  1. tx.setGasPaymentĐặt một đồng tiền khí riêng biệt: Chỉ định một đồng tiền khác để thanh toán gas bằng cách sử dụng.

  2. tx.setGasBudgetXác định ngân sách khí: Đặt ngân sách khí thích hợp bằng cách sử dụng.


// 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
Bình luận
.
casey.
Aug 14 2025, 03:40

TrênSui, một đối tượng đồng xu duy nhất có thể thay đổi (số dư của nó thay đổi khi bạn sử dụng nó) và bạn không thể tham chiếu cùng một đối tượng có thể thay đổi hai lần trong một giao dịch - đó là lý do tại sao:

Bạn đang tách khỏi cùng một PrimaryCoin

Và cũng sử dụng nó như thanh toán gas

→ Trình tạo giao dịch đánh dấu điều này là “đối tượng có thể thay đổi xuất hiện nhiều hơn một lần”.

Tại sao “Không tìm thấy đồng xu gas hợp lệ” xảy ra khi bạn xóa SetGasPayment

Khi bạn không chỉ định một đồng xu gas, Sui SDK sẽ tự động chọn một đồng xu gas từ các đồng tiền sở hữu của bạn mà chưa được sử dụng trong giao dịch. Nhưng vì giao dịch của bạn đã tiêu thụ đồng xu duy nhất bạn có (thông qua SplitCoins), không còn tiền xu nào để thanh toán gas.

Cách khắc phục:

Bạn cần hai đối tượng tiền xu riêng biệt:

Coin A→ chỉ được sử dụng cho gas

Coin B→ chia cho thanh toán.01 SUI của bạn

Nếu bạn chỉ có một đồng xu trong ví của mình, trước tiên bạn phải chia nó thành hai đối tượng coin riêng biệt trong một giao dịch sơ bộ.**

Chìa khóa là:

  • Sui ngăn không cho một đối tượng đồng xu đơn lẻ trở thành cả gas và đầu vào có thể thay đổi trong cùng một giao dịch vì nó được coi là cùng một tham chiếu có thể thay đổi.
  • Nhưng trong Move, bạn có thể nhận được một đồng xu để thanh toán mà không cần quan tâm nó đến từ đối tượng nào - bao gồm cả một đồng đã được tách ra từ đồng xu gas trước đó trong cùng một giao dịch.

Điều đó có nghĩa là chức năng Move của bạn chỉ nên chấp nhận đồng tiền thanh toán, không phải đồng tiền gốc và bạn để trình tạo giao dịch xử lý việc tách nó trước khi chuyển nó vào.

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>,
    }
}

Cách giải quyết vấn đề

Khi khách hàng xây dựng giao dịch:

1. Gas coin (tx.gas) được tự động sử dụng cho gas.

2. Tách khỏi gas để nhận PaymentCoin mới:

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 cho phép điều này bởi vì:

  • tx.gaslà đối tượngthanh toán gas. -Đầu ra phân tách (paymentCoin) là mộtđối tượng mới.
  • Bây giờ chúng là** các đối tượng có thể thay đổi riêng biệt** trong** giao dịch**.

✅ Lợi ích: Bạn không còn cần ví để giữ hai đối tượng tiền xu riêng biệt trước - chức năng Move chỉ quan tâm đến đồng tiền thanh toán và khách hàng luôn có thể tách nó ra khỏi đồng xu gas trước khi gọi.

0
Bình luận
.

Bạn có biết câu trả lời không?

Hãy đăng nhập và chia sẻ nó.