Skip to content

03 · 交易跨包全链路

当前银行侧主链路是 Facade → Wallet Node → Endorser → Auditor → Fabric-X。旧文档中的 app/institutionInstitutionOpsService 已分别改为 app/walletnodeWalletNodeOpsService

Transfer 总览

1. Facade 认证与路由

除公开方法外,Facade 要求 x-key-idx-timestampx-signature。中间件从 BizHub 同步到内存的认证资料中查找 Ed25519 公钥,对规范化请求进行验签,并把机构身份写入 context。

Wallet-bound 请求不由客户端选择节点。Facade 调用 wallet.ShardOf(wallet_id),再从配置的 Wallet Node client 集合中选择目标。当前实现只接受可服务 walletid.SingleShard 的单分片配置。

2. PrepareTransfer

Facade TransferService.PrepareTransfer 把银行侧请求映射为 WalletNodeOpsService.PrepareTransfer

Wallet Node 的处理顺序为:

  1. 校验 sender / recipients / amounts 等参数;
  2. 校验钱包权限与同一钱包是否已有 in-flight pending transaction;
  3. 选择并锁定 UTXO;
  4. 构造 Token transaction;
  5. 计算 TokenRequest.MarshalToSign()
  6. PendingTransactiontx_id 存入进程内 store;
  7. 返回 tx_id、base64 待签数据、金额与费用结果。

pending store 的实现位于 cbdc-token/app/walletnode/internal/biz/biz.go,不是数据库或 Redis 状态。

3. SubmitTransfer

Wallet Node 在解码签名成功后才从 pending store 原子 Pop(tx_id),避免格式错误请求提前丢失 pending transaction。随后 SubmitSignatureView

  1. 为普通 X.509 钱包注入预提交签名,或按 key_id 处理 policy wallet 签名;
  2. 运行 AuditAndEndorseView
  3. 广播到 Orderer;
  4. 把 selector 所有权交给 FinalityRegistry

成功响应的语义是“广播已接受,终局仍待确认”,不是“账本已经提交”。客户端需要通过交易查询接口轮询 Token SDK 的权威状态。

若广播结果不确定,代码返回 ErrBroadcastUncertain,同时保留锁并交由 finality watcher 决定最终释放或确认,避免重复花费。

4. Endorser 代理审计

AuditAndEndorseView 在银行侧节点运行,但只连接 Endorser。Endorser 的 AuditResponderView 接收交易字节,再通过 RequestAuditView 转给 Auditor。

Auditor 验证交易和规则并返回签名;Wallet Node 验证该签名确实对应公共参数中的 Auditor 身份,然后继续 owner signature、链码背书与分发流程。这个结构使 Wallet Node 无需为每笔交易直接连接 Auditor。

5. Orderer、Committer 与 finality

Submit 主路径在 broadcast 后立即返回。Wallet Node 的 FinalityWorker 异步观察交易:

  • 已提交时确认 selector 的已花费状态;
  • 明确失败时释放锁;
  • 超时或暂时不可判定时继续按 worker 策略处理。

收款方节点通过已注册的 responder 接收交易并等待 finality。FSC P2P 使用 WebSocket + TLS,实际对端由静态 resolver 与 BizHub Node Registry 同步共同维护。

6. 一步式托管转账

TransferDirect 面向私钥由 Wallet Node 持有的托管钱包:它在同一调用中构造交易、使用本地 wallet signer 签名并广播。只有证书、但没有本地私钥的钱包不能走这条路径。

7. Issue 与 Redeem

Issue

Issuer 构造发行交易后同样通过 AuditAndEndorseView 获取审计与背书,再进入排序和终局流程。Wallet Node 注册 AcceptCashView ← IssueCashView,用于接收发行结果。

Redeem

Wallet Node 同时支持 Prepare/Submit 赎回。它和两阶段 Transfer 一样生成待签数据并保存 pending transaction;提交阶段注入外部签名,经审计与背书后广播。结算请求和 RTGS 协调属于 BizHub 业务域,不改变 Token 账本的终局来源。

8. View 注册关系

节点主要 responder / initiator 关系
Wallet Node接收 transfer / identity / prepared-transfer / cash 等 View;发起 Prepare/Submit/Transfer/Redeem
EndorserAuditResponderView ← AuditAndEndorseView
AuditorAuditView ← RequestAuditView
Issuer发起 IssueCashView;同步 Auditor/Endorser resolver

Auditor 与 Endorser 注册自身地址;Issuer 与 Wallet Node 拉取所需节点快照。这不是所有节点都执行的对称注册流程。

9. 部署约束

  • Prepare 与 Submit 必须到同一 Wallet Node 实例,除非引入粘性路由或共享 pending store。
  • Token driver 取决于配置集:dev/config/token/* 是 zkatdlog,cbdc-token/conf/* 是 fabtoken。
  • SubmitTransfer 的成功不等于 finality;调用方应查询交易状态。
  • Facade 的请求验签与 Token owner signature 是两层不同签名,不能相互替代。

代码入口

  • cbdc-facade/internal/auth/
  • cbdc-facade/internal/service/transfer.go
  • cbdc-token/app/walletnode/internal/service/transfer_service.go
  • cbdc-token/app/walletnode/internal/biz/transfer_biz.go
  • cbdc-token/pkg/token/views/transfer.go
  • cbdc-token/pkg/token/views/endorsement.go
  • cbdc-token/pkg/token/views/audit.go