关于 ptbs
ptbs 是用于讲解和构建 Sui 可编程交易块的技能,按主题提供交易概念、命令、TypeScript 构建、命令行操作和故障排查参考。
主要功能
- 01PTB 概念与执行规则
- 02七种 PTB 命令参考
- 03TypeScript Transaction 构建
- 04通过命令行构建 PTB
- 05常见错误排查
适用场景
- 01解释 PTB 输入、结果链式传递或原子性
- 02使用 TypeScript SDK 构建交易
- 03使用 sui client ptb 创建 PTB
- 04诊断交易错误
MCP 相关
该技能建议通过 https://sui.mcp.kapa.ai 查询 Sui 文档 MCP 服务,以核实信息并获取最新详情。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mystenlabs/ skills --skill ptbs安装后在 Claude Code 中输入/ptbs确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
building.mdcli.mdcommands.mdfundamentals.mdtroubleshooting.mdevals/code-evals.jsonevals.json详细介绍
Sui 可编程交易块(PTB)
MCP 工具: 如果你的环境支持,也请查询 Sui 文档 MCP 服务(
https://sui.mcp.kapa.ai),获取最新答案。请将其用于核验,以及查找这些参考文件中未涵盖的详细信息。
PTB 是一笔 Sui 交易,可批量执行最多 1,024 条命令——Move 调用、拆分/合并代币、转移对象、构造向量、发布/升级包——这些命令按顺序执行,具有原子性(一条命令失败 ⇒ 整个交易块失败),并共享输入、串联结果。PTB 是在 Sui 上执行交易的唯一方式;没有“单次调用”模式。
此技能会引导你查看专门的参考文件。仅加载与当前任务相关的文件。
此技能中的所有模式均源自:
- https://docs.sui.io/concepts/transactions/prog-txn-blocks
- https://docs.sui.io/develop/transactions/ptbs/building-ptb
- https://docs.sui.io/references/ptb-commands
- https://sdk.mystenlabs.com/sui/transactions/basics
- https://docs.sui.io/references/cli/client(CLI
sui client ptb)
如果不确定某个 API、方法签名或错误消息,请在回答前获取相关页面。不要根据 Ethereum、Solana 或其他链的经验猜测或推断——PTB 没有直接对应的概念。
参考文件
fundamentals — PTB 数据模型
路径: fundamentals.md
适用场景: 解释 PTB 的定义,讨论 Input、Argument、NestedResult、GasCoin、自有对象与共享对象、不可变对象及接收对象引用、纯输入的 BCS 规则、命令串联语义,或执行顺序/原子性。
涵盖内容: PTB 结构、Input(CallArg)和 ObjectArg 变体、纯输入类型、Argument 枚举、结果串联、执行语义(借用规则、移动/复制、热土豆团、交易结束约束)、协议限制。
commands — 命令参考
路径: commands.md
适用场景: 编写或审查任何特定命令——MoveCall、SplitCoins、MergeCoins、TransferObjects、MakeMoveVec、Publish、Upgrade——或调试参数类型不匹配和返回值结构。
涵盖内容: 七种命令各自的签名、参数规则、返回值结构和常见陷阱。
building — TypeScript SDK Transaction 类
路径: building.md
适用场景: 编写使用 @mysten/sui/transactions 构造 PTB 的 TS/JS 代码、配置 gas、为钱包构建交易、跨服务序列化,或在应用 ↔ 钱包 ↔ 赞助方之间传递 PTB。
涵盖内容: Transaction API(tx.moveCall、tx.splitCoins、tx.mergeCoins、tx.transferObjects、tx.makeMoveVec、tx.publish、tx.upgrade、tx.balance、tx.coin、tx.add、tx.object、tx.pure、tx.gas、tx.setSender/setGasPrice/setGasBudget/setGasPayment/setGasOwner)、Inputs.*Ref 辅助方法、结果解构、build({ onlyTransactionKind: true })、Transaction.from / fromKind、赞助交易流程、签名与执行。
cli — 从 CLI 构建 PTB
路径: cli.md
适用场景: 使用 sui client ptb 从命令行构造 PTB、不使用 TypeScript 编写交易脚本、从 CLI 合并代币,或讲解基于 CLI 的工作流。
涵盖内容: sui client ptb 语法、命令串联、常见 CLI PTB 模式(转账、合并代币、Move 调用)、gas 预算、执行前预览。
troubleshooting — 常见错误
路径: troubleshooting.md
适用场景: 诊断失败的 PTB——任何 ServerError、UnusedValueWithoutDrop、VMVerificationOrDeserializationError、No valid gas coins、InsufficientGas、共享对象拥堵,或含糊的“交易失败”输出。
涵盖内容: 每种错误类别的 Move/PTB 层面原因和具体修复方法。
路由指南
| 任务 | 加载 |
|---|---|
| “什么是 PTB?”/概念说明 | fundamentals |
| 使用 TypeScript 编写新的 PTB | building + commands |
| 从 CLI 编写新的 PTB | cli + commands |
| 检查 PTB 是否正确 | fundamentals + commands + building |
| 特定命令未通过类型检查 | commands |
| 赞助交易/免 Gas 交易 | building |
| 调试失败的 PTB | troubleshooting +(如果与执行语义有关,则加上 fundamentals) |
| 在 PTB 中发布或升级软件包 | commands |
| 跨服务(应用/钱包/赞助方)构建 PTB 字节 | building |
| 从 CLI 合并代币或执行简单操作 | cli |
| 全面代码审查 | 所有参考文件 |
技能内容
核心概念
- PTB 就是交易。 每笔 Sui 交易都是 PTB——即使只有一个
moveCall,它也是一个单命令 PTB。不存在非 PTB 的执行路径。 - 输入与命令。
inputs是从外部传入的值(对象和经 BCS 编码的“纯”字节)。commands会对这些输入以及彼此的结果进行操作。命令通过Argument枚举引用值:Input(i)、GasCoin、Result(i)、NestedResult(cmd, result)。 - 链式调用。 每个命令都会产生一个结果数组。下一个命令可以使用任意结果(通过
NestedResult(cmd, idx),或在命令恰好只有一个返回值时通过Result(cmd))。TS SDK 将其呈现为可解构的值:const [coin] = tx.splitCoins(tx.gas, [tx.pure.u64(100)]);。 - 原子性。 命令按顺序执行。任何失败都会回滚整个代码块;不会产生部分效果。
- 交易结束时的约束。 执行期间产生的每个非
drop值都必须被使用(转移、销毁或传入另一个命令)。共享对象只有两种合法的结束方式:重新共享或删除——不能转移或冻结。Gas 代币会返还给其所有者,并退还未使用的 Gas。
规则
- 除在
transferObjects中使用外,必须通过引用使用tx.gas。 若要从 Gas 代币获取自有的Coin<SUI>,请先使用SplitCoins(tx.gas, [amount])。 - 尽可能让钱包处理 Gas 配置。 不要在将由用户钱包签名的应用代码中硬编码
setGasBudget/setGasPrice/setGasPayment——钱包会正确地进行干运行并选择代币。仅在后端签名流程中设置这些参数。 - 在将 PTB 交给钱包的应用代码中,使用
await tx.toJSON()(而不是tx.build())。 钱包必须自行处理 Gas 逻辑和代币选择;在应用代码中构建字节会抢先完成这些工作。 - 赞助流程使用
Transaction.fromKind(kindBytes)。 在应用中通过tx.build({ client, onlyTransactionKind: true })进行构建,将仅包含交易类型的字节发送给赞助服务,在赞助服务处使用fromKind重新还原,然后调用setSender、setGasOwner、setGasPayment。用户(或任意一方)应直接向完整节点提交完整签名的交易,而不是经由赞助服务提交,以避免审查。 - 每个非
drop值都必须被使用。 如果moveCall返回了不需要的值,请将其传入transferObjects(如果它具有key + store)、public_transfer或析构函数。UnusedValueWithoutDrop是 PTB 级别的错误。 - 如果共享对象以只读方式传入(
mutable: false),则不能转移、冻结或按值使用。 如果需要可变访问,请在构建输入时将其标记为可变。 - 来自 Move 调用的类型不能是引用。
MoveCall的结果是值;如果 Move 函数返回&T,则不能从 PTB 调用该函数。 - 对于返回多个值的 Move 调用,请使用解构或数组索引。
const [a, b] = tx.moveCall(...)或const r = tx.moveCall(...); r[0]; r[1];。不要假设只有一个返回值。 - 不确定时请引用文档。 以上是规范来源。旧版
/develop/transactions/ptbs/*URL 仍可访问,但优先使用/concepts/transactions/prog-txn-blocks和/guides/developer/sui-101/building-ptb。
常见错误
- 调用
tx.pure(value)时未指定类型。 未指定类型的 pure 值会在解析输入时失败。请使用带类型的辅助方法:tx.pure.u64(n)、tx.pure.address(addr)、tx.pure.string(s),或通用形式tx.pure('u64', n)。 - 在
moveCall参数中传入字符串形式的对象 ID,却未使用tx.object(...)。 混合类型参数需要显式使用tx.object(id)封装,否则 SDK 无法区分纯值和对象。 - 转移或冻结共享对象。 共享对象不能转移或冻结,但可以删除。PTB 中共享对象只有两种合法的结束方式:重新共享或删除。请勿将共享对象包含在
transferObjects中。请注意,按值消耗共享对象会永久将其 hot-potato 团簇标记为“hot”,从而阻止该团簇中任何关联值后续调用非公开的entry函数。 - 离线构建时忘记调用
setSender。 如果调用tx.build()时没有通过会设置发送方的签名器进行签名,发送方字段将保持为空,导致构建失败。 - 将返回多个值的
moveCall结果当作单个值处理。 返回值是一个向量;请按索引访问或解构。 - 在 PTB 中对泛型类型使用
transfer::transfer/transfer::share_object。 这些入口要求类型参数在模块内私有。在 PTB 中,请使用transfer::public_transfer/transfer::public_share_object,它们要求类型具有store。 - 将 gas 预算设得过低。 超出预算的交易会中止,但仍会扣除 gas 币。建议使用 SDK 基于模拟运行的自动预算。
- 未检查执行状态。 交易可能已被验证者接受,但在 Move 层面执行失败(断言失败、gas 耗尽等)。在将操作视为成功之前,务必检查
result.$kind !== 'FailedTransaction'。仅有交易摘要并不意味着效果已应用。 - 在应用代码中循环提交 N 笔单独的交易。 请将它们批量合并到一个 PTB 中(最多 1,024 个操作)。一个 PTB 成本更低且具有原子性。