Nervos CKB 的数据结构

NumberCategoryStatusAuthorOrganizationCreated
0019InformationalDraftXuejie XiaoNervos Foundation2019-03-26

Nervos CKB 的数据结构

本文档描述了 CKB 中使用的所有基本数据结构。

Cell

示例

{
"capacity": "0x19995d0ccf",
"lock": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"args": "0x0a486fb8f6fe60f76f001d6372da41be91172259",
"hash_type": "type"
},
"type": null
}

描述

名称类型描述
capacityuint64定义 cell 的容量大小 (用 shannons 表示)。 当一个新的 Cell (通过转账) 生成时, 其中一条验证规则是 capacity_in_bytes >= len(capacity) + len(data) + len(type) + len(lock). 这个值也代表了 CKB 作为 coin 的余额,就像比特币的 CTxOut 中的nValue 字段一样。(例如:Alice 拥有 100 个 CKB,这意味着她可以解锁一组共有数量为 100 个 bytes (即 10_000_000_000 个 shannons)的 Cells。) 实际返回值为十六进制字符串格式。
typeScript定义 cell 类型的脚本。 它限制了新 cells 的 data 字段是如何从旧 cells 转换过来的。type 需要具有 Script 的数据结构。这个字段是可选的。
lockScript定义 cell 所有权的脚本。 就像是比特币 CTxOut 中的 scriptPubKey 字段一样。任何能够提供解锁参数使得脚本成功执行的人,都可以使用该 cell 作为转账的 input(即拥有该 cell 的所有权)。

关于 Cell 的更多信息可以在 白皮书 中找到。

Script

示例

{
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"args": "0x0a486fb8f6fe60f76f001d6372da41be91172259",
"hash_type": "type"
}

描述

名称类型描述
code_hashH256(hash)定义为包含 CKB 脚本的具有 ELF 格式的 RISC-V 二进制文件的哈希值。 出于空间效率的考虑,实际脚本会作为 dep cell 附到当前转账中。根据 hash_type 的值,此处指定的哈希应该匹配 dep cell 中 cell data 部分的哈希或者是 dep cell 中 type script 的哈希。当它在转账验证中被指定时,实际的二进制文件会被加载到 CKB-VM 中。
argsBytes定义为作为脚本输入的参数。 这里的参数将作为脚本的输入参数被导入到 CKB-VM 中。
hash_typeString, 可以是 type 或者 data定义为查找 dep cells 时对代码哈希的说明。 如果是 datacode_hash 需要匹配 dep cell 中 data 部分经过 blake2b 得到的哈希;如果是 typecode_hash 需要需要匹配 dep cell 中 type script 的哈希。

当一个脚本被验证时,CKB 链会在 RISC-V 虚拟机内运行它,args 必须通过特殊的 CKB syscalls 进行调用加载。CKB 中不使用 UNIX 标准中的 argc/argv 方法。想要了解更多关于 CKB 虚拟机的信息,请参阅 CKB VM RFC

更多关于 Script 结构如何应用的信息,请参阅 CKB repo

转账

示例

{
"version": "0x0",
"cell_deps": [
{
"out_point": {
"tx_hash": "0xbd864a269201d7052d4eb3f753f49f7c68b8edc386afc8bb6ef3e15a05facca2",
"index": "0x0"
},
"dep_type": "dep_group"
}
],
"header_deps": [
"0xaa1124da6a230435298d83a12dd6c13f7d58caf7853f39cea8aad992ef88a422"
],
"inputs": [
{
"previous_output": {
"tx_hash": "0x8389eba3ae414fb6a3019aa47583e9be36d096c55ab2e00ec49bdb012c24844d",
"index": "0x1"
},
"since": "0x0"
}
],
"outputs": [
{
"capacity": "0x746a528800",
"lock": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"args": "0x56008385085341a6ed68decfabb3ba1f3eea7b68",
"hash_type": "type"
},
"type": null
},
{
"capacity": "0x1561d9307e88",
"lock": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"args": "0x886d23a7858f12ebf924baaacd774a5e2cf81132",
"hash_type": "type"
},
"type": null
}
],
"outputs_data": [
"0x",
"0x"
],
"witnesses": ["0x55000000100000005500000055000000410000004a975e08ff99fa0001
42ff3b86a836b43884b5b46f91b149f7cc5300e8607e633b7a29c94dc01c6616a12f62e74a1
415f57fcc5a00e41ac2d7034e90edf4fdf800"
]
}

描述

转账

名称类型描述
versionuint32定义为当前转账的版本。 当区块链系统发生分叉时,用它来区分转账(发生在哪一条链上)。
cell_deps[CellDep]一个 outpoint 数组,指向此转账依赖的 cells。 只有 live 的 cells 才可以列在这里。这里列出的 cells 是 read-only 的。
header_deps[H256(hash)]一个 H256 哈希数组,指向此转账依赖的区块头。 注意这里需要采用等待一定区块完成确认的规则:一笔交易只能引用至少已经完成 4 个 epochs 以上确认的区块头。
inputs[CellInput]一个引用 cell inputs 的数组。 参见下文对基本数据结构的解释。
outputs[Cells], 详情见上文一个作为 outputs 的 cells 数组。 也就是新生成的 cells。这些 cells 可以作为其他转账的 inputs。每一个 Cell 都拥有和上面 Cell 章节一样的结构。
outputs_data[Bytes]一个由所有 cell output 的 cell data 组成的数组。 将实际数据与输出分离,以便于 CKB 脚本的处理和未来优化的可能。
witnesses[Bytes]Witnesses 由交易创建器提供,使得相应的锁脚本可以成功执行。 这里的一个例子是,这里可能包含签名,以确保签名验证的锁脚本可以通过。

CellDep

名称类型描述
out_pointOutPoint一个指向 cells 的 cell outpoint,和 deps 一样使用。 Dep cells 和转账相关,它可以用于放置会加载到 CKB VM 中的代码,或者用于放置可用于脚本执行的数据。
dep_typeString, 是 code 或者是 dep_group解释引用 cell deps 的方法。 cell dep 可以通过两种方式进行引用:对于 dep_typecode 的 cell dep,这个 dep cell 会直接包含在转账中。对于 dep_typedep_group 的 cell dep,假设这个 cell 包含了一个 cell deps 的列表,CKB 可以先加载这个 dep cell,然后将剩下的 cell deps 替代当前的 cell dep,并将它们包含在当前的转账中。这可以在一个 CellDep 结构中包含多个更快更小(就转账大小而言)的 dep cells。

CellInput

名称类型描述
previous_outputOutPoint一个指向之前作为 inputs cells 的 cell outpoint。 输入 cells 实际上在上一次转账中是输出,因此在这里将它们标记为 previous_output。这些 Cells 通过 outpoint 进行引用,它会包含上一次转账的转账 hash,并在转账的 output 列表内包含这个 cell 的 index
sinceuint64Since 值用于保护当前引用的 inputs。 更多详情请参阅 Since RFC

OutPoint

名称类型描述
hashH256(hash)当前 cell 所属的转账的哈希。
indexuint32当前 cell 的转账 output 列表的索引。

关于 Nervos CKB 上转账的更多信息,可以在 whitepaper 中找到。

区块

示例

{
"uncles": [
{
"proposals": [
],
"header": {
"compact_target": "0x1a9c7b1a",
"hash": "0x87764caf4a0e99302f1382421da1fe2f18382a49eac2d611220056b0854868e3",
"number": "0x129d3",
"parent_hash": "0x815ecf2140169b9d283332c7550ce8b6405a120d5c21a7aa99d8a75eb9e77ead",
"nonce": "0x78b105de64fc38a200000004139b0200",
"timestamp": "0x16e62df76ed",
"transactions_root": "0x66ab0046436f97aefefe0549772bf36d96502d14ad736f7f4b1be8274420ca0f",
"proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"uncles_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"version": "0x0",
"epoch": "0x7080291000049",
"dao": "0x7088b3ee3e738900a9c257048aa129002cd43cd745100e000066ac8bd8850d00"
}
}
],
"proposals": [
"0x5b2c8121455362cf70ff"
],
"transactions": [
{
"version": "0x0",
"cell_deps": [
],
"header_deps": [
],
"inputs": [
{
"previous_output": {
"tx_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"index": "0xffffffff"
},
"since": "0x129d5"
}
],
"outputs": [
{
"capacity": "0x1996822511",
"lock": {
"code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
"args": "0x2ec3a5fb4098b14f4887555fe58d966cab2c6a63",
"hash_type": "type"
},
"type": null
}
],
"outputs_data": [
"0x"
],
"witnesses": ["0x590000000c00000055000000490000001000000030000000310000009b
d7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce801140000002
ec3a5fb4098b14f4887555fe58d966cab2c6a6300000000"
],
"hash": "0x84395bf085f48de9f8813df8181e33d5a43ab9d92df5c0e77d711e1d47e4746d"
}
],
"header": {
"compact_target": "0x1a9c7b1a",
"hash": "0xf355b7bbb50627aa26839b9f4d65e83648b80c0a65354d78a782744ee7b0d12d",
"number": "0x129d5",
"parent_hash": "0x4dd7ae439977f1b01a8c9af7cd4be2d7bccce19fcc65b47559fe34b8f32917bf",
"nonce": "0x91c4b4746ffb69fe000000809a170200",
"timestamp": "0x16e62dfdb19",
"transactions_root": "0x03c72b4c2138309eb46342d4ab7b882271ac4a9a12d2dcd7238095c2d131caa6",
"proposals_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"uncles_hash": "0x90eb89b87b4af4c391f3f25d0d9f59b8ef946d9627b7e86283c68476fee7328b",
"version": "0x0",
"epoch": "0x7080293000049",
"dao": "0xae6c356c8073890051f05bd38ea12900939dbc2754100e0000a0d962db850d00"
}
}

描述

区块

名称类型描述
headerHeader区块的区块头 这一部分包含区块的一些元数据,请参阅下方区块头部分,了解更多细节
trasactions[Transaction]一个由区块中已经确认提交的转账组成的数组。 这个数组中每个元素都具有同上面[转账]部分一样的结构
proposals[string]一个由提案转账进行十六进制编码后的短转账 ID 组成的数组。
uncles[UncleBlock]一个由叔块组成的数组 详情参阅下方[叔块]部分。

区块头

(区块头区块叔块 的子结构。)

名称类型描述
compact_targetuint32以压缩的格式表示的 PoW 解谜(挖矿)难度。
numberuint64区块高度。
parent_hashH256(hash)上一个区块的哈希。
nonceuint128随机数。 类似于比特币中的随机数, 表示 PoW 谜题的解
timestampuint64一个 Unix time 时间戳按毫秒计。
transactions_rootH256(hash)串联的转账哈希的 CBMT 根和转账 witness 哈希的 CBMT 根的哈希。
proposals_hashH256(hash)串联的提案 ids 的哈希。 (当没有提案时所有数字为 0)
uncles_hashH256(hash)所有叔块头的串联的哈希的哈希。 (当没有叔块时所有数字为 0)
versionuint32区块的版本。 这是用于解决在 fork 之后可能出现的兼容性问题
epochuint64当前 epoch 的信息。 假设 number 代表当前 epoch 的数字,index 代表当前 epoch 中区块的索引(从 0 开始),length 代表当前 epoch 的长度。那么这里的值需要满足 `(number & 0xFFFFFF)
daoBytes包含 DAO 相关的信息。 详情参阅 Nervos DAO RFC。

叔块

(叔块区块 的子结构。)

名称类型描述
headerHeader叔块的区块头。 这部分的内部结构和上方[区块头]一致
proposals[string]一个由叔块中提案转账的短转账 IDs 组成的数组