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 表示:
| 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 |
| 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` |
| 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 |