RFC:可扩展的 UDT(Extensible UDT)
可扩展的 UDT(Extensible UDT,本文统一称为 xUDT)是基于 Simple UDT 的扩展,可用于定义更多 UDT 可能需要的行为。sUDT 为在 Nervos CKB 上发行 UDT 提供了一个最基本的核心,xUDT 则可以建立在 sUDT 的基础上,满足更多的潜在需求,例如监管。
数据结构
xUDT Cell
xUDT cell 向后兼容于 sUDT,所有 sUDT 规范中定义的既存规则仍然适用于 xUDT cell。在 sUDT 的基础上,xUDT 扩展的 cell 如下:
data:
<amount: uint128> <xudt data>
type:
code_hash: extensible_udt type script
args: <owner lock script hash> <xudt args>
lock:
<user_defined>
这个被加上去的 xudt args 和 xudt data 部分提供了所有 xUDT 所需的新功能,我们将会在下文阐述这些细节的架构。
xUDT Args
xUDT args 的架构如下:
4 个字节的 xUDT 标记
可变长度扩展数据
依赖于 flags 的内容,可能会附加不同的扩展数据:
如果 flags 全部为 0,我们不需要任何扩展数据。值得注意的是,向后兼容的查看方式是,一个空白的 sUDT cell 也等于有一个全部为 0 的隐藏 flags 字段。
如果 flags 是 0x1,那么扩展数据将包含一个以 ScriptVec 结构进行序列化的 molecule (https://github.com/nervosnetwork/molecule)
table Script {
code_hash: Byte32,
hash_type: byte,
args: Bytes,
}
vector ScriptVec <Script>;
有些扩展的逻辑可能已经有预定义的哈希,例如,我们可以使用 0x0000 ... 0001 来表示监管的扩展。这些脚本的实际代码已经被镶嵌在 xUDT 自身的脚本中了。
Owner lock (所有者的锁)可拿来使用:如果当前交易中的一个 input cell 使用了与当前扩展脚本相同脚本哈希的 lock script,我们可以认为该扩展脚本已经被验证。
如果一个扩展脚本不匹配任何上述标准,xUDT 将使用包含在扩展脚本中的 code_hash 和 hash_type 以调用 ckb_dlopen2(https://github.com/nervosnetwork/ckb-c-stdlib/blob/37eba3102100808ffc6fa2383bcf9e1e2651c8ea/ckb_dlfcn.h#L108-L113) 的功能,从当前交易的 cell deps 中加载动态链接的脚本。如果脚本可以成功定位,xUDT 将寻找一个带有以下签名的导出函数:
int validate(int is_owner_mode, size_t extension_index, const uint8_t* args, size_t args_length);
如果 flags 是 0x2,扩展数据将包含前一节解释的 ScriptVec 结构的 blake160 哈希。实际的 ScriptVec 结构数据将包含在当前交易中的 witness 中。我们将在下面解释这一部分。
xUDT Data
vector Bytes <byte>;
vector BytesVec <Bytes>;
table XUDTData {
lock: Bytes;
data: BytesVec;
}
操作
原始扩展脚本
Inputs:
<vec> xUDT_Cell
Data:
<amount: uint128> <xudt data>
Type:
code_hash: extensible_udt type script
args: <owner lock script hash> <xudt args>
Lock:
<user defined>
<...>
Outputs:
<vec> xUDT_Cell
Data:
<amount: uint128> <xudt data>
Type:
code_hash: extensible_udt type script
args: <owner lock script hash> <xudt args>
Lock:
<user defined>
<...>
Witnesses:
WitnessArgs structure:
Lock: <user defined>
Input Type: <BytesVec structure>
P2SH Style Extension Script
Inputs:
<vec> xUDT_Cell
Data:
<amount: uint128> <xudt data>
Type:
code_hash: extensible_udt type script
args: <owner lock script hash> <xudt args>
Lock:
<user defined>
<...>
Outputs:
<vec> xUDT_Cell
Data:
<amount: uint128> <xudt data>
Type:
code_hash: extensible_udt type script
args: <owner lock script hash> <xudt args>
Lock:
<user defined>
<...>
Witnesses:
WitnessArgs structure:
Lock: <user defined>
Input Type: <Raw Extension Data> <BytesVec structure>