Launchpad模块开发问题:转移TreasuryCap时触发警告
问题
开发Launchpad模块核心功能时,要求用户调用create_coin函数时创建参数硬编码的Coin,并将其所有权转移给调用者。但执行treasury(即TreasuryCap)的public_transfer操作时收到警告,怀疑问题出在public struct COIN has drop {},但找不到具体原因,请求帮助。
代码如下:
module launchpad::coin_factory_better { use sui::coin::{Self, TreasuryCap}; public struct COIN has drop {} public fun create_coin(ctx: &mut TxContext) { let (treasury, metadata) = coin::create_currency(COIN {}, 6, b"ROTT", b"", b"", option::none(), ctx); transfer::public_freeze_object(metadata); transfer::public_transfer(treasury, ctx.sender()); } ...... }
警告信息(翻译后):
将对象转移到交易发送者地址 launchpad.move(11, 14): 从函数返回对象,允许调用者使用该对象并通过可编程事务实现组合性。 launchpad.move(14, 40): 交易发送者地址来源于此处 public fun sui::transfer::public_transfer<T>(obj: T, recipient: address) 将obj的所有权转移给recipient。obj必须具有key属性(这反过来确保obj具有全局唯一ID)。请注意,如果recipient地址代表对象ID,发送的obj在转移后将无法访问(不过一旦添加新功能,它们将在未来可检索)。对象必须具有store才能转移到其模块之外。
解决方案
1. 修正COIN结构体的能力定义
你定义的COIN结构体只带drop能力,不符合Sui货币类型的规范:
- 代币需要被存储、转移,必须具备
store能力; - 代币不能被随意丢弃(否则会破坏供应量准确性),不需要
drop能力。
正确定义:
public struct COIN has store {}
2. 处理public_transfer的警告
这个警告是Sui的代码规范提示,不是语法错误,但推荐遵循最佳实践:
- 警告核心是建议返回对象而非直接在函数内转移给发送者,这样能提升函数的组合性,调用者可以在可编程事务中进一步操作
TreasuryCap。 - 修改后的
create_coin函数:
public fun create_coin(ctx: &mut TxContext): TreasuryCap<COIN> { let (treasury, metadata) = coin::create_currency(COIN {}, 6, b"ROTT", b"", b"", option::none(), ctx); transfer::public_freeze_object(metadata); treasury // 返回TreasuryCap,由调用者自行处理转移或后续操作 }
- 如果业务需求必须在函数内直接转移给调用者,也可以忽略此警告,但返回对象的方式更灵活。
3. 澄清你的怀疑点
TreasuryCap本身自带key和store能力,转移操作的合法性没问题,你之前怀疑COIN的属性方向正确,但核心是缺少store能力,而非drop本身的问题。
内容的提问来源于stack exchange,提问作者GustavoGB
相关产品推荐
相关产品推荐

