Sui命令行界面(CLI)中的新命令允许用户直接从终端或Bash脚本创建和执行可编程交易区块(PTB)。这个新命令为开发人员在实现和执行PTB方面提供了更大的灵活性。
PTB为开发人员提供了一种非常强大的编程工具,这在其他区块链上不可用。将多个交易链接在一起形成单个可执行文件的能力在更广泛的软件工程世界中可能被视为理所当然,但在区块链上却代表了一个根本性的飞跃。
以往,只能使用可用的SDK之一来处理 PTB。现在,偏爱通过终端和编写脚本工作的开发人员有了使用这一强大功能的新途径。
查看Sui CLI PTB命令文档以获取详细信息和示例。
下面的示例显示了创建简单PTB所需的命令。它创建了三个新币,其价值分别为1000、2000和3000MIST,来自gas币,并将它们转移到地址:0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd9d636e7895dcfc8de05f331(注意地址前面的@符号,表示这是一个地址,而不是十六进制)。
sui client ptb \
--assign to_address @0x02a212de6a9dfa3a69e22387acfbafbb1a9e591bd \
--split-coins gas [1000,2000,3000] \
--assign coins \
--transfer-objects to_address [coins.0, coins.1, coins.2] \
--gas-budget 5000000 \
--summary
以下是结果消息:
╭──────────────────────────────────────────────────────╮
│ PTB Execution Summary │
├──────────────────────────────────────────────────────┤
│ Digest: 7S7XpkGns8mQ4mBUzjdM32xqNHGF2P1ErHSLbb4Chn2j │
│ Status: success │
│ Gas Cost Summary: │
│ Storage Cost: 3952000 │
│ Computation Cost: 1000000 │
│ Storage Rebate: 978120 │
│ Non-refundable Storage Fee: 9880 │
╰──────────────────────────────────────────────────────╯
Sui CLI PTB
CLI PTB支持的主要理念是让开发人员能够从命令行构建和执行PTB。您也可以编写Bash脚本来构建和执行PTB,就像您从命令行中所做的那样,这在自动化不同任务时提供了很大的灵活性。
sui client ptb命令接受以下选项:
sui client ptb -h
Build, preview, and execute programmable transaction blocks. Depending on your shell, you might have to use quotes around arrays or other passed values. Use --help to see examples for how to use the core functionality of this command.
Usage: sui client ptb [OPTIONS]
Options:
--assign <NAME> <VALUE> Assign a value to a variable name to use later in the PTB.
--gas-coin <ID> The object ID of the gas coin to use. If not specified, it will try to use the first gas coin that it finds that has at least
the requested gas-budget balance.
--gas-budget <MIST> The gas budget for the transaction, in MIST.
--make-move-vec <TYPE> <[VALUES]> Given n-values of the same type, it constructs a vector. For non objects or an empty vector, the type tag must be specified.
--merge-coins <INTO_COIN> <[COIN OBJECTS]> Merge N coins into the provided coin.
--move-call <PACKAGE::MODULE::FUNCTION> <TYPE> <FUNCTION_ARGS> Make a move call to a function.
--split-coins <COIN> <[AMOUNT]> Split the coin into N coins as per the given array of amounts.
--transfer-objects <[OBJECTS]> <TO> Transfer objects to the specified address.
--publish <MOVE_PACKAGE_PATH> Publish the Move package. It takes as input the folder where the package exists.
--upgrade <MOVE_PACKAGE_PATH> Upgrade the move package. It takes as input the folder where the package exists.
--preview Preview the list of PTB transactions instead of executing them.
--summary Show only a short summary (digest, execution status, gas cost). Do not use this flag when you need all the transaction data
and the execution effects.
--warn-shadows Enable shadow warning when the same variable name is declared multiple times. Off by default.
--json Return command outputs in json format.
-h, --help
概念和特性
除了使用现有的传统PTB相关概念外,还需要一些新的概念来支持这个命令。
- 使用 — assign命令重新使用结果或自定义定义的变量。
- 在执行PTB之前预览PTB中的输入命令。
- 在多次声明具有相同标识符的变量时发出警告。
- 受益于对常见包(如sui、std和deepbook)的名称解析(而不是使用它们的地址)。
- 错误消息提供了对PTB语法出错的简明而准确的解释。
- 变量名不能是address、bool、vector、some、none、gas、u8、u16、u32、u64、u128 或 u256。
示例
让我们通过一些示例来展示Sui CLI PTB工具的强大功能。请注意,这些示例是在Bash中进行测试的,您的情况可能会有所不同,这取决于您的shell以及它如何处理和解析字符串和引号(例如,在zsh或fish中,您可能需要在数组周围使用引号,但在Bash中则不需要)。
嵌套或多类型
当您需要使用嵌套类型时,您可以简单地将所需的类型包装在<and>中。例如,如果参数期望一个 Option<vector<u256>>,您可以写成 std::option::Option<vector<u256>>。
以下是一个例子:
sui client ptb
--make-move-vec "<std::option::Option<vector<u256>>>" "[vector[]]" \
--gas-budget 5000000
如果您需要为调用传递多个类型,可以在类型之间使用逗号,例如<u64,u8,bool,string>。
域名解析
CLI PTB使用域名解析来识别常见包如sui、std和deepbook,因此您可以直接使用它们,而不是它们的地址:0x2、0x1 或 0xdee9。您仍然可以使用传统的package::module::function方法来调用特定函数。例如,您可以同时使用std::option或0x1::option。
sui client ptb \
--assign A none \
--move-call std::option::is_none "<u64>" A \
--gas-budget 5000000
您还可以通过其别名而不是完整地址来引用本地钱包中的地址。
为变量分配数据
— assign参数将值绑定到变量。您可以以几种方式使用它:
1.将值分配给变量:
sui client ptb \
--assign myvar 100 \
--gas-budget 5000000
2.将变量分配给上一个交易的结果。在以下示例中,split-coins会产生三个新对象,由于使用了 — assign,因此可以通过coins变量访问这些对象。
sui client ptb \
--split-coins gas "[1000,2000,3000]" \
--assign coins \
--gas-budget 5000000
3.将变量分配给另一个变量
sui client ptb \
--assign myvar vector[100, 200] \
--assign my_addr @0x0fe375fff0ee40d20c54a7f2478b9b5c7eaa3625b761 \
--assign old_address my_addr \
--gas-budget 5000000
发布包并调用函数
在Sui仓库中,第一个包示例是一个简单的Move项目。简而言之,该示例发布了该包,创建了一个Forge对象,您可以使用该对象调用new_sword函数创建swords。下面的代码假设您已经设置了Sui测试网环境,并且您的地址有足够的gas。
首先,进入示例文件夹并发布该包。
cd sui/examples/move/first_package
sui client ptb
--move-call sui::tx_context::sender \
--assign "sender" \
--publish "." \
--assign upgrade_cap \
--transfer-objects [upgrade_cap] sender \
--gas-budget 50000000
发布此包会生成以下交易数据:
INCLUDING DEPENDENCY Sui
INCLUDING DEPENDENCY MoveStdlib
BUILDING first_package
Successfully verified dependencies on-chain against source.
╭──────────────────────────────────────────────────────╮
│ PTB Execution Summary │
├──────────────────────────────────────────────────────┤
│ Digest: 8ULSyjJXhX5CPiEge3a7T2kLSA3YA8V44BAGZPdknJ1h │
│ Status: success │
│ Gas Cost Summary: │
│ Storage Cost: 9978800 │
│ Computation Cost: 1000000 │
│ Storage Rebate: 978120 │
│ Non-refundable Storage Fee: 9880 │
╰──────────────────────────────────────────────────────╯
从上一个结果中,我们可以使用digest,并将其传递给sui client tx-digest来查找packageId和Forge对象的objectId。我们想要锻造一个新sword并将其转移到此交易的发送者。
接下来,我们查找我们发布的包中的new_sword函数,以了解我们需要传递给函数的参数。其签名是:
/// Constructor for creating swords
public fun new_sword(
forge: &mut Forge,
magic: u64,
strength: u64,
ctx: &mut TxContext,
): Sword
现在,由于包存在于链上,让我们使用PTB来创建一个sword。首先要做的是使用move-call命令获取发送者的地址,并将该调用的结果分配给sender变量。我们可以使用assign来处理magic和strength参数,并将Forge对象的ID分配给forge_obj变量。
最后,通过move-call命令调用new_sword函数,传递所有正确的函数参数,将move-call的结果分配给sword变量,并将新sword对象转移到发送者。
sui client ptb \
--move-call sui::tx_context::sender \
--assign sender \
--assign magic 10u64 \
--assign strength 50u64 \
--assign forge_obj @0xd5d19fde64ea43876add02efb2a769372869f30118 \
--move-call 0xbe6edeefea02371d35fdde5a45033d8d8e2e00b3eb911b23fa::example::new_sword forge_obj magic strength \
--assign sword \
--transfer-objects "[sword]" sender \
--gas-budget 5000000 \
--summary
因为我们设置了 — summary标志,所以执行结果如下所示:
╭──────────────────────────────────────────────────────╮
│ PTB Execution Summary │
├──────────────────────────────────────────────────────┤
│ Digest: HYqWpN9sYBGLawj4BE9VnRM7qaezUFA8aLrGBbjf72L7 │
│ Status: success │
│ Gas Cost Summary: │
│ Storage Cost: 3739200 │
│ Computation Cost: 1000000 │
│ Storage Rebate: 2309868 │
│ Non-refundable Storage Fee: 23332 │
╰──────────────────────────────────────────────────────╯
在Bash脚本中使用PTB
为了方便自动化和重用,您可以将终端中的PTB命令复制粘贴到Bash脚本中并运行它。
#!/usr/bin/bash
sui client ptb \
--assign to_address @0x02a212de6a9dfa3a69e22387acfbafbb1a9e59
--split-coins gas "[1000,2000,3000]" \
--assign coins \
--transfer-objects "[coins.0, coins.1, coins.2]" to_address \
--gas-budget 5000000
上述代码可以作为普通的 Bash 脚本运行。
在Bash脚本中使用PTB发行100个NFT并转移它们
此示例使用Bash脚本来发行100个NFT并将它们转移到100个地址。NFT在此发布到GitHub的智能合约中进行定义。我们发布了该包,并获取了num_issuer_cap和package ID。项目在module num中定义了mint函数,我们在此声明。
然后脚本从一个文本文件中加载地址,每个地址都在新行上。然后它构建了一个move-call命令字符串,在for循环中调用mint函数并将对象转移到一个地址。最后,执行了PTB。
请注意,作为Bash脚本,您可以像处理其他Bash脚本一样传递环境变量。
num_issuer_cap=0x3e8a046807edd63b75014b9aff0f8dc30b76344a4dfdb1ae4655932e0514086b
package=0x610834b5fa960b297a5caf6af56bcc045d67d158889da5b511a20031307ce099
module=num
fun=mint
echo "Loading addresses from file"
readarray -t addresses < addresses.txt
cmd=""
for address in ${addresses[@]}; do
cmd+="--move-call $package::$module::$fun @$num_issuer_cap --assign X --transfer-objects [X] @$address "
done
echo "Executing PTB"
sui client ptb \
$cmd \
--gas-budget 5000000000 \
--summary
最终结果如下:
bash-5.2$ bash working-demo.sh
Loading addresses from file
Executing PTB
╭──────────────────────────────────────────────────────╮
│ PTB Execution Summary │
├──────────────────────────────────────────────────────┤
│ Digest: 7THBdpRHWSTiWExxSB7A3m9E7PDP9kQaD16N8xXevdcA │
│ Status: success │
│ Gas Cost Summary: │
│ Storage Cost: 132376800 │
│ Computation Cost: 1000000 │
│ Storage Rebate: 2392632 │
│ Non-refundable Storage Fee: 24168 │
╰──────────────────────────────────────────────────────╯
购买SuiNS上的域名
以下示例通过首先创建一个没有SUI的零币来注册一个Sui域名,以供move-call使用,然后将新创建的域名对象转移到特定地址。
sui client ptb \
--assign suins_object_id @0x300369e8909b9a6464da265b9a5a9ab6fe2158a040e84e808628cde7a07ee5a3 \
--split-coins gas "[0]" \
--assign zero_coin \
--move-call 0x4255184a0143c0ce4394a3f16a6f5aa5d64507269e54e51ea396d569fe8f1ba5::register::register suins_object_id '"mysui.sui"' 1u8 zero_coin @0x6 \
--assign suins_name \
--transfer-objects "[suins_name]" @0x0fe375fff0ee40d20c54a7f2478b9b5c7eaa3625b7611f9661ec5faefb4a6fea \
--gas-budget 50000000
这个命令的结果是:
╭──────────────────────────────────────────────────────╮
│ PTB Execution Summary │
├──────────────────────────────────────────────────────┤
│ Digest: 5D2W4beXGWzF4Cn69y6ihnTvoyBC99vb5zGhpxAhdq1z │
│ Status: success │
│ Gas Cost Summary: │
│ Storage Cost: 10039600 │
│ Computation Cost: 1000000 │
│ Storage Rebate: 5394708 │
│ Non-refundable Storage Fee: 54492 │
╰──────────────────────────────────────────────────────╯
预览而不是执行PTB
— preview标志对于复杂的PTB很有用,它列出PTB中的交易而不是执行它。预览显示了在解析整个输入后的每个交易及其参数的格式良好的表格。它还显示了任何错误。这在处理复杂的PTB时很有帮助,因为它会生成交易列表而不是执行PTB。
sui client ptb \
--assign to_address @0x02a212de6a9dfa3a69e22387acfbafbb1a9e59 \
--split-coins gas [1000,2000,3000] \
--assign coins \
--transfer-objects [coins.0, coins.1, coins.2] to_address \
--gas-budget 5000000 \
--summary \
--preview
这次调用的结果如下:
警告和错误
当使用 — assign命令和 — warn-shadows标志时,工具在遇到阴影变量时会发出警告。也就是说,如果给定变量名有多个声明,工具会警告开发人员同一变量被声明多次。以下是一个示例:
sui client ptb \
--assign a 10 \
--assign a 15 \
--gas-budget 5000000 \
--warn-shadows
下图显示了构建PTB时产生的警告:
我们在报告有用的错误方面投入了大量的工作。我们的目标是让错误信息包含足够的信息来说明问题所在,准确指出导致该错误的参数,并在某些情况下甚至提供如何修复的提示。
例如,如果用户调用std::Option::is_none函数并将模块名称用大写而不是小写传递,工具将生成以下消息:
sui client ptb \
--move-call std::Option::is_none none \
--gas-budget 5000000
错误消息将显示如下:
这是另一个例子,展示了用户在命令不产生任何结果后调用 — assign X而不传递变量时产生的错误:
sui client ptb \
--assign X \
--gas-budget 5000000
在这种情况下,错误将如下所示:
这里是另一个关于工具中保留字段的错误示例:
sui client ptb --assign address 5 --gas-budget 5
在这种情况下,错误消息将显示为:
关于 Sui Network
Sui是基于第一原理重新设计和构建而成的L1公有链,旨在为创作者和开发者提供能够承载Web3中下一个十亿用户的开发平台。Sui上的应用基于Move智能合约语言,并具有水平可扩展性,让开发者能够快速且低成本支持广泛的应用开发。获取更多信息:https://linktr.ee/sui_apac
官网|英文Twitter|中文Twitter|Discord|英文电报群|中文电报群