跳到主要内容

Object Wrapping 例子

我们来对成绩记录单的例子实现 object wrapping, 让 WrappableTranscriptFolder object 封装起来,使得 Folder object 可以被解包,因而内部的成绩记录单只能被特定的地址/观察者获取。

修改 WrappableTranscriptFolder

首先,需要对我们上一节中定制的类型 WrappableTranscriptFolder 做一些调整。

  1. WrappableTranscript 类型定义加上 key 的能力,可以成为资产和被转移。

回想一下,在 Sui Move 中具备了 keystore 能力的定制类型可以认为是资产。

public struct WrappableTranscript has key, store {
id: UID,
history: u8,
math: u8,
literature: u8,
}
  1. 我们需要为 Folder struct 增加一个额外的属性 intended_address 用来声明内部被封装起来的成绩记录单的目标观察者的地址。
public struct Folder has key {
id: UID,
transcript: WrappableTranscript,
intended_address: address
}

请求 Transcript 方法

public entry fun request_transcript(transcript: WrappableTranscript, intended_address: address, ctx: &mut TxContext){
let folderObject = Folder {
id: object::new(ctx),
transcript,
intended_address
};
//We transfer the wrapped transcript object directly to the intended address
transfer::transfer(folderObject, intended_address)
}

这个方法简易地把一个 WrappableTranscript object 封装到一个 Folder object 里头,然后将被封装的成绩记录单转移到目标地址。

解封装 Transcript 方法

public entry fun unpack_wrapped_transcript(folder: Folder, ctx: &mut TxContext){
// Check that the person unpacking the transcript is the intended viewer
assert!(folder.intended_address == tx_context::sender(ctx), 0);
let Folder {
id,
transcript,
intended_address:_,
} = folder;
transfer::transfer(transcript, tx_context::sender(ctx));
// Deletes the wrapper Folder object
object::delete(id)
}

如果这个方法的调用者就是成绩记录单的目标观察者,就会从 Folder wrapper object 中解封装出 WrappableTranscript object, 然后将其发送给方法的调用者。

问题: 我们为什么需要在这里手动删除 wrapper object? 如果我们不删除会怎样?

Assert

我们使用 assert! 语法来判定在交易中解包出成绩记录单的地址与 Folder wrapper object 中的 intended_address 属性是一致的。

这个 assert! 宏会以下面的格式输入两个参数:

assert!(<bool expression>, <code>)

这里的布尔表达式必须判断为真,否则就会弹出错误码 <code> 并中止。

定义错误码

上面是用了默认的0来作为错误码,但其实我们也可以用下面的方式来定义其他错误码:

    const ENotIntendedAddress: u64 = 1;

这个错误码会在应用层上被消耗掉并进行合适的处理。

这里能找到对应这里的第二版处于开发进展中版本的代码: WIP transcript.move