composable-move-functions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesecomposable-move-functions
可组合的Move函数
MCP tool: When available in your environment, also query the Sui documentation MCP server () for up-to-date answers. Use it for verification and for details not covered by these reference files.https://sui.mcp.kapa.ai
MCP工具: 如果你的环境中提供了该工具,也可以查询Sui文档MCP服务器()获取最新答案。可用于验证以及获取这些参考文件未涵盖的细节。https://sui.mcp.kapa.ai
Overview
概述
Sui transactions can chain multiple function calls in a single Programmable Transaction Block (PTB). Functions that transfer objects internally instead of returning them break this composability. This skill covers how to design functions that work well in PTBs.
All patterns sourced from https://move-book.com/guides/code-quality-checklist
Sui交易可以在单个可编程交易块(PTB)中链式调用多个函数。那些在内部转移对象而非返回对象的函数会破坏这种可组合性。本技能介绍如何设计能在PTB中良好运行的函数。
No public entry
public entry禁止使用public entry
public entryFunctions should be either (composable, can be called from other modules and PTBs) or (transaction endpoint only). Never use together.
publicentrypublic entrymove
// 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) { }When to use : Only for convenience endpoints that are intentionally non-composable — functions that wrap a composable function and handle transfers to sender.
entrypublic函数应要么为(可组合,可从其他模块和PTB中调用),要么为(仅作为交易端点)。切勿同时使用。
publicentrypublic entrymove
// 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) { }何时使用: 仅用于特意设计为不可组合的便捷端点——即包装可组合函数并处理向发送者转移对象的函数。
entrypublicReturn Objects, Don't Transfer Internally
返回对象,而非在内部转移
Public functions should return values to the caller rather than transferring them to . This makes them composable in PTBs — the caller decides what to do with the result.
ctx.sender()move
// 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());
}公共函数应将值返回给调用者,而非转移到。这样它们在PTB中具备可组合性——由调用者决定如何处理结果。
ctx.sender()move
// 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 implication for returned values
返回值对CLI的影响
Functions that return non- values cannot be invoked via — the CLI has no way to consume the returned value, causing an error. Use instead, where you can chain and to handle the return value:
dropsui client callUnusedValueWithoutDropsui client ptb--assign--transfer-objectsbash
sui client ptb \
--move-call @pkg::module::create_thing --assign thing \
--transfer-objects "[thing]" @senderIf the function is called frequently from the CLI, consider providing a companion wrapper that transfers internally (as shown above).
entryThis applies broadly:
- should return LP coins and remainder coins, not transfer them
add_liquidity - should return both coins, not transfer them
remove_liquidity - should return the output coin, not transfer it
swap - should return the borrowed asset, not transfer it
borrow
返回非类型值的函数无法通过调用——CLI无法处理未使用的返回值,会导致错误。应改用,你可以通过链式使用和来处理返回值:
dropsui client callUnusedValueWithoutDropsui client ptb--assign--transfer-objectsbash
sui client ptb \
--move-call @pkg::module::create_thing --assign thing \
--transfer-objects "[thing]" @sender如果该函数经常从CLI调用,可考虑提供一个在内部处理转移的配套包装函数(如上文所示)。
entry这一原则广泛适用:
- 应返回LP代币和剩余代币,而非直接转移
add_liquidity - 应返回两种代币,而非直接转移
remove_liquidity - 应返回输出代币,而非直接转移
swap - 应返回借入资产,而非直接转移
borrow
Parameter Ordering
参数排序
Function parameters follow a strict order:
- Objects first — the primary object being acted on
- Capabilities second — authorization tokens like
AdminCap - Primitive values — amounts, flags, addresses
- Clock — always at the end (before ctx), exception to objects-first rule
- last — ALWAYS the final parameter, after all primitives and all other arguments
ctx: &mut TxContext
move
// 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,
) { }函数参数遵循严格的顺序:
- 对象优先 —— 要操作的主要对象
- 能力其次 —— 如这类授权令牌
AdminCap - 原始值 —— 数量、标志、地址
- Clock —— 始终放在末尾(ctx之前),是对象优先规则的例外
- 最后 —— 始终是最后一个参数,在所有原始值和其他参数之后
ctx: &mut TxContext
move
// 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 Exception
Clock例外情况
Clockctxmove
public fun timed_action(
app: &mut App,
cap: &AppCap,
value: u8,
clock: &Clock,
ctx: &mut TxContext,
) { }Clockctxmove
public fun timed_action(
app: &mut App,
cap: &AppCap,
value: u8,
clock: &Clock,
ctx: &mut TxContext,
) { }Quick Reference
快速参考
| Pattern | Rule |
|---|---|
| Visibility | |
| Returns | Public functions return objects. Don't transfer to sender internally. |
| Entry wrappers | Separate |
| Param order | Object → Capability → Primitives → Clock → TxContext |
| 模式 | 规则 |
|---|---|
| 可见性 | |
| 返回值 | 公共函数返回对象。不要在内部向发送者转移对象。 |
| Entry包装函数 | 单独的 |
| 参数顺序 | 对象 → 能力 → 原始值 → Clock → TxContext |