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

RFC:可组合的 Open Transaction lock script

2021-06-25 01:05 | 出处: Nervos

本文介绍了一个在 Nervos CKB 上能实现 Open Transaction 的 lock script。它的灵感来自于之前 Open Tx Brainstorm 的设计,具有在 Open Transaction 中重新排序和重新安排签名组件的新能力。


Open Tx Brainstorm:

https://talk.nervos.org/t/open-tx-protocol-brainstorm-4-an-implementation-proposal/4427



数据结构



哈希阵列


受最初的 Open Tx 头脑风暴的文章的启发,我们在可组合的 OpenTx lock script 使用的签名前面添加了一个新的 hash_array 的数据结构。hash_array 包含一个 hash item 列表,如下所示:


| NAME | Command | Arg1 | Arg2 ||------|---------|------|------|| BITS | 8       | 12   | 12   |


一个 Hash item 包含 3 个 32 位(4 字节)长的物件。hash_array 不要求在开始处是有长度的字段,一个特殊的命令将标记哈希阵列的结束。在某种程度上,我们可以将哈希阵列看作是一个小型的虚拟机输入程序。这个虚拟机的目的是为了给 blake2b 哈希函数提供数据。来自哈希函数的哈希将用来作签名用的签名信息。


命令


本节将介绍接受 hash item 的有效命令,以及描述和所接受的参数。


首先,我们有一些常见的命令:


| COMMAND | DESCRIPTION                                                 | ARG 1                 | ARG 2        ||---------|-------------------------------------------------------------|-----------------------|--------------|| 0 x00    | Hash the full current transaction hash                      | ignored               | ignored      || 0 x01    | Hash length of input & output cells in current script group | ignored               | ignored      || 0 xF0    | Terminate and generate the final blake2b hash               | ignored               | ignored      |


当虚拟机开始执行 hash_array 时,一个 blake2b 的哈希事件(hash instance)会被创建,大多数命令会生成一些数据。这些数据作为要哈希的内容,并放入 blake2b 事件中。例如,命令 0 x00 将通过 CKB syscall 获取当前正在运行的交易的哈希值,然后将交易哈希值作为数据片段提供给 blake2b 事件。稍后我们将看到更多为 blake2b 哈希物件生成数据的命令。


看到 hash_array 的另一种方法是,每个哈希物件将生成的数据(除了一些项目不这么做以外,我们可以把这些哈希物件生成空数据),然后将所有数据连接到通过 blake2b 哈希算法的单一数据入口,并用之作为后续签名验证阶段的签名消息。


命令 0 x01 会计算当前 lock script 组中输入和输出的 cell 的数量,并用 ** 位无符号小端序格式的两个数字提供给 blake2b 事件来进行哈希。这可用于防止 Open tx 聚合器任意添加未处理的 cell。


命令 0 xf0 填补了另一个不同的目的:一方面,它标示着 hash_array,另一方面,它通知这个小型虚拟机在此运行所有已经传送到虚拟机的数据,而且我们现在还可以从 blake2b 事件生成相应的哈希。此相应的 hash 也用作签名消息,用于稍后的签名验证阶段。


有了大体的工作流程后,我们就可以使用更多生成数据的命令了:


| COMMAND | DESCRIPTION                                   | ARG 1                 | ARG 2        ||---------|-----------------------------------------------|-----------------------|--------------|| 0 x11    | Hash part or the whole output cell            | index of output cell  | `Cell mask`  || 0 x12    | Hash part or the whole input cell             | index of input cell   | `Cell mask`  || 0 x19    | Hash part or the whole output cell            | offset of output cell | `Cell mask`  || 0 x1A    | Hash part or the whole input cell             | offset of input cell  | `Cell mask`  |


这 4 个命令将首先定位在输入或输出 cell ,然后生成作为一部分或整个 cell 的数据。cell 的来源(无论它是输入或输出 cell)由命令表示,cell 的索引则由命令和 ARG 1 表示:



从 cell 生成的数据,由 ARG 2Cell mask 确定,mask 中的有效位包括:

| BIT   | INCLUDED DATA    ||-------|------------------|| 0 x1   | Capacity         || 0 x2   | type.code_hash   || 0 x4   | type.args        || 0 x8   | type.hash_type   || 0 x10  | lock.code_hash   || 0 x20  | lock.args        || 0 x40  | lock.hash_type   || 0 x80  | Cell data        || 0 x100 | Type script hash || 0 x200 | Lock script hash || 0 x400 | The whole cell   |

以下是一些实际的例子:



除了 Cell ,还有一个 CellInput 结构与每个输入 cell 相关联,提供有价值的信息,如 sinceOutPoint。下面的命令提供了一种将 CellInput 数据进行哈希的方法:


| COMMAND | DESCRIPTION                                   | ARG 1                 | ARG 2        ||---------|-----------------------------------------------|-----------------------|--------------|| 0 x15    | Hash part or the whole cell input structure   | index of input cell   | `Input mask` || 0 x1D    | Hash part or the whole cell input structure   | offset of input cell  | `Input mask` |

定位 cell 的相同程序也用于定位 CellInput 的结构,唯一的区别在于要生成的实际数据,或保存在 ARG 2 中的 Input mask

| BIT  | INCLUDED DATA                 ||------|-------------------------------|| 0 x1  | previous_output.tx_hash       || 0 x2  | previous_output.index         || 0 x4  | since                         || 0 x8  | previous_output               || 0 x10 | The whole CellInput structure |

这里是一些实际的范例:

相关文章