0%

PTB & 快速开始dapp

sui -move

Sui-PTB (可编程交易模块)

官方文档地址:https://docs.sui.io/concepts/transactions/prog-txn-blocks

PTB概述

PTB 全称 Programmable Transaction Block(可编程交易模块),在Sui上,交易不仅仅是资产流动的基本记录,交易由多个命令组成,这些命令在输入上执行,定义交易的结果。

PTB允许用户在单个交易中调用多个Move函数,管理其对象和管理其代币,而无需发布新的Move包,是生成交易的一种轻量灵活的方式,同时其执行组合的交易模式减少了gas fee 。

PTB 的组成

每个PTB由单独的交易命令组成,这里的交易命令有:

  1. TransferObjects

    • 将一组对象转移到指定地址。
  2. SplitCoins

    • 将一个硬币拆分成多个硬币。
  3. MakeMoveVec

    • 构建一个 Move 类型的向量。
  4. MoveCall

    • 调用指定的 Move 函数。
  5. Publish

    • 发布指定的模块。
  6. Upgrade

    • 升级已有的模块或包。

每个交易命令按顺序执行,您可以在任何后续交易命令中使用前一个交易命令的结果。所有交易命令在一个块中的效果,特别是对象修改或转移,会在事务结束时以原子方式应用。如果一个交易命令失败,整个块都会失败,并且命令的任何效果都不会被应用

主要通过前端来整合并连续实施多个操作,即操作前端来实现交易的添加和合约的调用

PTB的使用

前端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//创建可编程事务块 (PTB)
const txb = new Transaction();
//设置输入参数
const arg1 = txb.object(objectId0);
const arg2 = txb.object(objectId1);
const arg3 = txb.pure.u8(0);
const arg4 = txb.pure.bool(true);
const arg5 = txb.pure(bcs.vector(bcs.U64).serialize([123, 456]));

const myCoin = txb.object(myCoinId);
//通过命令调用 Move 函数拿到输出的资产
const coinOut = txb.moveCall({
target: '${packageId}::${moduleName}::${funcName}*',
typeArguments: [type1, type2],
arguments: [arg1, arg2, arg3, arg4, arg5]
});
// 拆分Coin为coinOut0和 coinOut1
const [coinOut0, coinOut1] = txb.splitCoins(coinOut, [100, 200]);
// 将coin合并到自己的资产中
txb.mergeCoins(myCoin, [coinOut]);
// 转移对象
if (coinOut0) txb.transferObjects([coinOut0], recipient);

if (coinOut1) txb.transferObjects([coinOut1], recipient1);

terminal

1
2
3
4
5
6
7
8
sui client ptb 
--assign kapy @0xa8f224924c9570c0bed020606be889fd46373e80c3a6b9547aeb33e646b4d540
--assign cfg @0x80ff28774e3056f00e130a2dedda8be83c04acf3ab0697395bd37ee022001d15
--move-call 0xf61cffb662dda6c8ac484f299361b0d85464d06e46603321ad0b7311f0594490::exercise_3::buy_with_kapy kapy
--assign dv
--move-call 0xf61cffb662dda6c8ac484f299361b0d85464d06e46603321ad0b7311f0594490::exercise_3::pay "<sui::sui::SUI>" @0xd4fb85849ac089d5df317663b818dda0cf35a9f8b3c68ec81f941d010019bf7d cfg dv @0x5617dbcfdea83576ae108ce03ea4fdebf2c505c53eec6e8c1130366f5bbb2eac
--assign org
--move-call 0xcbfbdaaa8e8a70556c0cf1a038ddb3d9cc86cdaeb1add61abf7ebd2becac7b9d::kapy::carry kapy org --gas-budget 10000000

Sui -client 命令速查

Sui-Dapp kit 套件

1
2
3
4
npm i --save @mysten/dapp-kit @mysten/sui @tanstack/react-query
npm creat @mysten/dapp
npm install --legacy-peer-deps
npm run dev

创建 Dapp

https://sdk.mystenlabs.com/dapp-kit/create-dapp

1
2
3
4
5
6
7
npm create @mysten/dapp
选择1:react-client-dapp - 一个基本的 React dApp,用于获取连接的钱包所拥有的对象列表。
选择2:react-e2e-counter - 包含 Move 代码和简单计数器应用程序 UI 的端到端示例
输入Dapp-name
cd Dapp-name
npm install // 产生冲突 npm install --legacy-peer-deps
npm run dev - 运行

Typescript SDK

coin::valuecoin::into_balance 不同

  1. coin::value:

    • 用于获取一个 Coin数值

    • 它是一个公共的 getter 函数,可以返回 Coin 的具体数值。

    • 代码签名为:

      1
      public fun value<T>(self: &coin::Coin<T>): u64
    • 这个函数不会改变 Coin 的状态,只是读取其数值。

  2. coin::into_balance:

    • 用于将一个 Coin 解构为 Balance

    • 这个函数会消耗 Coin 对象,并返回其内部的 Balance

    • 代码签名为:

      1
      public fun into_balance<T>(coin: coin::Coin<T>): balance::Balance<T>
    • 使用这个函数后,**Coin 不再存在,而是转换为了 Balance**。

这两个函数的主要区别在于一个是读取操作(value),另一个是转换操作(into_balance)。如果你想获取 Coin 的数值而不改变其状态,使用 value;如果你需要将 Coin 转换为 Balance,使用 into_balance

& 和直接传参和&mut 的区别

在 Move 中,&、直接传参和 &mut 的区别主要在于所有权和可变性:

  1. 引用(&)

    • 传递的是对象的不可变引用。
    • 允许在函数中读取对象,但不能修改。
    • 不会转移对象的所有权。
  2. 直接传参

    • 传递的是对象本身。
    • 转移对象的所有权到函数中。
    • 函数可以消耗对象(例如,销毁或转移)。
  3. 可变引用(&mut)

    • 传递的是对象的可变引用。
    • 允许在函数中读取和修改对象。
    • 不会转移对象的所有权,但允许修改其状态。

选择使用哪种方式取决于你的具体需求:

  • 使用 & 当你只需要读取对象而不修改。
  • 使用 &mut 当你需要在函数中修改对象。
  • 使用直接传参当你需要转移对象的所有权或消耗它。

各类transfer的区别与使用

方法 生成的方法 属性
transfer 独享对象 key
public_transfer 独享对象 key + store
freeze_object 共享对象-常量 key
public_freeze_object 共享对象-常量 key + store
share_object 共享对象 key
public_share_object 共享对象 key + store

源码地址:https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/sui-framework/sources/transfer.move