You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分Coin转账Sui?解决函数返回前Coin未消耗编译错误

修复Sui Move合约中Coin未完全消费的错误

错误原因

Coin<SUI>类型不具备drop能力,Move语言强制要求这类无drop能力的对象在函数执行结束时必须被完全消费——要么转移给其他地址,要么销毁(仅零余额可销毁),不能留存在函数参数中。你的代码在两次调用coin::split后,原coin变量仍有未分配的余额,因此触发编译器报错。

修复方案

最合理的做法是将拆分后剩余的Coin转回给交易发起者(sender),在函数末尾添加转移剩余Coin的逻辑:

public entry fun purchase_nft(
        marketplace: &mut Marketplace,
        item_id: ID,
        coin: Coin<SUI>,
        ctx: &mut TxContext
    ) {
        let sender = tx_context::sender(ctx);
        let listing = dynamic_object_field::borrow_mut<ID, List<BidData>>(&mut marketplace.id, item_id);

        let pay_amount = option::extract(&mut listing.bid_data).highest_price;
        let owner_cut = pay_amount * marketplace.owner_cut / 10000;
        
        let owner_cut_coin = coin::split(&mut coin, owner_cut, ctx);
        let pay_coin = coin::split(&mut coin, pay_amount - owner_cut, ctx);

        transfer::transfer(owner_cut_coin, marketplace.owner);
        transfer::transfer(pay_coin, listing.seller);

        transfer::transfer(listing.token, option::extract(&mut listing.bid_data).highest_bidder);
        
        // 将剩余的Coin转回给交易发起者
        transfer::transfer(coin, sender);
    }

补充说明

如果业务逻辑要求用户必须传入恰好等于pay_amount的Coin,也可以在拆分后检查剩余余额是否为零,然后销毁零余额Coin:

// 确保剩余余额为0,否则触发错误
assert!(coin::value(&coin) == 0, E_INVALID_AMOUNT);
coin::destroy_zero(coin);

但这种方式灵活性较低,用户必须精确转款,不如转回剩余金额的体验友好。

内容的提问来源于stack exchange,提问作者marethyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:23:16