CKB(Common Knowledge Base,公共知识库)是 Nervos Network 的 Layer 1 公链,2019 年 11 月主网上线。与以太坊的账户模型、比特币的纯价值 UTXO 不同,CKB 的核心设计是:用 Cell 承载任意链上状态,用 RISC-V 虚拟机验证状态转换,把计算尽量推到链下,链上专注验证与安全。

nervosnetwork/ckb 是 Nervos Network 的底层 Layer 1 区块链节点实现。CKB 全称 Common Knowledge Base,主要使用 Rust 开发。它不是传统“账户模型 + 智能合约虚拟机”的架构,而是采用:

  • Cell 状态模型
  • 基于 RISC-V 的 CKB-VM
  • PoW + NC-Max 共识
  • 链上状态占用与原生代币 CKB 绑定
  • Lock Script / Type Script 双脚本验证机制

可以从协议层和代码工程层两个角度理解。


一、整体架构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌───────────────────────────────────────────────┐
│                 应用与工具层                   │
│ Wallet / SDK / Explorer / dApp / Indexer      │
└──────────────────────┬────────────────────────┘
                       │ JSON-RPC / P2P
┌──────────────────────▼────────────────────────┐
│                  节点服务层                    │
│ RPC │ Indexer │ Tx Pool │ Block Assembler     │
└──────────────────────┬────────────────────────┘
                       │
┌──────────────────────▼────────────────────────┐
│                  区块链核心层                  │
│ Chain Service │ Block Verification │ Reorg     │
│ Epoch │ DAO │ Reward │ Consensus Rules         │
└───────────────┬───────────────────┬────────────┘
                │                   │
┌───────────────▼──────────┐ ┌──────▼────────────┐
│      脚本执行层           │ │     共识与同步层    │
│ CKB-VM / RISC-V          │ │ NC-Max / PoW       │
│ Lock Script / Type Script│ │ P2P / Relay / Sync │
└───────────────┬──────────┘ └──────┬────────────┘
                │                   │
┌───────────────▼───────────────────▼────────────┐
│                  数据与类型层                  │
│ Cell / Transaction / Header / Block / Molecule│
│ Chain DB / State DB / Index                   │
└───────────────────────────────────────────────┘

二、核心状态模型:Cell Model

1. Cell 是什么

CKB 没有采用以太坊式的账户模型,而是采用一种扩展的 UTXO 模型,称为 Cell Model。

一个 Cell 可以简化理解为:

1
2
3
4
5
6
Cell {
    capacity: 该 Cell 占用的 CKB 数量,
    lock: 谁可以消费这个 Cell,
    type: 该 Cell 遵循什么状态规则,
    data: Cell 保存的链上数据
}

更具体地说,一个 Cell 通常由以下内容组成:

  • capacity
    • 表示这个 Cell 中锁定的 CKB 数量;
    • 同时约束 Cell 能占用多少字节的链上空间。
  • lock script
    • 决定谁有权消费 Cell;
    • 类似比特币的解锁条件,但可以运行通用 RISC-V 程序。
  • type script
    • 可选;
    • 负责约束 Cell 的状态生成和状态转换规则。
  • data
    • 保存资产、协议状态、配置或者任意二进制数据。

2. Cell 的生命周期

Cell 只有两种状态:

  • Live:尚未被消费;
  • Dead:已经被某笔交易消费。

交易不会原地修改 Cell,而是:

1
旧 Cell 作为输入 → 执行验证脚本 → 创建新的输出 Cell

例如:

1
2
3
4
5
6
输入:
  Alice 的 Token Cell,余额 100

输出:
  Bob 的 Token Cell,余额 30
  Alice 的 Token Cell,余额 70

Type Script 验证总量、格式和状态转换规则,Lock Script 验证 Alice 是否授权了这笔交易。

3. 与传统模型的区别

模型 状态表示 状态更新方式
比特币 UTXO 未花费交易输出 消费旧 UTXO,创建新 UTXO
以太坊账户模型 账户和合约存储 原地修改全局状态
CKB Cell 模型 带任意数据和脚本的 Cell 消费旧 Cell,创建新 Cell

CKB 的 Cell 更接近一种“可编程、可保存任意状态的 UTXO”。


三、脚本架构:Lock Script 与 Type Script

CKB 将资产所有权和状态转换规则分开。

1. Lock Script

Lock Script 负责验证:

这笔交易是否有权消费某个输入 Cell?

典型例子是签名验证:

1
2
3
4
5
lock {
    code_hash: secp256k1 验证程序的哈希,
    hash_type: type,
    args: 公钥哈希
}

交易执行时,CKB-VM 加载对应程序,并通过交易的 witness 验证签名。

它还可以实现:

  • 多签;
  • 时间锁;
  • 支付条件;
  • 自定义身份验证;
  • WebAuthn、Passkey 等身份方案;
  • 跨链资产解锁条件。

2. Type Script

Type Script 负责验证:

输入 Cell 到输出 Cell 的状态转换是否合法?

常见用途包括:

  • 同质化代币;
  • NFT;
  • DID;
  • 域名系统;
  • 链上配置;
  • 协议状态;
  • 跨链映射资产。

例如一个代币 Type Script 可以验证:

1
输入代币总量 == 输出代币总量

如果是铸币或销毁,则必须再满足额外的授权条件。

3. Code 与 Data 分离

CKB 的合约代码不一定内嵌在每次交易中。程序可以保存在某个 Cell 的 data 里,其他交易通过 Cell 依赖引用它:

1
CellDep → 保存脚本二进制的 Cell → CKB-VM 加载执行

因此 CKB 交易通常包括:

  • inputs:被消费的 Cell;
  • outputs:新创建的 Cell;
  • outputs_data:输出 Cell 的数据;
  • cell_deps:执行脚本需要依赖的代码或数据 Cell;
  • header_deps:脚本需要引用的历史区块头;
  • witnesses:签名、证明及其他验证材料。

四、执行环境:CKB-VM

1. RISC-V 虚拟机

CKB 使用基于 RISC-V 指令集的虚拟机,而不是设计一套高度专用的合约字节码。

大致过程是:

1
2
3
4
5
6
7
合约源代码
  ↓ 编译
RISC-V ELF 二进制
  ↓ 存入 Cell 或由交易引用
CKB-VM 加载
  ↓
执行验证逻辑

这种设计的优势是:

  • 可以复用 LLVM、GCC 等编译工具链;
  • 理论上可以使用 C、Rust 等语言编写脚本;
  • 指令集较稳定、通用;
  • 密码学算法可以直接编译运行;
  • 不需要将所有功能固化为虚拟机内置操作码。

2. CKB-VM 的角色

CKB-VM 主要执行的是交易验证脚本,不是持续运行的服务进程。

脚本会读取:

  • 输入 Cell;
  • 输出 Cell;
  • Cell data;
  • Witness;
  • Cell dependencies;
  • 区块头依赖;
  • 交易自身的哈希和结构。

脚本通过系统调用访问交易上下文。

3. Cycle 计费

脚本执行成本通常用 cycles 衡量。节点验证交易时会计算脚本消耗的周期数,并检查是否超过共识或交易限制。

它主要用于:

  • 防止无限循环;
  • 限制验证资源消耗;
  • 估算交易验证复杂度;
  • 约束区块可容纳的计算量。

这与以太坊 Gas 类似,但 CKB 中链上存储成本和计算成本的表达方式并不完全相同:

  • Cell 的 capacity 约束长期状态空间;
  • Transaction Fee 激励矿工处理交易;
  • VM cycles 约束计算资源。

五、共识层:PoW 与 NC-Max

CKB 是 PoW 公链,其共识通常称为 NC-Max,建立在 Nakamoto Consensus 思路之上,并针对区块传播效率进行了设计。

主要组件包括:

  • 区块头;
  • PoW 难度;
  • Epoch;
  • 链权重选择;
  • 区块传播;
  • Uncle 区块机制;
  • 时间戳和难度调整;
  • 区块奖励及交易手续费。

1. Epoch

CKB 使用 Epoch 管理一段区块周期内的共识参数,例如:

  • 挖矿难度;
  • 区块奖励;
  • 区块容量相关规则。

Epoch 不一定是固定区块数量,它与出块情况和难度调整机制有关。

2. 主链选择

节点接收到分叉时,会依据共识规则和累计工作量等信息选择规范链。

链服务需要处理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
接收新区块
  ↓
检查区块头与 PoW
  ↓
检查父区块和共识字段
  ↓
验证交易及脚本
  ↓
计算链权重
  ↓
提交主链或触发 Reorg

3. Uncle 机制

由于网络传播延迟,有些合法挖出的区块可能未进入最终主链。CKB 引入 Uncle 相关机制,以减少传播延迟对矿工的不公平影响,并提升网络对较快出块的容忍度。


六、经济模型与状态占用

CKB 的一个重要特点是:

1 CKB 对应一定数量的链上状态容量,通常可抽象理解为 1 字节状态空间的占用权。

如果一个 Cell 序列化后占用一定空间,它必须具有至少相应数量的 capacity。

因此,CKB 代币不只是手续费或价值载体,也与底层状态资源绑定。

1. Cell 容量检查

一个输出 Cell 必须满足:

1
cell.capacity >= occupied_capacity(cell)

占用容量与以下内容有关:

  • capacity 字段本身;
  • lock script;
  • type script;
  • data 长度。

这能在协议层对无限状态膨胀形成经济约束。

2. Nervos DAO

Nervos DAO 是协议内置的经济机制之一。用户可以将 CKB 存入 DAO Cell,根据协议规则获得补偿。

从技术实现看,它涉及:

  • DAO 存款交易;
  • DAO 提取交易;
  • 区块头中的 DAO 字段;
  • Epoch 和发行参数;
  • 基于历史区块头计算可提取容量;
  • header_deps 对相关区块头的引用。

它并不是普通的账户余额利息,而是通过 Cell 状态转换和共识规则实现。


七、P2P 网络与同步

CKB 节点内部一般包含独立的网络和同步服务。

1. P2P 网络

网络层负责:

  • 节点发现;
  • 连接管理;
  • 协议协商;
  • 区块广播;
  • 交易广播;
  • Peer 状态管理;
  • 黑名单与异常节点处理。

CKB 的网络协议采用模块化设计,不同功能以独立子协议运行,例如:

1
2
3
4
5
6
Identify
Discovery
Sync
Relay
Time
Feeler

具体协议划分会随版本演进。

2. 区块同步

同步服务大致负责:

  1. 与 Peer 比较最佳链;
  2. 获取区块头;
  3. 校验 Header Chain;
  4. 下载对应区块;
  5. 提交给链验证模块;
  6. 更新本地最佳链。

同步层和链验证层通常是分离的:

  • Sync 负责“从哪里获取、按什么顺序获取”;
  • Chain 负责“区块是否合法、是否应成为主链”。

3. 交易广播

节点接收新交易后通常执行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
格式检查
  ↓
依赖解析
  ↓
输入 Cell 是否存活
  ↓
脚本执行
  ↓
手续费与 cycles 检查
  ↓
进入 Tx Pool
  ↓
广播给其他节点

八、交易池架构

CKB 的交易池不只是一个简单交易列表。由于 Cell 之间存在依赖关系,交易池需要管理:

  • 输入冲突;
  • 交易依赖;
  • CellDep 依赖;
  • 父子交易;
  • 手续费率;
  • Cycles;
  • 区块打包顺序;
  • 链重组后的交易恢复;
  • 已消费 Cell 的冲突检测。

例如:

1
2
交易 A 创建 Cell X
交易 B 在内存池中消费 Cell X

虽然 Cell X 还没有上链,B 仍可作为 A 的后继交易暂存在交易池中。因此交易池内部可以形成依赖图。

矿工或区块模板生成器会从池中选择交易,满足:

  • 依赖顺序正确;
  • 没有双花;
  • 总区块字节数不超限;
  • 总 cycles 不超限;
  • 手续费收益合适。

九、存储层

节点需要保存多类数据:

  • 区块;
  • 区块头;
  • 交易;
  • 主链索引;
  • Live Cell 集合;
  • Epoch 信息;
  • Chain state;
  • Uncle 信息;
  • 交易与区块位置索引;
  • 链重组所需元数据。

在节点内部,通常不会把“完整全局状态”抽象为以太坊式键值存储,而是重点维护:

  • 哪些 Cell 仍然 Live;
  • 哪些 Cell 已被消费;
  • Cell 所在交易和区块;
  • 当前规范链及相关索引。

链重组时,数据库需要能够:

1
2
3
4
5
6
7
8
9
Detach 旧主链区块
  ↓
恢复被旧链消费的 Cell
  ↓
撤销旧链创建的 Cell
  ↓
Attach 新主链区块
  ↓
更新 Live Cell 状态和索引

为了保证一致性,这类变更一般需要通过数据库事务或批量原子写入完成。


十、序列化与数据类型

CKB 在协议对象的序列化上使用 Molecule。它是一套面向区块链场景的二进制序列化方案。

主要用于:

  • Block;
  • Header;
  • Transaction;
  • CellInput;
  • CellOutput;
  • Script;
  • Witness;
  • P2P 消息等。

其设计目标包括:

  • 确定性编码;
  • 跨语言兼容;
  • 便于生成各语言绑定;
  • 适合哈希和共识数据;
  • 避免通用序列化框架产生歧义。

在共识系统中,这一点非常重要,因为不同节点必须对同一对象得到完全一致的字节表示和哈希结果。


十一、RPC 与 Indexer

1. JSON-RPC

节点通过 JSON-RPC 对外提供接口,常见类型包括:

  • 获取区块与区块头;
  • 查询交易;
  • 提交交易;
  • 查询 Tx Pool;
  • 获取 Tip;
  • 获取 Epoch;
  • 获取共识信息;
  • 生成区块模板;
  • 网络和 Peer 信息;
  • 调试和统计信息。

SDK、钱包、浏览器通常通过 RPC 与节点交互。

2. Indexer

底层 CKB 节点擅长按照区块哈希、交易哈希、OutPoint 查询数据,但应用往往希望查询:

  • 某个 Lock Script 下的所有 Cell;
  • 某种 Type Script 的 Cell;
  • 某个地址的资产;
  • 满足特定脚本条件的历史交易。

因此 CKB 生态中通常会使用 Indexer,将区块数据建立为适合应用检索的索引。

需要注意:

1
CKB 共识数据库 ≠ 应用查询索引

共识数据库只需保证节点验证和同步正确;Indexer 是面向钱包、浏览器和 dApp 的派生查询层。


十二、代码仓库的工程组织

仓库会随版本调整,但从职责上通常可以将相关 Rust crate 理解为以下几类。

1. 基础数据类型

常见职责:

1
2
3
4
ckb-types
ckb-jsonrpc-types
ckb-fixed-hash
ckb-hash

负责:

  • 共识数据结构;
  • Packed/Unpacked 类型;
  • 哈希类型;
  • RPC 数据与内部数据转换;
  • Molecule 生成类型封装。

2. 共识与验证

常见职责:

1
2
3
ckb-consensus
ckb-verification
ckb-script

负责:

  • 共识参数;
  • 区块验证;
  • 交易验证;
  • Cell 容量检查;
  • DAO 计算;
  • 脚本分组;
  • CKB-VM 执行;
  • Cycles 统计。

3. 链服务

常见职责:

1
2
ckb-chain
ckb-shared

负责:

  • 区块接入;
  • 主链选择;
  • Fork 处理;
  • Reorg;
  • Snapshot;
  • 跨模块共享状态;
  • 数据库提交。

4. 网络与同步

常见职责:

1
2
ckb-network
ckb-sync

负责:

  • P2P 连接;
  • 网络协议;
  • Peer 管理;
  • Header/Block 同步;
  • 区块和交易 Relay。

5. 交易池

1
ckb-tx-pool

负责:

  • 交易准入;
  • 冲突检测;
  • 依赖管理;
  • 手续费率管理;
  • 打包候选交易;
  • Reorg 后交易恢复。

6. 存储

常见职责:

1
2
ckb-db
ckb-store

负责:

  • 数据库抽象;
  • 区块和交易存储;
  • Chain index;
  • Live Cell 状态;
  • 数据库事务;
  • Snapshot 和迭代查询。

7. RPC 与应用接口

常见职责:

1
2
ckb-rpc
ckb-indexer

负责:

  • JSON-RPC 服务;
  • RPC 类型转换;
  • Cell 和交易查询;
  • 应用索引。

8. 节点入口

常见职责:

1
2
ckb-bin
ckb-app-config

负责:

  • 命令行入口;
  • 配置加载;
  • 日志初始化;
  • 数据目录;
  • 各服务启动和关闭;
  • 子命令管理。

从启动结构上,可简化为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ckb-bin
  ├─ 加载配置与共识参数
  ├─ 打开数据库
  ├─ 创建 Shared State
  ├─ 启动 Chain Service
  ├─ 启动 Tx Pool
  ├─ 启动 Network
  ├─ 启动 Sync
  ├─ 启动 RPC / Indexer
  └─ 管理退出与资源回收

十三、一笔交易的完整处理流程

可以用一笔普通转账理解整个架构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
钱包构造交易
  ↓
查询可用 Live Cells
  ↓
选择 Inputs
  ↓
创建 Outputs 和找零 Cell
  ↓
加入 CellDeps
  ↓
计算交易哈希并签名
  ↓
通过 JSON-RPC 提交

节点收到后:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
RPC 接收交易
  ↓
Tx Pool 做基础检查
  ↓
解析所有输入 Cell
  ↓
检查 Cell 是否仍然 Live
  ↓
按脚本哈希对脚本分组
  ↓
加载 CellDep 中的 RISC-V 程序
  ↓
CKB-VM 执行 Lock/Type Scripts
  ↓
检查 capacity、手续费和 cycles
  ↓
进入交易池并通过 P2P 广播

矿工打包:

1
2
3
4
5
6
7
8
9
Block Assembler 从 Tx Pool 选择交易
  ↓
保证父子依赖顺序
  ↓
生成区块模板
  ↓
PoW 挖矿
  ↓
新区块广播

其他节点确认:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
验证 Header 和 PoW
  ↓
验证每笔交易
  ↓
执行所有脚本
  ↓
更新 Live Cell 集合
  ↓
提交数据库
  ↓
更新主链 Tip

十四、架构的主要优点与代价

优点

1. 状态与所有权统一

资产、合约状态、权限都以 Cell 表达,模型相对统一。

2. 状态转换天然可审计

旧 Cell 被消费、新 Cell 被创建,状态历史边界比较清晰。

3. 并行执行潜力较好

如果交易消费的 Cell 集合互不冲突,理论上可以并行验证。

4. 密码学灵活性较强

RISC-V VM 可以运行不同签名方案、证明验证程序和密码学库,不必全部依赖虚拟机预编译合约。

5. 链上状态有明确资源约束

Cell 数据必须由相应 CKB capacity 支撑,从经济层面对状态占用收费。

代价

1. 开发心智模型不同

开发者需要理解:

  • Cell;
  • OutPoint;
  • CellDep;
  • Script Group;
  • Witness;
  • Capacity;
  • Live/Dead 状态。

2. 应用查询依赖索引

底层状态适合验证,但复杂查询通常需要额外 Indexer。

3. 交易构造相对复杂

钱包需要完成:

  • Cell 收集;
  • 容量计算;
  • 依赖解析;
  • 找零;
  • Witness 组装;
  • 手续费估算。

4. 并发状态设计需要额外考虑

多个用户同时更新同一个状态 Cell 时可能产生争用。应用通常需要通过拆分 Cell、状态分片或其他模式降低冲突。


总结

CKB 可以概括为:

一个以 PoW 保证安全性、以 Cell 表示链上状态、以 RISC-V 程序验证状态转换、并将原生代币与状态存储容量绑定的 Layer 1 区块链。

其最关键的架构关系是:

1
2
3
4
5
6
7
8
9
Cell       = 状态与资产容器
Lock       = 所有权规则
Type       = 状态转换规则
CKB-VM     = 规则执行环境
CellDep    = 代码和数据依赖
NC-Max     = PoW 共识与主链选择
Tx Pool    = 交易依赖和冲突管理
Chain DB   = 区块、索引和 Live Cell 状态
RPC/Indexer= 面向钱包和应用的访问层

与以太坊相比,CKB 更像是“可编程 UTXO + 通用 RISC-V 验证器”,而不是“全局账户状态 + 合约调用虚拟机”。这也是理解该项目代码架构的核心切入点。

与以太坊/Bitcoin 的对比(简要)

维度 Bitcoin Ethereum CKB
状态模型 UTXO(仅价值) 账户 + 全局状态 Cell(价值 + 任意数据)
合约执行 Script(非图灵完备) EVM(链上执行) CKB-VM(链上验证为主)
共识 PoW PoS(The Merge 后) PoW(NC-MAX)
扩展思路 L2 / 闪电网络 Rollup、分片等 分层 + 链下 Generator

进一步阅读