当前位置:主页 > 列表页 > 正文

RFC:可扩展的 UDT(Extensible UDT)

2021-04-21 00:20 | 出处: Nervos


可扩展的 UDT(Extensible UDT,本文统一称为 xUDT)是基于 Simple UDT 的扩展,可用于定义更多 UDT 可能需要的行为。sUDT 为在 Nervos CKB 上发行 UDT 提供了一个最基本的核心,xUDT 则可以建立在 sUDT 的基础上,满足更多的潜在需求,例如监管。



数据结构



xUDT Cell


xUDT cell 向后兼容于 sUDT所有 sUDT 规范中定义的既存规则仍然适用于 xUDT cell。在 sUDT 的基础上,xUDT 扩展的 cell 如下



这个被加上去的 xudt args xudt data 部分提供了所有 xUDT 所需的新功能,我们将会在下文阐述这些细节的架构。



xUDT Args


xUDT args 的架构如下:


依赖于 flags 的内容,可能会附加不同的扩展数据:





ScriptVec 结构中包含的每个条目,都被解释为具有附加行为的扩展脚本的 CKB 脚本哈希。当一个 xUDT 脚本被执行时,它将运行这里所包含的每个扩展脚本。只有当所有扩展脚本都通过验证时,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 结构中的索引。argsargs_length 被设置为当前扩展脚本的 Script 结构中所包含的 script args。

如果该函数返回 0,则认为对当前扩展脚本的验证是成功的。



xUDT Data


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



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

XUDTData 中包含的 lock 字段不会被 xUDT 脚本使用,它被保留用于当前 cell 脚本特定数据。

扩展脚本首先需要找到它定位在 xUDT args 中的索引,然后在 XUDTData 结构的 data 字段的同一个索引处,查找当前扩展脚本的数据。



操作



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

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


原始扩展脚本


flags 设置为 0 x1 时,原始扩展数据将直接包含在 xUDT args 中。


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

注意,每个扩展脚本在交易中只执行一次。扩展脚本负责检查当前类型的所有 xUDT cell,确保当前扩展脚本的每个 cell 数据和 witness 都可以根据扩展脚本的规则进行验证。



P2SH Style Extension Script


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



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