主题
新手入门:整套系统如何跑起来
本页是整个 wiki 的小白入口:不预设任何 Fabric 背景,用「一笔转账的完整旅程」把整套 CBDC 系统的运行细节串一遍。每个结论都附代码出处(仓库相对路径);想深挖某一步时,跟着文内链接进对应章节。
0. 三十秒版本
这套系统让商业银行之间转数字货币。一笔转账要过五道手:
- 银行(institution) 构造交易并提供花钱授权;
- 审计方(auditor) 检查交易合规并盖章;
- 背书方(endorser) 校验并背书;
- 排序服务(orderer) 给交易排队出块;
- 记账服务(committer) 验签、防双花、落账。
钱本身是 UTXO token(像现金:花掉旧的、产出新的),金额和持有人通过零知识证明(ZK)加密隐藏,但审计方能看见一切。所有关键私钥放在 KMS(密钥服务) 里,签名时私钥不出库。
1. 系统地图:三个面、十来个进程
| 进程 | 它是什么 | 代码位置 |
|---|---|---|
| institution | 银行的钱包后端:开钱包、选币、发转账 | cbdc-chain/cbdc-biz/app/institution/ |
| issuer | 央行发行/回笼货币 | cbdc-chain/cbdc-biz/app/issuer/ |
| auditor | 每笔交易的强制审计与签章 | cbdc-chain/cbdc-biz/app/auditor/ |
| endorser1 | 校验交易并背书;也负责把 token 公共参数部署上链 | cbdc-chain/cbdc-biz/app/endorser/ |
| bizhub | 机构准入、证书、清算编排(不碰 token 交易本身) | cbdc-chain/cbdc-biz/app/bizhub/ |
| orderer | Arma 协议:分片排序、BFT 共识、出块 | fabric-x-orderer/ |
| committer | 验签名策略 + MVCC 防双花 + 写状态库 | fabric-x-committer/ |
| sign-kms | 集中签名服务,后端 SoftHSM2,私钥不出库 | sign-kms/ |
一个关键分类:前 4 个业务应用(institution / issuer / auditor / endorser)启动时都会调 nodesdk.StartFSC 装载 FSC(Fabric Smart Client)节点 + Token SDK(cbdc-chain/cbdc-biz/pkg/common/nodesdk/fsc.go:18、sdk.go,装的是 fabricx + zkatdlog 组合 fxdlog)——它们是「FSC 节点」,能直接参与 token 协议。bizhub 不是:它的代码不 import 任何 token-sdk / FSC node 包,只做管理面。
2. 钱长什么样:UTXO + ZK
- 钱不是「账户余额」,是一张张 token(UTXO)。转账 = 花掉若干张旧 token,产出收款人的新 token + 自己的找零 token。
- token 的金额与持有人在链上是 Pedersen 承诺(看不出数值);转账附带 ZK 范围证明 证明「输入 = 输出、金额非负」。驱动叫
zkatdlog(无图隐藏版,交易关联关系不隐藏),曲线 BN254(cbdc-chain/cbdc-biz/scripts/gen_crypto.sh:85用tokengen gen zkatdlognogh.v1,未传--aries即默认 BN254,见fabric-token-sdk/cmd/tokengen/cobra/pp/zkatdlognoghv1/gen.go:131-134)。 - auditor 拿着审计密钥可以解开每笔交易——隐私对同业,透明对监管。
2.1 公共参数(pp 文件):全网的「密码学宪法」
ZK 体系需要一份全网一致的公共参数文件 zkatdlognoghv1_pp.json(内含 Pedersen 生成元、范围证明参数、issuer/auditor 公钥、Idemix 公钥)。它由 tokengen 生成(cbdc-chain/cbdc-biz/scripts/gen_crypto.sh:78-89)。
谁需要这份文件?——所有装载 Token SDK 的 FSC 节点:
| 节点 | 需要 pp 文件? | 角色 | 依据 |
|---|---|---|---|
| endorser1 | ✅ 且是部署者 | 启动后 Init 读文件并 DeployTMSWithPP 发布上链 | cbdc-biz/app/endorser/internal/biz/endorser.go:41-77,113 |
| institution | ✅ | 构造转账证明 | conf/institution-001/core.yaml(publicParameters.path) |
| issuer | ✅ | 发行证明 | conf/issuer/core.yaml 同上 |
| auditor | ✅ | 审计/解密 | conf/auditor/core.yaml 同上 |
| bizhub | ❌ | 非 FSC 节点 | 无 token-sdk import |
为什么 4 个节点都要本地文件:Token SDK 初始化 TMS 时取参优先级是 调用参数 → 本地存储 → 本地配置文件 → 链上拉取(fabric-token-sdk/token/core/tms.go:228-244),全新节点前两项为空,先读本地 publicParameters.path 文件,链上拉取只是兜底。
⚠️ 运维含义:换 auditor / issuer 公钥 = 重新生成 pp = 4 个节点都要替换文件并重载。
3. 一笔转账的完整旅程(六幕)
下面是 A 银行给 B 银行转 100 元的全过程。详细到每行代码的版本见 组合性设计 · 03 交易跨包全链路。
第一幕 · 下单与外部签名(银行客户端 ↔ institution)
- 客户端调
PrepareTransfer:institution 选币(挑出足额的 UTXO)、构造交易草稿、生成 ZK 证明,返回一段待签字节MessageToSign(cbdc-biz/pkg/views/transfer.go:267-624)。 - 客户端用银行自托管的 X.509 私钥在系统外完成 ECDSA 签名,再调
SubmitSignature交回(transfer.go:662-705,NewPreSubmittedSignatureSigner)。
设计点:花钱授权(owner 签名)不经过中心 KMS——银行自己管自己的钱包私钥。
第二幕 · 审计(institution → endorser1 → auditor)
- institution 把交易发给 endorser1;endorser1 的
AuditResponderView纯转发给 auditor(自己不签,cbdc-biz/pkg/views/audit.go:83-128)。 - auditor 跑业务规则(余额、限额、黑名单等),通过后用auditor 钱包私钥(在 KMS 里)对
MarshallToAudit()签出审计签章 σ,原路返回(pkg/views/audit.go:134起)。 - institution 验 σ 并注入交易(
pkg/views/endorsement.go:69-81)。没有 σ 的交易链上必拒:协议层强制 1-of-N auditor 签名(fabric-token-sdk/token/core/common/validator_auditing.go:22-77)。
第三幕 · 收齐签名与背书(FSC 背书模型)
CollectEndorsementsView:把第一幕的 owner 签名写进TokenRequest.Signatures[](fabric-token-sdk/token/services/ttx/collectendorsements.go:104-120)。RequestApproval:institution 节点用自己的 fabric 身份(KMS)签 proposal(fabric-token-sdk/token/services/network/fabric/endorsement/fsc/initiator.go:77→transasction.go:490-503)。- endorser1 收到后过 9 道校验闸门(含重验 ZK 证明、owner 签名、σ),用endorser 身份(KMS)签出背书(
fsc/responder.go:332-354)。 - institution 把背书装进信封,再用自己的 fabric 身份(KMS)给整个 envelope 签名(
fsc/initiator.go:106→core/generic/transaction/envelope.go的CreateEndorserSignedTX)。
第四幕 · 排序(orderer / Arma)
OrderingView.Broadcast把已签好的 envelope 广播给排序服务(fabric-token-sdk/token/services/ttx/ordering.go:74-92,广播不再签名)。- Arma 把「交易分发」与「共识」解耦:router 收稿 → batcher 按分片攒批 → consenter BFT 对批元数据定序 → assembler 拼块(
fabric-x-orderer/)。
第五幕 · 落账(committer)
- sidecar 拉块 → coordinator 建依赖图 → verifier 验namespace 签名策略(这笔交易的背书签名是否满足
cbdcnamespace 的政策)→ VC 做 MVCC 防双花(输入 token 还没被花过吗?)→ 写状态库(fabric-x-committer/service/)。 - committer 完全不懂 token:它的
go.mod不依赖 fabric-token-sdk,只验签名策略 + 读写集冲突。ZK 等 token 语义校验全部在第三幕的 endorser 侧完成。
第六幕 · 终局通知与本地记账
- committer 把
COMMITTED状态推回各 FSC 节点;institution 的 finality 监听器在一个短数据库事务里写入新 token、删除已花 token、置状态为 Confirmed(fabric-token-sdk/token/services/ttx/finality/listener.go:187-228→services/tokens/tokens.go:95-161,事务内纯 DB 操作、解析已提前缓存)。 - 收款行同样收到通知,新 token 进入其钱包,可以开始下一笔。
4. 签名速查卡:一笔转账到底签几次
5 个业务签名,其中 4 次打到 KMS(出处见上文各幕):
| # | 签名 | 谁签 | 私钥在哪 |
|---|---|---|---|
| 1 | owner 花钱授权 | 付款行钱包 | 银行自托管(外部注入) |
| 2 | 审计签章 σ | auditor 钱包 | KMS |
| 3 | proposal 签名 | institution 节点身份 | KMS |
| 4 | 背书签名 | endorser1 节点身份 | KMS |
| 5 | envelope 信封签名 | institution 节点身份(同 #3 的 key) | KMS |
记忆口诀:银行签授权,审计签放行,机构签两头(proposal+信封),背书签中间。KMS 负载分布是 institution 2 次 / endorser 1 次 / auditor 1 次每笔。
Issue(发行)同为 5 签但 owner 换成 issuer 钱包(KMS,共 5 次 KMS);Redeem(回笼)多一道 issuer 背书共 6 签。
5. 性能边界速览(为什么不能无限快)
小白只需记住三个天花板(详细论证与数据溯源见 08 扩容指南 与 性能基准溯源):
| 天花板 | 量级 | 原因 |
|---|---|---|
| ZK 证明生成(institution) | 2进2出 ~111ms/笔(Apple M1 Max 实测) | 范围证明是重密码学计算;可加核水平摊 |
| auditor 单点 | 单进程 | 协议强制每笔过 auditor,且签名身份不可分片 |
| KMS(SoftHSM2) | 单实例 ~11,000 签名/s(实测),且串行——加并发/加核不涨 | 每笔转账吃 4 次签名 ⇒ 单 SoftHSM 实例 ≈ 2,750 笔/s 的硬地板;要扩只能多进程实例 + 按 key 分片 |
数据出处:ZK 基准 fabric-token-sdk/docs/drivers/benchmark/core/dlognogh/transfer_results.txt(M1 Max);SoftHSM 基准 sign-kms/README.md:119-129(pool=1 并发 1 → ~10,200,pool=10 并发 50 → ~11,400:并发×50 只涨 12%,即串行)。
6. 小白 FAQ
Q:committer 这么快(论文 47 万 TPS),为什么整套系统到不了? A:那是账本面的能力。业务面每笔要过 ZK 证明生成、auditor 审计、KMS 签名三道闸,先碰到的是上面三个天花板。论文负载也和本系统不同(300 字节小交易 vs KB 级 ZK 交易)。
Q:bizhub 为什么不需要 pp 文件、也不签交易? A:它不是 FSC 节点,不跑 token 协议。它管机构准入、证书、清算编排——动嘴不动钱。
Q:endorser 挂了会怎样? A:转账链路断(审计转发和背书都过它)。它可以加副本(每副本独立身份+独立 DB),见扩容指南。
Q:为什么转账前 endorser 要先手动调一次 Init? A:Init 把 pp 文件部署上链(DeployTMSWithPP),链上没有 pp 时全网无法验任何 token 交易(cbdc-biz/README.md、app/endorser/internal/biz/endorser.go:41)。
Q:私钥真的不出 KMS 吗? A:经 KMS 的 4 类签名是(PKCS#11 C_Sign,私钥句柄不出库)。但 owner 钱包私钥在银行侧自托管,安全性取决于银行自己的密钥管理。
7. 下一步读什么
| 你想懂 | 去哪 |
|---|---|
| 出问题了怎么查(按报错原文定位到代码行) | 10 问题排查指南 |
| 每条链路的函数级调用链 | 11 调用链路速查 |
| 每一步的代码级细节(778 行逐步拆解) | 03 交易跨包全链路 |
| 各进程怎么部署、端口、启动顺序 | 04 部署拓扑 |
| 证书/身份体系(mTLS、MSP、CA) | 02 信任与身份模型、09 CA 与证书签发 |
| 怎么扩容、瓶颈在哪 | 08 扩容指南 |
| 每个包单独是什么 | 生态全景 → 各包章节 |
| 性能数字哪来的、可信度 | 性能基准与数据溯源 |