如何拆分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
相关产品推荐
相关产品推荐

