乐趣区

关于区块链:RFC可扩展的-UDTExtensible-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/nervosnetw…
table Script {
    code_hash:      Byte32,
    hash_type:      byte,
    args:           Bytes,
}

vector ScriptVec <Script>;

ScriptVec 构造中蕴含的每个条目,都被解释为具备附加行为的扩大脚本的 CKB 脚本哈希。当一个 xUDT 脚本被执行时,它将运行这里所蕴含的每个扩大脚本。只有当所有扩大脚本都通过验证时,xUDT 才会认为该验证是胜利的。

一个扩大的脚本能够被下列的任一种形式加载:

  • 有些扩大的逻辑可能曾经有预约义的哈希,例如,咱们能够应用 0x0000 … 0001 来示意监管的扩大。这些脚本的理论代码曾经被镶嵌在 xUDT 本身的脚本中了。
  • Owner lock(所有者的锁)可拿来应用:如果以后交易中的一个 input cell 应用了与以后扩大脚本雷同脚本哈希的 lock script,咱们能够认为该扩大脚本曾经被验证。
  • 如果一个扩大脚本不匹配任何上述规范,xUDT 将应用蕴含在扩大脚本中的 code_hash 和 hash_type 以调用 ckb_dlopen2(https://github.com/nervosnetw… 的性能,从以后交易的 cell deps 中加载动静链接的脚本。如果脚本能够胜利定位,xUDT 将寻找一个带有以下签名的导出函数:
int validate(int is_owner_mode, size_t extension_index, const uint8_t* args, size_t args_length);

is_owner_mode 示意以后 xUDT 是否通过所有者模式解锁(如 sUDT 所述),extension_index 指的是以后的扩大在 ScriptVec 构造中的索引。args 和 args_length 被设置为以后扩大脚本的 Script 构造中所蕴含的 script args。

如果该函数返回 0,则认为对以后扩大脚本的验证是胜利的。

  • 如果 flags 是 0x2,扩大数据将蕴含前一节解释的 ScriptVec 构造的 blake160 哈希。理论的 ScriptVec 构造数据将蕴含在以后交易中的 witness 中。咱们将在上面解释这一部分。

xUDT Data

xUDT 数据是一个以 XUDTData 构造来进行序列化的模组:

vector Bytes <byte>;
vector BytesVec <Bytes>;

table XUDTData {
  lock: Bytes;
  data: BytesVec;
}

蕴含在 XUDTData 中的 data 字段,必须与蕴含在 xUDT args 中的 ScriptVec 构造的长度雷同。一些扩大可能须要在每个 xUDT cell 中存储特定于用户的数据。xUDT 数据为此类数据提供了一个搁置的位子。

XUDTData 中蕴含的 lock 字段不会被 xUDT 脚本应用,它被保留用于以后 cell 的锁定脚本特定数据。

扩大脚本首先须要找到它定位在 xUDT args 中的索引,而后在 XUDTData 构造的 data 字段的同一个索引处,查找以后扩大脚本的数据。

操作

xUDT 采纳与 sUDT 雷同的治理操作:所有者锁管制所有治理行为,如代币铸造等。

然而,xUDT 的失常调用操作不同于 sUDT。依据所用的 flags,可能会有两种应用模式:

原始扩大脚本

当 flags 设置为 0x1 时,原始扩大数据将间接蕴含在 xUDT args 中。

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>

与第一个输出 xUDT cell 雷同的索引的 witness 是由 xUDT 脚本定位的。它首先被解析为 WitnessArgs 构造,因而 WitnessArgs 的 input_type 字段被视为 BytesVec 构造。这个构造也必须与 xUDT args 和 xUDT data 局部的长度雷同。扩大脚本可能还须要特定交易的数据,以便进行验证。Witness 在此为这种数据需要提供了一个搁置的地位。

留神,每个扩大脚本在交易中只执行一次。扩大脚本负责查看以后类型的所有 xUDT cell,确保以后扩大脚本的每个 cell 数据和 witness 都能够依据扩大脚本的规定进行验证。

P2SH Style Extension Script

当 flags 设置为 0x2 时,xUDT args 只蕴含扩大数据的 blake160 哈希。用户会被要求间接提供在 Witness 中的扩大数据:

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>

这里惟一的区别是,在相应的 WitnessArgs 构造中的 input_type 字段蕴含在 ScriptVec 数据结构中的原始扩大数据,xUDT 脚本必须首先验证这里提供的原始扩大数据的哈希,是否与 xUDT args 中蕴含的 blake160 哈希雷同。在此之后,它将应用与后面工作流中雷同的逻辑。

退出移动版