本文是一个关于统一注册表RFC草稿,也是对Terry最新上线的Mermaid功能的测试。
鸣谢Terry的工作。
本文以nightly-0.23的 Registry 实现为准。0.23 当前仍不是稳定发布证书;0.24 不在本文讨论范围内,也尚未发布。
从三个月前的 RFC 到现在
五月的第一版 公共注册表 RFC 当时采用了一个极简模型:
1. Git 负责源码分发和版本历史,
2. registry.json 负责版本索引
3. 链上只记录运行时真正需要的部署事实。
这个选择解决的是当时最直接的问题,即如何在不运行一套专用基础设施的情况下发布和解析 CellScript 源码包。
Jan 随后提出了一个问题:如果 namespace/name 本质上是在命名可验证对象,那么它是否也可以描述 CellScript 之外的产物,例如 CKB 本身、bootstrapper、可复现二进制或运行时 verifier?
沿着这个问题继续推演后,我认为答案是肯定的。
在 CellScript 最新的的commit上,Registry 已经不是单纯的 CellScript 包仓库,而是一个统一的 CKB artifact 注册表, 并且结合到了CellScript本身的cli工具链 cellc 中。
在这个过程中我重新设计了很多细节和边界,目前前后端已经能接受 6 类产物,并且极其严格地把 源码身份、构建身份、部署身份、可用性 拆开处理。
现在的公共 Registry 不再只承担 Git discovery,而增加了以下协调职责:
- 发布者身份与 namespace 所有权;
- 限定作用域的 capability;
- 不可覆盖的 release admission;
- 不可变对象存储;
- 隔离验证队列;
- 构建、复现与部署 evidence;
- availability 和安全隔离;
- 主网与短期 Pudge 沙盒的环境分离。
为什么不再只是一个包列表
假设开发者发布了一个 CKB 合约。
最开始,Registry 只能确认:某个开发者以某个名称提交了一组文件。这不代表文件能够编译,也不代表编译结果安全,更不代表合约已经部署到链上。
随后可能发生几件不同的事:
- Registry 在隔离环境中重新编译源码;
- 开发者发布构建出的二进制;
- 其他构建者使用同一份源码独立复现这个二进制;
- 二进制被部署到一个真实的 CKB Cell;
- 这个版本因为漏洞被标记为不建议使用。
这些事情发生在不同时间,需要不同的验证方法,也不能被一个笼统的“已发布”或“已验证”概括。
这就是当前 Registry 与最初 GitHub 包索引最大的区别:它不仅记录“东西在哪里”,还记录“我们已经检查到了哪一步”。
同一个名字下面可能是什么?
Registry 目前支持六类内容:
- CellScript 源码库;
- CellScript profile;
- CKB 合约;
- 运行时 verifier;
- 需要独立复现的二进制;
- 可以复制修改的项目模板。
它们可以使用同一套名称和版本规则,但不能以相同方式使用。
源码库可以通过 cellc add 加入项目;模板只能复制;二进制必须先检查哈希;CKB 合约只有在确认对应的 Cell 仍然存在后,才能作为可靠的 CellDep 使用。
因此,Registry 中的“类型”不是一个展示标签。它决定文件需要满足什么条件、Registry 如何检查它,以及开发者以后可以怎样使用它。
“发布成功”到底意味着什么?
发布成功只说明三件事:
- 发布者有权使用这个名称;
- 提交内容的格式和签名正确;
- 同一版本没有被覆盖。
接下来,Registry 会分别显示:
- 内容是否经过检查;
- 对应程序是否已经部署;
- 这个版本当前是否仍建议使用。
例如,一个合约可以“内容已经检查,但尚未部署”;也可以“已经部署,但后来因为漏洞被下架”。下架不会删除以前的源码、二进制或链上记录。
这些状态由实际检查结果产生,不能由发布者自己选择。
什么需要上链?
完整源码、构建日志、ABI 和审计文档体积较大,仍保存在链下不可变对象存储中,并通过哈希绑定到具体 release。
真正部署的 CKB Script 代码存在于 CKB Cell 中。Registry 的部署验证会检查:
- OutPoint 对应的 Cell 是否仍为 live;
- Cell data 是否与已发布 executable 一致;
code_hash、hash_type、Type Script identity 是否匹配;code或dep_groupCellDep 是否按真实语义解析。
0.23 的 Registry commitment 不是整个 Registry 的全局状态根,也不是任意离线文件的通用上链哈希服务。
它只绑定一个已经存在部署证据的具体 release,承诺内容包括:
namespacenamereleasesource_hashmanifest_hashartifact_hashdeployed_evidence_hash
链上 Cell data 为 CSREGv1 || commitment_hash。
这个 commitment 只证明:达到确认数的 live Commitment Cell,在最近一次协调检查时,与配置的 Scripts、具体 release 身份和已接受部署证据一致。
它不证明:
- 源码或二进制没有漏洞;
- Registry 完成了安全审计;
- 文件来源具有普遍真实性;
- Registry operators 达成了共识;
- 任意离线文件都可以通过 Registry 获得链上信任。
当前 commitment 使用配置的 custody Lock,因此它是该 custody key 作出的可归责声明,而不是去中心化共识。
目前支持发布的产物种类
| 产物类型 | 内容与用途 | 发布后的验证 | 消费方式 |
|---|---|---|---|
source_library |
普通 CellScript 源码库 | Registry verifier 重新编译,成功后 verified |
cellc add/install |
profile_library |
CellScript profile、协议模型、schema 库 | 同样重新编译 | cellc add/install |
runtime_verifier |
CKB-VM verifier、外部 TCB 程序 | 绑定源码、ELF、ABI、verifier ID、IPC ABI | fetch / verify / pin,部署后可生成 CellDep |
deployable_contract |
Rust、C、CellScript、JS 等编写的 CKB Lock/Type Script | 绑定源码、ELF、ABI、构建与 CKB profile | record-deployment / cell-dep |
reproducible_binary |
需要独立复现的构建工具或 TCB 二进制 | 初始为 evidence_required,还需独立 builder 报告 |
fetch / verify / pin |
template |
可复制、可修改的项目模板 | 验证 file map 和每个文件哈希 | cellc artifact copy,不会成为依赖 |
语言约束也是封闭的:
- CellScript library:只接受 CellScript。
- CKB executable:CellScript、Rust、C、JavaScript、other。
- Reproducible binary:Rust、C、other。
- Template:允许所有语言和 unspecified。
最重要的模型改进是:deployable_contract 和 runtime_verifier 发布时不需要假装已经部署。它们首先是 undeployed artifact;之后再用真实链上 Cell 的 OutPoint 补充部署证据。
开发者发布流程
flowchart LR
C["Coordinate identity<br/>namespace/name@release"]
S["Source identity<br/>source and manifest hashes"]
B["Build identity<br/>artifact, ABI and recipe hashes"]
D["Deployment identity<br/>network, OutPoint and Script hashes"]
O["Optional release commitment<br/>exact release plus deployed evidence"]
C -->|"Names"| S
S -->|"Builds into"| B
B -->|"May be deployed as"| D
D -->|"May be committed by configured custody policy"| O
V["Verification status<br/>pending, hash_bound, verified,<br/>evidence_required or rejected"]
P["Deployment status<br/>not_applicable, undeployed,<br/>deployed or chain_verified"]
A["Availability status<br/>active, deprecated,<br/>yanked or quarantined"]
V -.-> C
P -.-> C
A -.-> C
CellScript 源码包
cellc package verify --json
cellc publish --dry-run
cellc publish --authorise
后续已有有效 publishing capability 时:
cellc publish
非 CellScript 产物
先准备:
Artifact.toml:坐标、版本、kind、language、bundle 路径。artifact.bundle.json:profile contract 和 base64 编码的不可变对象。
然后:
cellc publish --artifact-manifest Artifact.toml --dry-run
cellc publish --artifact-manifest Artifact.toml --authorise
Bundle 目前最大只能 5 MiB,且不能覆盖同一 release。CLI 会检查对象角色、重复对象、非法字段、安全路径以及所有哈希绑定。
cellc publish --authorise 会在本地生成 delegated P-256 publishing key,将私钥保存在系统 keychain,打开一个 15 分钟、限定到精确 artifact coordinate 的浏览器授权 session。钱包批准后,CLI 会自动继续原来的发布操作。
手工 capability payload、外部钱包签名和现有 key ID 仍作为 CI、恢复及高级流程保留。
CKB 部署证据
发布 CKB executable 后,再记录部署:
cellc artifact record-deployment namespace/[email protected] \
--network mainnet \
--code-hash <hash> \
--hash-type data1 \
--dep-type code \
--tx-hash <tx_hash> \
--index 0 \
--capability-key-id <key_id>
API 会通过 CKB RPC 验证:
- OutPoint 仍是 live Cell;
- Cell data 等于已发布 executable;
data/data1/data2/type身份匹配;- Type Script hash 正确;
- DepGroup 时解析真实成员,而不是把 DepGroup 容器当代码。
验证完成才是 chain_verified。
从 DX 角度考虑的已知缺点
发布流程图
sequenceDiagram
participant C as cellc
participant B as Registry Browser
participant W as CKB Wallet
participant R as Registry API
C->>C: Generate delegated P-256 key locally
B->>W: Request scoped capability authorisation
W-->>B: Sign namespace, scope, key and expiry
B->>R: Register public capability key
B->>R: Claim namespace with wallet identity
Note over C,R: The wallet is not required for every release
C->>C: Build canonical publish payload
C->>R: Submit payload signed by delegated key
R->>R: Verify owner, scope, expiry, nonce and idempotency
R-->>C: Return accepted release and verification status
当前体验的优点
-
钱包只负责首次授权,不需要每次发布都弹钱包。
-
capability 被限定到
publish:namespace/name,私钥留在本机 keychain。 -
dry-run、不可覆盖 release、幂等重试和隔离 verifier 都已经具备。 -
“发布了”“验证了”“部署了”“仍可用”不会再混成一个含糊状态。
-
非 CellScript 产物不会被错误地当成 CellScript dependency。
当前体验摩擦
但是目前我也注意到的很明显的摩擦是:
cellc publish --authorise已经关闭首次发布的 CLI → 浏览器钱包 → CLI 自动继续闭环,但外部钱包、CI 和恢复路径仍然需要显式处理 capability payload。- 通用 artifact 虽然可以生成
Artifact.toml和artifact.bundle.json骨架,但开发者仍需填入真实对象的 base64 字节和完整 profile contract。 hash_bound只代表字节完整性,不代表安全审计、语义正确或适合生产。- reproducible build 晋级依赖 Registry policy 中相互独立的 builder 和 operator 接受流程,不能由发布者单方面完成。
- Registry readiness 只说明服务依赖和配置检查通过,不代表 Registry 中的 artifact 已达到生产安全级别。
注意:
Registry 可能还需要一些UIUX改进和产品化和部署方面的优化,所以目前未进入生产阶段。
- 主网 Registry commitment 当前为
disabled,所以可以到chain_verified,但暂时不能声称on_chain_committed。 - Pudge commitment 已
configured_and_live。 - 主网和 Pudge测试网两边的 reproducer policy 当前都为
disabled,因此reproducible_binary可以发布并进入evidence_required,但还不能完成生产级reproduced_build → verified晋级。
详细实现可见我在持续推进的 CellScript 0.23分支
