交易是 CKB 操作的核心。在与 CKB 交互时,人们将通过交易提交新的状态。本文档中,CKB 开发者 DingWei Zhang 将向大家解释 CKB 交易验证的生命周期,欢迎查看。
RPC
首先,发送方会构造一笔交易,通过 RPC 提交。交易由提交到的 outputs_validator
(从 0.27.0 版本引入)进行验证。
默认的验证逻辑包括检查各种东西:
transaction.outputs.all{ |output|
let script = output.script
(script.code_hash == secp256k1_blake160_sighash_all && script.hash_type == "type" && script.args.size == 20) ||
(script.code_hash == secp256k1_blake160_multisig_all && script.hash_type == "type" && (script.args.size == 20 || (script.args.size == 28 && script.args[20..28].is_valid_since_format))
}
transaction.outputs.all{ |output|
let script = output.type
script.is_null || script.code_hash == dao && script.hash_type == "type"
|| (script.has_lock_period() && since.is_absolute())
}
此验证旨在防止格式不正确的交易,例如在 Common Gotchas 中提到的交易。
此外,可以将其配置为 passthrough
以跳过此验证。
交易提交到本地节点后,节点还会输出交易 id,您可以使用该 id 跟踪交易的状态。
Verification验证
在广播交易并进入 mempool 之前,交易将在本地验证和执行。
步骤 1——Resolve
本质上,交易 input 只是指针,如下所示:
struct OutPoint {
tx_hash: Byte32,
index: Uint32,
}
我们在交易执行之前通过指针收集引用的数据,这个过程称为「解析交易」。我们还需要检查这个交易的所有输入都是有效的(没有重复或双花)。
步骤 2——验证
验证步骤需要检查如下要素:
- 版本(目前必须是 0)
- serialized_size 必须小于如下限制:
- pub fn serialized_size(&self) -> usize {
// the offset in TransactionVec header is u32
self.as_slice().len() + molecule::NUMBER_SIZE
// molecule::NUMBER_SIZE =size_of::<u32>() 4
}
- pub fn serialized_size(&self) -> usize {
- inputs 不是空的
- inputs().is_empty() || outputs().is_empty()
- inputs 是成熟的
- 对于每个 input 和 dep,如果引用的 output 交易是 cellbase,那么它必须至少经过 4 个 epoch 确认
- capacity
- input capacity 的和必须大于或等于 output capacity
- duplicate_deps
- deps 不能重复
- outputs_data_verifier
- 「output data」字段的数量必须等于 outputs 的数量
- since
- since 值必须遵循 RFC:Transaction valid since
CKB VM 将执行交易脚本,并输出所消耗的 cycles 个数
向网络广播
如果验证成功,当前节点将交易(带有 cycles 值)广播给它的所有对等节点(它所连接的节点)。
在验证失败的情况下,将不再广播交易。交易流经各个「完整节点」,这些节点重复前面步骤中描述的验证过程,并检查 cycle 值是否与验证交易时使用的实际 cycle 相匹配。
Tx-pool
CKB 使用 two-step 进行交易确认。交易将在 tx-pool 中划分为不同的状态(pending 状态和 proposed 状态)。当一个块上链时,交易的状态将改变。当最新的块更改时,将重新扫描 tx-pool 中的所有交易,以确保它们仍然有效。
BlockAssembler
将从 pending 池和 proposed 池中为块模板获取 proposal 和交易,详细可参考:Two-Step Transaction Confirmation.