mcpField
C
composable-move-functions

composable-move-functions

github.com/mystenlabs开发19365 次安装今天更新
代码仓库

关于 composable-move-functions

composable-move-functions 是面向 Sui Move 开发者的参考技能,指导如何设计可在可编程交易块中组合的函数,重点包括可见性、返回对象和参数顺序。

主要功能

  1. 01可组合函数的可见性指引
  2. 02返回对象而非内部转移
  3. 03入口包装函数模式
  4. 04命令行处理返回值
  5. 05统一函数参数顺序

适用场景

  1. 01设计可在 PTB 中链式调用的函数
  2. 02区分可组合逻辑与便捷端点
  3. 03通过 sui client ptb 处理返回对象
  4. 04统一 Move 函数签名

MCP 相关

条件允许时,建议查询 https://sui.mcp.kapa.ai 上的 Sui 文档 MCP 服务,以验证信息并获取最新答案。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mystenlabs/skills --skill composable-move-functions

安装后在 Claude Code 中输入/composable-move-functions确认已加载。

附带文件evals/code-evals.jsonevals/evals.json

详细介绍

composable-move-functions

MCP 工具: 在你的环境中可用时,也请查询 Sui 文档 MCP 服务(https://sui.mcp.kapa.ai)以获取最新答案。使用它来核实信息,并了解这些参考文件未涵盖的细节。

概览

Sui 交易可以在单个可编程交易块(PTB)中串联多个函数调用。在内部转移对象而不是返回对象的函数会破坏这种可组合性。本技能介绍如何设计能够在 PTB 中良好协作的函数。

所有模式均摘自 https://move-book.com/guides/code-quality-checklist

不要使用 public entry

函数应该是 public(可组合,可从其他模块和 PTB 调用)或 entry(仅作为交易端点)。绝不要同时使用 public entry。

// WRONG — public entry is redundant and limits composability
public entry fun do_something() { }

// CORRECT — public for composable functions that return values
public fun mint(ctx: &mut TxContext): NFT { }

// CORRECT — entry for intentionally non-composable endpoints
entry fun mint_and_keep(ctx: &mut TxContext) { }

何时使用 entry: 仅用于有意设计为不可组合的便捷端点——这类函数会包装可组合的 public 函数,并处理向发送者的转移。

返回对象,不要在内部转移

公共函数应将值返回给调用方,而不是将其转移到 ctx.sender()。这样函数就能在 PTB 中组合使用——由调用方决定如何处理结果。

// WRONG — couples minting with transfer, can't compose
public fun mint_and_transfer(ctx: &mut TxContext) {
    let nft = NFT { id: object::new(ctx) };
    transfer::transfer(nft, ctx.sender());
}

// CORRECT — returns the object, caller decides
public fun mint(ctx: &mut TxContext): NFT {
    NFT { id: object::new(ctx) }
}

// If you need a convenience entry point, add a separate entry wrapper:
entry fun mint_and_keep(ctx: &mut TxContext) {
    let nft = mint(ctx);
    transfer::transfer(nft, ctx.sender());
}
返回值对 CLI 的影响

返回非 drop 值的函数无法通过 sui client call 调用——CLI 无法处理返回值,因此会导致 UnusedValueWithoutDrop 错误。请改用 sui client ptb,你可以在其中串联 --assign 和 --transfer-objects 来处理返回值:

sui client ptb \
  --move-call @pkg::module::create_thing --assign thing \
  --transfer-objects "[thing]" @sender

如果函数经常通过 CLI 调用,可以考虑提供一个配套的 entry 包装函数,在内部进行转移(如上所示)。

这普遍适用:

  • add_liquidity 应返回 LP 币和剩余币,而不是转移它们
  • remove_liquidity 应返回两种币,而不是转移它们
  • swap 应返回输出币,而不是转移它
  • borrow 应返回借入的资产,而不是转移它

参数顺序

函数参数必须严格按照以下顺序排列:

  1. 对象优先——被操作的主要对象
  2. 能力对象其次——例如 AdminCap 这样的授权令牌
  3. 基本类型值——数量、标志、地址
  4. Clock——始终放在末尾(ctx 之前),是对象优先规则的例外
  5. ctx: &mut TxContext 最后——始终是最后一个参数,排在所有基本类型值和其他参数之后
// WRONG — cap before object, primitives mixed in
public fun authorize_action(
    cap: &AdminCap,
    value: u8,
    app: &mut App,
    ctx: &mut TxContext,
) { }

// CORRECT — object first, cap second, primitives third, ctx last
public fun authorize_action(
    app: &mut App,
    cap: &AdminCap,
    value: u8,
    ctx: &mut TxContext,
) { }
Clock 例外

尽管 Clock 是一个对象,但它应放在靠近末尾的位置,也就是 ctx 之前:

public fun timed_action(
    app: &mut App,
    cap: &AppCap,
    value: u8,
    clock: &Clock,
    ctx: &mut TxContext,
) { }

快速参考

模式规则
可见性可组合函数使用 public,端点使用 entry。绝不要使用 public entry。
返回值公共函数应返回对象。不要在内部将对象转移给发送者。
Entry 包装函数使用单独的 entry 函数调用 public 函数并进行转移。
参数顺序对象 → 能力对象 → 基本类型值 → Clock → TxContext

评论

支持 Markdown