Files
dsh_ai1net_server/docs/分布式数据链路/分布式数据链路-详细方案与逻辑推演_20260919.md
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

1385 lines
128 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 分布式数据链路 · 详细方案与逻辑推演
> 📌 术语:本文以「分布式」指代本项目(2026-09-19 由「去中心化」更名);引用原文、DAO 专有名词与行业泛指保留原措辞。
> 版本 v1.7 | 2026-09-19 | 状态:**推演完成 · 待评审**
> 主文档:`分布式数据存储与查询-架构设计与隐私保护方案_20260919.md`(v1.2 · md5 `788f2a3a574733eae35cea3404550a7f`)
> 推演基准:`分布式数据链路-技术方案与落地路线_20260919.md` | 前身(存档):`面向公众资产平台与隐私金库-落地方案_20260919.md`
> 本文做九件事:**(一) 8 场景推演(§2)** + **(二) 多用户与规模量级(§3)** + **(三) 能力层密钥与核验(§3.6)** + **(四) 中继 / 节点信誉分层(§3.7)** + **(五) 目标形态 3 骨干 + 1,000 节点 + 50 万终端(§3.8)** + **(六) 终端升格子节点(§3.9)** + **(七) 依赖顺序裁决(§3.10)** + **(八) 账号密码与 1000 万并发登录(§3.11,v1.6 新增)** + **(九) 链上 / 链下边界与链的引入时机(§3.12,v1.7 新增)**
> ⛔ 本文**不改动**上述三份文档;对主文档的修订建议集中写在 §5,须拍板后才回填。
### 📌 v1.1 修订记录(依据用户 2026-09-19 三条拍板)
| # | 用户拍板(原话要点) | 本文落点 |
|---|---|---|
| 1 | 「**现在不做,预留扩展空间(这是面向全球的开源项目)**」 | §2.9 场景 8 第 7 步 + §3.6 V1 扩展点 + §5 已拍板段 —— 开源主仓**默认不含任何价值凭证能力** |
| 2 | 「**平台只做互联和项目协作的作用:能力共创、能力共享、能力使用分发**」 | §2.9 前置澄清(平台范围收窄)+ §4 判据 22(平台不经手资金与内容) |
| 3 | 「**预留扩展空间,先用最低成本的方式生成密钥与核验**」 | **§3.6(新增整节)** —— V0 = WebCrypto/Passkey + Merkle 包含证明 + Ed25519 签名,零额外基础设施;V1 = ZK 只留接口 |
### 📌 v1.2 修订记录(依据用户 2026-09-19 19:30 提问与 19:31 认可)
| # | 用户输入(原话要点) | 本文落点 |
|---|---|---|
| 1 | 提问:「**🛡️ 可信中继网络 … 节点信任:将中继节点的历史表现(延迟、成功率)记录在链上,用智能合约自动筛选可靠节点**」+ 认可:「**分层方案和建议不错 可以记录下来**」 | **§3.7(新增整节)** + §0 第 8 条 + §4 判据 25 / 26 + §5.0 第 4 行 + §1.2 新增 `OBS` 代号 + §5 第 14 项(由步 ① 引出) |
### 📌 v1.3 修订记录(依据用户 2026-09-19 规模提问 + 本轮核算发现)
| # | 触发 | 本文落点 |
|---|---|---|
| 1 | 用户提问:「**假设要部署3台骨干服务器 和1000台节点 以及500000个终端设备**…」 | **§3.8(新增整节)** + §0 第 9 条 + §4 判据 27 / 28 + §5 第 15 / 16 项 |
| 2 | **本轮核算发现的既有算错**(§3.4.2「峰值 TPS」行) | **已更正 §3.4.2 表格两行 + 计算示例第 7 条 + §3.4.3 判断 3 + §0 第 5 条**:年→秒除数须为 `365×86400`;100 万用户正确值 **95 TPS**(读 **951 TPS**),原值偏大 **3.65×** |
### 📌 v1.4 修订记录(依据用户 2026-09-19 子节点提问)
| # | 触发 | 本文落点 |
|---|---|---|
| 1 | 用户提问:「**假设50W终端之间有公网IP的设备也能升级为子节点呢,现有方案支持这样的情况吗**」 | **§3.9(新增整节)** + §0 第 10 条 + §4 判据 29 / 30 + §5 第 17 项 |
### 📌 v1.5 修订记录(依据用户 2026-09-19 依赖顺序提问)
| # | 触发 | 本文落点 |
|---|---|---|
| 1 | 用户提问:「**现在有必要优化吗,不优化后续做链会有影响吗,先做链后续在优化网络是不是会返工**」 | **§3.10(新增整节)** + §0 第 11 条 + §4 判据 31 |
### 📌 v1.6 修订记录(依据用户 2026-09-19 账号密码 / 并发登录提问)
| # | 触发 | 本文落点 |
|---|---|---|
| 1 | 用户提问:「**链上存 用户账号密码等信息,1000万用户 1000万同时登录 能支持并发吗,是不是无法像数据库那样做分布式 主从库那样容易扩展性能**」 | **§3.11(新增整节)** + §0 第 12 条 + §4 判据 32 |
### 📌 v1.7 修订记录(依据用户 2026-09-19 拍板:链的引入时机)
| # | 用户拍板(原话) | 本文落点 |
|---|---|---|
| 1 | 「**还是区分链上和链下的数据是对的,后续做DAO和在线游戏时在考虑链**」 | **§3.12(新增整节)** + §0 第 13 条 + §4 判据 33 + §5.0 第 5 行 + §6 自查 1 行 + §7 判断 1 条 |
---
## 0. 本文结论(十三条)
1. **架构在 7 个场景下逻辑自洽,但有 3 处真实的冲突点必须在 S0 解决**:① B 层"链上不可删" vs PIPL 47 条删除权(§2.4)② 内容哈希的"公开可验证" vs "删除后不可枚举关联"(§2.4)③ zkVM 盲验证与 B 层"平台授权可解"的边界(§2.5)。
2. **2-of-3 门限只防"单方",不防"平台 + 第三方串谋"**(§2.3 / §2.5)。这是全架构**比桥表更危险的残余风险**——桥表泄露泄露身份,双片串谋直接泄露全部数据明文。必须如实写进安全声明。
3. **最现实的攻击不是密码学被破,而是前端投毒**(§2.7):平台控制客户端下发通道 ⇒ 可窃取用户 MK。所有"平台不可解"的承诺都建立在这条之上,必须用可验证构建 + 透明日志登记来收窄。
4. **多租户密钥的分水岭只有一条判据:「平台是否需要解」**(§3.1)。需要解 ⇒ 由租户级 KEK_t 派生(平台侧);不需要解 ⇒ 由用户级 KEK_u 派生(用户侧,平台不可计算)。**不是"每租户一把 DEK"**。
5. **百万用户在写入量级上是单链可承载的**(§3.4:峰值约 95 TPS),真正的门槛在三处:**盲索引条目(约 10 GB,且是查询热路径)· 审计日志增速(约 10 GB/年,只增不减)· 读流量(约为写的 10 倍 ⇒ 约 951 TPS)**。⇒ 查询必须走只读副本 + 索引层缓存,**不得穿过共识层**。
6. **统计攻击无法消除,只能压到"需要外部辅助信息 + 大量观测"才成立**(§3.5)。这是验收判据 10 的落点,也是"号称加密但被流量分析打穿"的分水岭。
7. **DAO 是第 8 个场景,且它的前置条件是"平台承担备案与实名"**(§2.9)—— 🔴 律所口径:未登记为法人/合伙的 DAO **无法合规从事区块链信息服务**,所以 DAO 自己备案做不到,**只能是平台上的组织形态**。本轮三条拍板(价值凭证现在不做但预留 · 平台只做互联与协作 · 先上最低成本密钥与核验)已落地为 §2.9 + §3.6。
8. **「把中继节点表现记在链上、用合约自动筛选」这个形态不成立,正确形态是四层分工**(§3.7):合约不会观测(要人喂数 ⇒ 中心只是换了位置)· 当前真正缺的是 **≥3 个独立观测者**(不是链)· 逐条上链在 1,000 节点时 ≈ 33 TPS 而 99% 样本无人读 · 共识秒级 vs 选路毫秒级差 3–4 个数量级 ⇒ **链只做「周期性信任锚」,实时选路留在链下**。上链成立的唯一判据 = **观测者与被观测者互不信任 且 筛选结果需对外举证**(§3.7.4)。
9. **3 骨干 + 1,000 节点 + 50 万终端的形态推演**(§3.8):数据面不成问题(元数据 12.8 GB/年 · 密文 blob 323 GB · 每节点 0.97 GB/年);两处**形态硬伤** —— 3 台骨干 BFT `f = 0`(容 1 台作恶须 **4 台**)、1,000 节点跑经典 PBFT 是 `O(n²)` 不可行(须抽样委员会 / 分层锚定);覆盖网络**撑得住 1,000 节点(占用 13.3%)撑不住 50 万终端**(需 17–67 台中继,而目录硬上限只有 8 个地址)。
10. **终端升格为子节点:①② 已支持、③ 只到设计**(§3.9):"子节点"是**三档不同能力** —— **① 被连方**(声明端口 + 回环监听 + 一机一钥,已支持,但**纯浏览器终端做不到**)· **② 内容子节点**(peer 声明 + 分组隔离 + 取回复算,已支持)· **③ 中继子节点**(公网入向可达 + 控制面登记 + 目录下发,**无自动升格代码路径**,106 升格是人工)。五条硬门里最前置的是**目录 8 地址上限**(升格出 2.5 万台也发现不了)与**"有公网 IP"≠"入向可达"**。
11. **依赖顺序:不必先优化网络,先做链也不返工**(§3.10):判据是**「返工来自同一件事被定义两遍,不来自晚做优化」** —— 网络侧 6 项里只有**目录协议**会变兼容债,其余 5 项全是加法、后置不触碰链的数据模型;现在必须定死的是**三条复用点**(节点身份、寻址与会合、锚定落点)+**两个口径**(命名空间、世代),⛔ 不写死则返工点恰好落在「身份 / 寻址」。
12. **账号密码不上链、登录事件不上链;1000 万并发登录的瓶颈是 KDF 不是存储**(§3.11):密码摘要留在链下应用侧(链上最多存匿名锚);"链 vs 库"在登录并发上**不是变量**(同样的 KDF 账);用户的判断**正确** —— 链的**写**扩展只能分片、片内不能像主从那样加写节点,**但读的扩展与库相同**。1000 万用户在 B 层必须**分片**(峰值写 951 TPS 已抵单链下沿 ⇒ 8 片 / 每片 119 TPS)。
13. **链上 / 链下分离定为原则;链的引入时机 = 做 DAO 与在线游戏时**(§3.12):链对外提供的三样能力 —— **时序不可否认 · 多方一致性 · 防篡改日志** —— 在 V0 全都有链下等价物(**Merkle 根 + 可信时间戳锚** / **多方各留副本 + 摘要互签对账** / **哈希链**),且三者的升级动作**一律是「把单方改成多方」** ⇒ ⛔ 不触碰数据结构、密钥分层与 API 形状,**不返工**(与第 11 条同一判据)。V0 唯一硬约束:对外「**不可篡改**」必须由**用户自行举证**(Merkle 根 + 签名 + 自留副本),⛔ 不得表述为"平台保证"—— 前者在引入链后自动升级为可举证真命题,后者届时是**推翻承诺**。落层:DAO → **A 层**;在线游戏 → **B 层 + 链下执行、链上结算**(与 §3.7「链只做周期锚」同构)。
---
## 1. 推演口径与分层记号
### 1.1 三层落点记号(本文全文统一)
| 记号 | 含义 | 平台能否解密 |
|---|---|---|
| **A** | A 层分布式存储与查询层(可公开 / 半公开);密文 blob + 盲索引 token + 匿名 ID + 内容哈希 | ⛔ **永不** |
| **B** | B 层隐私金库(私有共识链,不公开但多节点共识);KV 结构 | ✅ **授权下可**(受审计约束) |
| **桥** | 窄桥匿名 ID 映射表(HMAC,独立加密、双人授权、每次留痕) | ✅ 可(最高保护级) |
| **链下** | 云对象存储(密文 blob 本体)/ 关系库 / 备份 | 视封装密钥而定 |
| **设备** | 用户侧(安全芯片 / Keychain / 原生客户端) | ⛔ 永不 |
### 1.2 参与方代号
`U`=用户设备 | `GW`=接入网关 | `BR`=桥服务 | `B`=B 层节点群 | `A`=A 层链 | `OSS`=云对象存储 | `KMS`=密钥管理(HSM) | `T3`=用户指定的第三方托管方 | `ZK`=证明层 | `LOG`=只追加审计日志 | `ADM`=平台管理员 | `OBS`=信誉观测者(多方独立,§3.7)
### 1.3 密钥分层记号(§3.1 详述)
`MK` 用户主密钥(设备生成,Shamir 分片)→ `KEK_t` 租户级 KEK(KMS 持有)→ `KEK_u`=HKDF(MK,…) 用户级 → 域密钥 `DK_idx`/`DK_kv_key`/`DEK_kv`/`DEK_data` → 记录级 `rk`
> **全文默认前提**:密码学原语一律用成熟库(libsodium / OpenSSL / 国密 SDK)或硬件模块,⛔ 不自研(主文档 §3.2 红线 1)。
> **全文默认取舍**:任何一步"是否引入新组件 / 是否花钱 / 是否触碰合规口径"都**不在本文自决**,统一收进 §5 待拍板。
---
## 2. 多场景推演
> 每个场景统一五段:**参与方 → 时序步骤(含落层与安全属性)→ 该场景的数据落点汇总 → 失败模式与处置 → 本场景的结论/遗留**。
### 2.1 场景 1 · 新用户注册与首份数据上传
**参与方**:U · GW · BR · B · A · OSS · KMS · T3 · LOG
**时序步骤**
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | 提交注册:手机号 + 邮箱验证码 + 实名信息(U→GW) | 桥(凭据校验)+ B(实名落库) | 传输层 TLS;验证码一次性;⛔ 实名**绝不进 A 层** |
| 2 | 实名 KV 写入:`key=HMAC(DK_kv_key, normalize(uid))`,`value=AES-256-GCM(DEK_kv_pii, 实名)`(GW→B) | B | key 为盲索引 token ⇒ 链上节点看不出"同属一人";value 密文;全程审计 |
| 3 | 生成 MK(32 B,设备 CSPRNG)(U) | 设备 | MK 由设备 CSPRNG 生成,**从不上传明文** |
| 4 | Shamir 2-of-3 分片:Sh1→设备安全芯片、Sh2→B 层、Sh3→T3(U→B/T3) | 设备 / B / T3 | 单方仅持 1 片 ⇒ **信息论上无法重建**(非"计算困难",是"信息不足") |
| 5 | 分片封装:Sh2 落 B 层前用 `KEK_t` 封装(B/KMS) | B | 拿到节点磁盘 ≠ 拿到可用分片;解封需 KMS 凭据 + 门限授权 |
| 6 | 生成匿名 ID:`anon_id = HMAC(DK_bridge, tenant‖user_id)`(BR) | 桥 | 裸哈希会被彩虹表/枚举反推(手机号空间极小)⇒ 必须 HMAC + 域密钥 |
| 7 | 首份数据加密:生成 `DEK_data(u, ds1)`;`rk=HKDF(DEK_data,"rec",rec_id,v1)`;`C=AES-GCM(rk, pt, AAD={anon_id,rec_id,v1})`(U) | 设备 | AAD 绑定归属与版本 ⇒ 防跨记录密文替换 |
| 8 | 上传密文:GW 转存 `C` 到 OSS(路径含 `content_hash`)(U→GW→OSS) | 链下 | 平台只见密文;OSS 凭证由 GW 持有,**不暴露给 A 层** |
| 9 | A 层链写:`{anon_id, content_hash, rec_id, v1, index_token[], blob_ptr, ts}`(GW→A) | A | ⛔ 链上**无任何明文**;仅有匿名 ID、哈希、token |
| 10 | 盲索引写入:`index_token = truncate(HMAC(DK_idx, normalize(field)‖value), b)`(GW→A) | A | 只见 token 不见明文;截断位数 b 由总量算出(§3.4) |
| 11 | DEK_data 信封备份:`wrap(DEK_data, MK)` 随数据写 A 层(U→A) | A | 🔴 **必须用 MK 包裹**——若用平台 KEK 包裹 ⇒ A 层零知识当场失效 |
| 12 | 确认返回:anon_id + content_hash + 版本号(GW→U) | — | 客户端可独立复算 content_hash 校验 |
| 13 | 审计锚定:本次全部操作事件写只追加日志并定期锚定(LOG) | 链下 + 锚 | 篡改可检测(主文档判据 9) |
**数据落点汇总**:实名/联系方式 → **B**|密文 blob → **链下 OSS**|索引与内容哈希与匿名 ID → **A**|`anon_id↔user_id` 映射 → **桥**|MK 分片 → **设备 + B + T3**|DEK_data 包裹体 → **A**
**失败模式与处置**
| 失败 | 后果 | 处置 |
|---|---|---|
| OSS 成功、A 层链写失败 | **孤儿 blob**(有密文无索引,查不到) | 客户端持 rec_id 重试链写;后台对账清理 N 天无引用的 blob(⚠️ 需并入删除权流程) |
| A 层链写成功、OSS 失败 | **悬空指针**(索引指向不存在的 blob) | 链上记录标 `pending`;客户端重传(密文是确定输入,可重算);超时未补 ⇒ 标记废弃 |
| 分片只落 2 处(Sh2 写失败) | 用户仅剩 Sh1+Sh3,仍可恢复但冗余耗尽 | 🔴 **顺序纪律:三分片全部确认落位后,才允许上传首份数据** |
| 实名 KV 写失败 | 注册未完成 | **阻断注册**——《区块链信息服务管理规定》第 8 条:未实名不得提供服务 |
| 客户端时钟漂移 | 审计时间戳不可信 | 时间戳以**服务端签注**为准,客户端时间仅作提示 |
**结论/遗留**:本场景的核心风险不在密码学,在**两步写(OSS + A 层)没有分布式事务** ⇒ 设计上接受最终一致,用对账 + 幂等补偿。⚠️ 幂等键 = `(anon_id, rec_id, version)`,重复写入必须去重(A 层链天然按 txid 去重)。
---
### 2.2 场景 2 · 用户跨设备登录与查询
**参与方**:U2(新设备)· GW · 认证服务 · B · A · OSS · T3 · LOG
**时序步骤**
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | 登录:账号 + 二次认证(U2→GW) | B(凭据哈希校验) | 密码走 Argon2id;二次认证防凭据单点 |
| 2 | 设备绑定校验:新设备指纹/设备证书(U2→GW) | B | 🔴 **这是场景 3 之外唯一能阻止"平台+攻击者合谋取片"的闸门** |
| 3 | 取回 Sh2:平台侧交出,需**双人授权 + 风控判定**(B/KMS→U2) | B | 平台持有 Sh2 ≠ 可随意使用;每次交出留痕(谁批、何因) |
| 4 | (可选)取回 Sh3(T3→U2) | T3 | 第三方须**独立于平台**验证,否则两片同源 |
| 5 | 重建 MK:Shamir 组合(U2 本地) | 设备 | MK 只在设备内存中存在;用后**显式清零**(mlock + 擦除 + 禁 core dump) |
| 6 | 派生 `DK_idx`:`HKDF(KEK_u,"dk-index")`(U2 本地) | 设备 | ✅ **用户侧派生** ⇒ 平台无法替用户构造 token(防平台做访问模式画像) |
| 7 | 构造查询 token:`token = truncate(HMAC(DK_idx, field‖value), b)`(U2) | 设备 | 查询条件明文不出设备 |
| 8 | 提交 token 到查询接口(U2→GW→A) | A | 索引层只见 token;无法反解明文 |
| 9 | 返回匹配指针列表(A→U2) | A | 只返回 blob 指针与内容哈希,不含数据 |
| 10 | 取回密文:预签名 URL 或 anon_id 签名能力(U2→OSS) | 链下 | 预签名 URL 短期有效 + 绑定 anon_id + 单次使用 |
| 11 | 取回 `wrap(DEK_data, MK)` 并用 MK 解出 DEK_data(U2→A→设备) | A→设备 | 平台全程不接触可用密钥 |
| 12 | 本地解密:`rk=HKDF(DEK_data,"rec",rec_id,v)` → 解出明文(U2) | 设备 | 校验 AAD 与 content_hash ⇒ 防替换/降级攻击 |
| 13 | 查询事件:`{anon_id, token 摘要, ts}` 写只追加日志(GW→LOG) | LOG | ⚠️ **这一步本身就是访问模式泄露面**(§3.5) |
**数据落点汇总**:MK 分片 → **设备/B/T3**|查询条件明文 → **仅设备**|token → **A**|密文 blob → **链下 OSS**|查询审计 → **LOG**
**失败模式与处置**
| 失败 | 后果 | 处置 |
|---|---|---|
| 新设备未绑定即请求分片 | 攻击者冒充用户取 Sh2 | 阻断 + 强认证 + 告警;新设备首次取片后 N 小时内限制批量拉取(冷却期) |
| Shamir 组合失败(分片损坏/版本不符) | 无法重建 MK | 分片带 checksum + 版本;回退 `Sh1+Sh3` 或 `Sh2+Sh3` 路径 |
| 设备内存被 dump(恶意软件/调试器) | MK 泄露 | TEE 隔离(L3)+ 用后清零 + 禁 core dump + 原生客户端加固 |
| token 截断过短 | 单次查询返回大量记录 | 应用层解密过滤兜底 + **单次返回行数硬上限**(判据 5 的落点) |
| 预签名 URL 被转发 | 密文被未授权者下载 | 短期(分钟级)+ 绑定 anon_id + 单次使用;⚠️ 密文即使被下载也不可解,风险等级中等 |
| **平台选择"服务端代理查询"模式** | 平台可任意扫描用户 token ⇒ 访问模式全暴露 | ⛔ 默认**不做**代理;若为体验引入,必须限定"只转发 token、不落盘、不聚合" |
**结论/遗留**:本场景的设计选择是 **`DK_idx` 由用户侧派生**。若改为平台侧持有,可支持"服务端代理查询"(体验好、离线可查),代价是平台获得完整的访问模式可见性。这是**真取舍**(各有优劣)⇒ 收进 §5。
---
### 2.3 场景 3 · 丢失密钥/设备 → 2-of-3 门限恢复
**参与方**:U3(新设备)· 恢复服务 · B · T3 · 可选守护人 · LOG · ADM
**前置状态**:用户丢失设备(Sh1 丢失),仍可登录账号,但无 MK。
**时序步骤**
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | 发起恢复:新设备登录 + 触发恢复(U3→恢复服务) | B | 加强认证(实名 + 手机 + 活体/人工审核,按风险分级) |
| 2 | 交付 Sh2:需**双人授权 + 事由登记**(ADM/B→U3) | B | 场景中**唯一**允许平台单独交出一片的路径;全程留痕 |
| 3 | 交付 Sh3:第三方独立验证(向注册手机发挑战 / 守护人多签)(U3↔T3) | T3 | 🔴 第三方验证**不得依赖平台提供的凭据**,否则两片同源 |
| 4 | 重建 MK:`Sh2 + Sh3`(2-of-3 已满足)(U3 本地) | 设备 | 平台 + 第三方各自单独都无效 |
| 5 | **重新分片**:生成 Sh1'→U3、Sh2'→B、Sh3'→T3(U3→B/T3) | 设备/B/T3 | 旧分片作废(靠 B/T3 侧删除实现) |
| 6 | **轮换 MK**(安全增强):生成 MK',重新 `wrap(DEK_data, MK')`(U3→A) | A/设备 | 🔴 旧分片即使被攻击者复制也失效(它只能重建已作废的 MK) |
| 7 | (按损失面决定)**轮换 DEK_data + 全量重加密** | A/链下 | 仅在"设备可能被解锁"时执行;代价为全量重加密 |
| 8 | 恢复后校验:抽样拉取 → 校验 content_hash → 试解密 → 试查询(U3) | 设备 | 端到端验证,避免"看起来恢复了但数据不可用" |
| 9 | 审计:完整恢复轨迹(授权人、时间、第三方验证凭据)写只追加日志 | LOG | 不可抵赖 |
**数据落点汇总**:分片三分位(设备/B/T3)|MK 只在设备内存|MK' 包裹体 → **A**|恢复审计 → **LOG**
**失败模式与处置**
| 失败 | 后果 | 处置 |
|---|---|---|
| 用户同时丢分片 + T3 不可用 | 🔴 **数据永久丢失**(架构固有代价) | 注册时强提示;可选升 3-of-5 增加冗余(⚠️ 但串谋门槛随之下降 ⇒ 真取舍) |
| 攻击者同时控制平台 + T3(串谋) | 🔴 **全部用户 MK 可重建 ⇒ A 层数据全解** | 见下方"残余风险",这是架构最高风险点 |
| 恢复流程被社工(冒充用户) | 攻击者拿到分片 | 强认证 + 冷却期 + 恢复后通知(邮件/短信)+ 恢复期禁止批量导出 |
| T3 托管商倒闭 | 无法取 Sh3 | 分片本身可迁移(只是数据,无密码学障碍);需在 SLA 中约定数据可导出 |
| 设备被找到但已被解锁过 | 攻击者已复制 Sh1 + 可能已 dump MK | 走步骤 7(轮换 MK + DEK_data 全量重加密)——**只轮换 MK 不够** |
| 只轮换 MK 不轮换 DEK_data | 若攻击者已持有 MK,轮换 MK 无效 | 判据:**攻击者是否曾获得过完整 MK** ⇒ 是 ⇒ 必须连 DEK_data 一起换 |
**🔴 本场景最重要的判断:2-of-3 的安全性上限 = "平台与第三方不串谋"这条假设**
- 门限分片的数学保证只针对**少于 2 片**的情况;2 片到手即可重建,与"谁持有"无关。
- ⇒ 因此 **`平台 + T3` 在合法程序下协同即可解开全部用户数据**(场景 5 会用到这一点)。
- ⇒ 这不是设计缺陷,但**必须如实写进安全声明**,⛔ 不能对外宣称"任何人都无法解密"。
- 缓解手段(三层叠加,缺一层则风险显著上升):
1. **T3 必须为独立法人 / 独立管理域**(最好独立司法辖区)——同一实控人手中 ⇒ 等同单点;
2. **T3 的片用 T3 独立 KEK 保护** ⇒ 平台侧即使拿到 T3 的存储也无用;
3. **取 Sh2 / Sh3 均需多角色授权 + 全量审计 + 异常告警**(单次请求量、非工作时间、跨租户批量)。
- **若"连串谋也必须不可解"是硬需求** ⇒ 唯一办法是让平台**不参与**分片,即 2-of-3 改为"用户设备片 + 用户密码派生片 + T3 片"。代价:平台彻底无恢复能力,用户丢设备 + 忘密码 ⇒ 永久丢失(回到 V3 硬代价)。⇒ **真取舍,收进 §5**。
---
### 2.4 场景 4 · 用户行使删除权(PIPL 47 条)—— 链上不可删 vs 删除义务
**参与方**:U · 平台合规 · A · B · 桥 · OSS · LOG
**核心拆解(本文的关键推演)**:删除义务要落在"四类真实副本"上,而不是落在一个"删除按钮"上。
| 副本类别 | 内容 | 能否真删 | 处置 |
|---|---|---|---|
| ① 数据本体(密文 blob) | OSS 中的密文 | ✅ 能 | 调 API **彻底删除**(含多版本/软删除/回收站),并回读验证 |
| ② 密钥材料 | `wrap(DEK_data, MK)`、DEK_data 副本 | ✅ 能 | 删除包裹体 ⇒ **加密粉碎(crypto-shredding)**作为加固(⛔ 主文档负面清单:不可作为唯一手段) |
| ③ 索引 | A 层 `index_token` 条目 | ⚠️ 部分 | 见下方"链上处理" |
| ④ 身份映射 | 桥表 `anon_id ↔ user_id` | ✅ 能 | 删除映射 ⇒ 旧链上记录变为"无主哈希" |
| ⑤ 备份 / 快照 | OSS 备份、B 层快照、LOG 备份 | ⚠️ 有窗口 | 备份保留期 ≤ 合规窗口;**宣称删除效力的最坏时延 = 备份保留期** |
**时序步骤**
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | 提交删除请求(指定数据集 / 全账号)(U→平台合规) | B(工单审计) | 请求本身走 B 层审计,不落 A |
| 2 | 定位全部引用:按 anon_id 枚举 A 层记录 + B 层 KV + 桥映射 + OSS blob(平台) | 桥→A/B/OSS | 🔴 这一步需要**桥的映射能力** ⇒ 双人授权 + 留痕 |
| 3 | 删除本体:OSS 彻底删除(含版本/回收站) | 链下 | 回读验证(删除后拉取必须 404) |
| 4 | 销毁密钥:删除 `wrap(DEK_data, MK)` + DEK_data 所有副本 | A/链下 | 即使 blob 因备份残留也不可解(加固,非主手段) |
| 5 | A 层处理:链上记录**保留**,但断开关联 | A | 见下方"两处冲突" |
| 6 | 桥表处理:删除 `anon_id ↔ user_id` 映射 | 桥 | 旧 anon_id 成为无法映射到任何现实身份的字符串 |
| 7 | B 层处理:写**墓碑记录**(tombstone)+ 真删 value 密文 | B | 墓碑 = "曾存在且已删除"的不可篡改事实,**不含任何个人信息** |
| 8 | 分片处理:若为全账号删除 ⇒ 删除 Sh2(B 层)+ 通知 T3 删除 Sh3 | B/T3 | ⚠️ 必须警告:删除后用户若再丢设备 ⇒ 永久无法恢复 |
| 9 | 生成删除证明:`commit = HMAC(DK_hash, 删除范围描述 ‖ ts)`(平台→U) | — | 用户可验证"删除已执行",⛔ 证明本身不含数据内容 |
| 10 | 审计锚定:删除事件写只追加日志 + 锚定 | LOG | 不可抵赖 |
**🔴 冲突一:B 层也是链 ⇒ 链上不可删与删除权在 B 层同样成立**
主文档说"B 层 = 私有共识链上的加密 KV 金库"。但链的特性是**不可删除** ⇒ 若 value 密文直接落链,B 层将**同样无法履行删除义务**(这与 A 层的问题一模一样,此前只在 A 层讨论过)。
**推演出的三种解法(含取舍)**
| 解法 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| **b1 状态裁剪 + 历史归档** | 链上语义只保证"最新状态";状态库支持删除;老区块靠"密文 + 销毁 DEK"变成不可解 | 改动最小;保留链式结构 | ⚠️ "不可解" ≠ "已删除"(PIPL 要求删除,不是加密丢弃);老区块仍是永久密文 |
| **b2 链上只存锚 + 链下存密文**(本文推荐) | 链上存 `key_token → {value_hash, version, DEK_id, tombstone}`;value 密文本体存链下受控加密存储 | ✅ 删除权真满足(真删链下);链条不可篡改语义保留(墓碑也是不可篡改的事实) | ⚠️ B 层不再是"纯 KV 链"(value 在链下),与 v1.1 需求表述有落差;需处理备份中的影子副本 |
| **b3 可裁剪历史的许可链** | 定期状态快照后裁剪旧区块 | 能满足删除 | 🔴 削弱"历史不可篡改"的可验证性(历史没了)⇒ B 层不可篡改性只能保证"自上次 checkpoint 以来" |
**我的建议(须拍板后回填主文档)**:采用 **b2 变体** ——
> B 层链上 = `key_token → {value_hash, version, DEK_id, status}`,其中 `status ∈ {active, tombstone}`;value 密文在链下受控加密存储;删除 = 链上写 tombstone + 链下真删密文 + 销毁 DEK。
> ✅ 删除权满足(真删)+ 不可篡改语义保留(墓碑不可撤)+ **删除可证明**(墓碑是公开可验证的"已删"事实,不含内容)。
> ⚠️ 代价:B 层形态从"纯 KV 链"变为"KV 索引链 + 链下密文库";必须处理备份/快照中的影子副本(保留期 ≤ 合规窗口)。
**🔴 冲突二:内容哈希的"公开可验证" vs "删除后不可枚举关联"**
- A 层链上存 `content_hash` ⇒ 若明文集合可枚举(证件号、已知文件、公开文档),攻击者**枚举比对哈希**即可反查"某人是否上传过 X" ⇒ 删除后依然可关联。
- 但加盐哈希(`HMAC(DK_hash, content)`)会**摧毁跨用户去重与第三方独立验证能力**(同内容在不同用户下产生不同哈希)。
- ⇒ **真取舍**,两条路各有优劣:
- **全局哈希**:保留公开可验证 + 去重;代价是存在枚举关联风险;
- **加盐哈希**:删除后真正不可关联;代价是失去第三方独立验证(须降级为"凭平台签发的凭证号 + 可吊销")。
**失败模式与处置**
| 失败 | 后果 | 处置 |
|---|---|---|
| OSS 开了版本化/软删除 | "删了"其实只剩标记 | 必须调用彻底删除 API 并**回读验证 404** |
| 备份/快照仍含密文 | 删除效力存在窗口 | 备份保留期 ≤ 合规窗口;最坏时延 = 保留期,须在用户协议中写明 |
| 用户要求删"链上哈希" | ⛔ 技术上不可行 | 提前在协议写明"链上仅存匿名化哈希、不含个人信息"(⚠️ 合规口径 ⇒ §5) |
| 只删某条记录 | 部分删除 | 逐条走 3–6 步;不得因"只删一条"而跳过密钥销毁 |
| 全账号删除后用户又丢设备 | 永久无法恢复 | 删除确认页**显式警告** + 二次确认 |
| 缓存/CDN 残留密文 | 密文可被再次下载 | 短期签名 URL + 防盗链;⚠️ 密文不可解 ⇒ 风险等级中等 |
**结论/遗留**:删除权的技术实现是**可以做到的**,但成立条件有两个**前置定性**(⛔ 均属合规口径 ⇒ §5 待拍板):① 链上"匿名化哈希 + 去映射 anon_id"是否构成 PIPL 意义上的"非个人信息";② 用户协议中"链上不可删"的告知是否足以豁免。
---
### 2.5 场景 5 · 平台受司法/监管配合请求 —— B 层可解 vs A 层不可解的边界
**参与方**:司法机关 · 平台合规/法务 · ADM · B · A · 桥 · LOG
**边界表(能配合什么 / 不能配合什么)**
| 请求内容 | 平台能否配合 | 依据 | 落层 |
|---|---|---|---|
| 用户实名信息(姓名/证件号) | ✅ 能 | B 层平台可解(授权下) | B |
| 联系方式(手机/邮箱) | ✅ 能 | 同上 | B |
| 登录与风控日志(时间/IP/设备) | ✅ 能 | 同上(⚠️ IP 亦属个人信息,仅按法定范围提供) | B |
| 账号 ↔ 匿名 ID 的映射 | ✅ 能 | **桥表存在的目的之一**;需双人授权 + 合法性审查 | 桥 |
| 链上交易流水(时间/哈希/token 结构) | ✅ 能(且本已公开) | 公开数据 | A |
| 支付信息 | ⚠️ 只能给 Token | Token 本身无意义,须向支付网关另行调取 | B |
| **用户数据本体明文(文件/内容)** | ❌ **不能** | 平台只有 MK 的 1 片,无 DEK_data | A |
| **用户私钥 / 助记词** | ❌ **不能** | 从不出设备 | 设备 |
| **批量解密全部用户** | ❌ **不能(架构级不存在此接口)** | 🔴 技术上**不提供**批量解密能力 ⇒ 这是设计上的合规保障 | — |
| 平台 + T3 在合法程序下协同重建指定用户 MK | ⚠️ **理论上可** | 2 片即可重建 ⇒ **必须如实告知这一事实** | B/T3 |
**时序步骤(配合流程)**
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | 受理法律文书 → 法务审查(主体、范围、合法性、案号)(合规) | — | ⛔ 技术层不得自行判断合法性,必须法务前置 |
| 2 | **双人授权**:两名授权人独立签署导出审批(ADM) | B(+LOG) | 防单人滥用;授权链不可抵赖 |
| 3 | 在受控环境执行范围内查询(TEE 隔离区,若有)(ADM→B) | B | 只输出请求范围内的字段;输出受限(行数上限、字段白名单) |
| 4 | 导出留痕:对导出内容计算哈希并登记(ADM→LOG) | LOG | 可证明"交付了什么、多少条、何时" |
| 5 | 通知用户(若法律允许 / 有约定) | — | 透明性 |
| 6 | 事后审计:异常检测(单次请求量、非工作时间、跨租户批量)(审计) | LOG | 内部人滥用是主要风险面 |
**失败模式与处置**
| 失败 | 后果 | 处置 |
|---|---|---|
| 请求内容超出平台技术能力(要 A 层明文) | 无法满足 | 书面回复"技术上不可行"并说明密钥架构(⚠️ **是否构成拒不配合责任 ⇒ 法律定性 ⇒ §5 待拍板**) |
| 内部人滥用配合通道 | 数据泄露 | 双人 + 范围限制 + 行数上限 + 告警 + 权限分离(申请人与执行人分离) |
| 收到"解密全部用户"的泛化请求 | 架构不支持 | 技术层**不存在**此接口;须由法务界定可执行范围 |
| 请求方要求"静默配合" | 审计与通知被绕过 | ⛔ 不允许绕过审计;"静默"只能体现在"不通知用户",⛔ 不能体现在"不记录" |
**结论/遗留(本场景最重要的坦白)**:**"平台不可解"在本架构中准确表述是"平台单方不可解"**。司法程序下平台 + T3 协同是**可解**的;若某类数据连这一点都不能接受,唯一办法是让平台完全退出分片(§2.3 的真取舍)。⇒ 这条必须写进对外的安全声明与用户协议,⛔ 不能含糊。
---
### 2.6 场景 6 · B 层单节点宕机 / 节点被攻破
**参与方**:B 层节点 N1..N4(PBFT 类,N=3f+1,f=1)· 运维 · KMS · LOG
#### 6a · 单节点宕机(崩溃容错)
| 步 | 动作 | 落层 | 安全属性 |
|---|---|---|---|
| 1 | 心跳超时检测 | B | 3 个节点仍在 quorum(N=4 ⇒ quorum=2f+1=3)⇒ **可用性不降** |
| 2 | 剔除节点,共识继续 | B | 视图切换;已提交数据不丢(其余节点有副本) |
| 3 | 节点恢复 → 从快照 + 区块追赶 | B | 必须**校验状态根**(防被喂假状态) |
| 4 | 重新准入(需授权) | B | 新/恢复节点须授权准入(判据 12) |
**失败模式**:同时宕 2 个节点(N=4)⇒ 只剩 2 个 < quorum ⇒ **停止出块**,但**不产生错误数据**——这是 BFT"安全性优先于活跃性"的正常行为。处置:只读降级 + 告警 + 尽快恢复(⛔ 不得为了"保持写入"而降 quorum,那正是"悄悄削共识假设")。
**部署建议**:至少 4 节点(容 1 故障),推荐 7 节点(容 2 故障);**跨机架/跨可用区**部署;⚠️ 全部节点在同一云账号 ⇒ 账号失陷 = 全网失陷(与项目"跨云为目标生产形态"的基调一致)。
#### 6b · 单节点被攻破(拜占庭容错)
**攻击者拿到 1 个节点的完全控制 + 该节点磁盘(含全量状态与历史)。**
| 攻击者能做什么 | 后果 |
|---|---|
| 读取全部 `key_token` 与 value 密文 | 只有密文 ⇒ 无明文泄露;但**获得完整的访问模式与改查分布** |
| 读取该节点上的 Sh2 分片(封装态) | ⚠️ 需 KMS 凭据解封;且**只有 1 片 ⇒ 信息论上不足以重建 MK** |
| 发起恶意提案 | 被其余诚实节点拒绝(f=1 在容错范围内) |
| 选择性拒绝服务 | liveness 攻击 ⇒ 超时 + 视图切换 + 审计告警 |
| 攻击者**不能**做什么(关键安全属性) | 原因 |
|---|---|
| ❌ 解密 B 层 value | 派生密钥在 KMS/HSM,节点只有密文 |
| ❌ 重建任何用户的 MK | 只有 1 片 ⇒ 少于门限的片数**不含任何信息** |
| ❌ 篡改历史 | 其余节点拒绝 ⇒ 篡改可检测 |
| ❌ 推导 A 层数据 | A 层用 `DEK_data`(用户侧密钥),B 层从未持有 |
**🔴 但必须点明的组合风险**:**若攻击者同时攻破 B 层节点 + T3 ⇒ 2 片到手 ⇒ 全部用户 MK 可重建 ⇒ A 层数据全解。**
> 这比桥表泄露更危险:桥表泄露泄露**身份**,双片串谋泄露**数据明文**。
> 缓解三层:① T3 片用 T3 独立 KEK 保护;② Sh2 在 B 层**必须封装存放**(拿到节点磁盘 ≠ 拿到可用分片);③ **分片的解封只在 TEE 内进行,且需多角色授权**(L3 + L4 组合)——即"平台持有 Sh2 ≠ 平台可随意使用 Sh2"。
**处置时序**:检测(共识行为异常/审计告警)→ 隔离(剔除)→ **凭据轮换**(该节点所有凭据)→ 评估是否需轮换数据密钥(⚡ 判据:若该节点运行时可解 `DEK_kv` ⇒ 必须轮换 KEK_t + 重加密 B 层 value;若只拿到 Sh2 ⇒ 无需轮换用户密钥)→ 取证(链上记录攻击者全部提案)→ 恢复(从快照重建,**不信任节点本地数据**)
**失败模式**
| 失败 | 后果 | 处置 |
|---|---|---|
| 控制 f+1 个节点(N=4 时控制 2 个) | **可破坏安全性**(可写入错误数据,但 value 仍不可解) | 跨管理域部署 + 准入证书 + 监控(⚠️ 4 节点全在同一台机器 ⇒ 容错形同虚设) |
| 快照/备份被投毒 | 恢复时喂假状态 | 恢复必须校验状态根 + **多节点交叉校验** |
| 全部节点丢失(灾难) | 服务中断 | 从备份恢复;⚠️ **备份是信任的根** ⇒ 加密 + 分离保管 + **真跑一次恢复演练** |
---
### 2.7 场景 7 · 管理员越权尝试解密 A 层数据(应失败 + 留痕)
**前提**:攻击者拥有**平台全部权限**(DBA + KMS 管理员 + 链节点管理员 + 桥管理员),但**没有用户设备**。
**攻击路径矩阵与结果**
| # | 路径 | 结果 |
|---|---|---|
| 1 | 直读 A 层链上数据 | ❌ **失败**——只有密文、匿名 ID、哈希、token |
| 2 | 从 OSS 下 blob,用 KMS 的 KEK 解密 | ❌ **失败**——`DEK_data` 由**用户 MK** 包裹,平台 KEK 对其无效(🔴 前提:绝不用平台 KEK 加密 A 层数据) |
| 3 | 从 B 层取 Sh2 尝试重建 MK | ❌ **失败**——只有 1 片,Shamir 信息论上不可重建 |
| 4 | 伪造用户身份走恢复流程取 Sh3 | ❌ **失败**——T3 独立验证,不依赖平台提供的凭据 |
| 5 | 攻破 T3(平台运营方实施) | ⚠️ **成功**——2 片到手 ⇒ 这是架构残余风险,必须承认(§2.3 / §2.6b) |
| 6 | 走 TEE 隔离区 | ⚪ 不算"越权成功"——只能在授权 + 范围内运行,输出受限、全程留痕(**受控通道**,而非绕过) |
| 7 | 🔴 **改代码 / 向下发恶意客户端 JS 窃取 MK** | ⚠️ **这才是最现实的攻击**——平台控制前端下发通道 ⇒ 可窃取 MK ⇒ 直接击穿"平台不可解"承诺 |
**关于路径 7(必须写进安全声明的软肋)**
> **对"平台不可信"模型,客户端加密是唯一防线,而前端投毒可击穿它。**
缓解手段(按强度递增):
1. CSP + SRI(子资源完整性)+ 禁止动态注入脚本;
2. **可验证构建**:发布物带签名,构建哈希登记到**只追加透明日志**(用户可校验"我运行的代码 = 已登记的代码",类比 Certificate Transparency);
3. 原生客户端 + 代码签名 + 系统级校验;
4. 开放客户端源码(⚠️ 商业权衡,需拍板);
5. 最彻底:本机应用 + **可复现构建**。
⚠️ **诚实结论**:前端投毒属于**不可完全防住**的一类攻击,只能降低概率 + 提高可检测性。这是所有"零知识"平台共同的软肋,⛔ 不能对外声称"绝对不可解"。
**审计留痕设计(三平面分离)**
| 平面 | 内容 | 存储 | 权限 | 保留 |
|---|---|---|---|---|
| 业务日志 | 业务操作 | 常规存储 | 运维可读 | 常规 |
| **密钥使用日志** | 谁、何时、对哪个 DEK/分片、用途、授权链 | 独立存储 | 仅密钥管理员 + 审计 | 长 |
| **管理操作日志** | 授权审批、恢复操作、桥表访问 | 独立存储 | 仅审计 | 长 |
**关键要求**:
- 🔴 **审计日志必须只追加(Merkle 日志)+ 定期锚定** ⇒ 管理员无法悄悄删;
- ⚠️ 但若管理员同时控制日志存储 + 锚定通道 ⇒ 可停掉锚定 ⇒ **必须有外部监督者**(判据 7 同款:没人验证的透明日志 = 没有);
- **异常检测**:解密量突增、非工作时间、跨租户批量、同一管理员重复失败("尝试重建"信号)。
**判据 2 的可执行测试(本轮细化)**
| 测试 | 期望 |
|---|---|
| T1 用 A 层全量数据 + 全部 KEK 尝试解密 | **0 条成功** |
| T2 用 B 层全量分片 + 全部权限尝试重建任一用户 MK | **失败**(判据 14) |
| T3 全库扫描"能解 A 层"的密钥路径 | **0 命中** |
| T4 越权/超范围查询 | **告警必触发** |
| T5 前端下发通道注入检测(可验证构建比对) | **比对不一致必告警**(本轮新增,见 §4) |
---
### 2.8 八场景横向对照(一页速查)
| 场景 | 平台可见明文 | 平台不可见 | 主要风险 | 是否已可落地 |
|---|---|---|---|---|
| 1 注册与首传 | 实名、联系方式 | 数据本体、MK | 两步写不一致(孤儿/悬空) | ✅ 可(需补对账) |
| 2 跨设备查询 | 无(token 摘要除外) | 查询条件、数据本体 | 访问模式泄露;平台代理查询的选择 | ✅ 可 |
| 3 门限恢复 | 无 | MK、Sh1 | **平台+T3 串谋** | ⚠️ 待拍板(分片参数) |
| 4 删除权 | 无 | — | B 层链上删除;哈希可枚举关联 | ⚠️ 待拍板(B 层形态 + 哈希策略) |
| 5 司法配合 | 实名、日志、映射 | 数据本体、私钥 | 单方 vs 合谋的表述 | ⚠️ 待拍板(合规口径) |
| 6 节点故障/被破 | 无 | 分片、value 明文 | 双片串谋;quorum 部署 | ✅ 可(需部署纪律) |
| 7 管理员越权 | 无 | 数据本体 | **前端投毒**;审计可被停锚 | ⚠️ 待拍板(客户端策略) |
| 8 DAO 协作网络 | 实名、成员表(V0) | 数据本体、私钥 | **备案主体缺位**;贡献值无法链上度量 | ✅ 可(V0 零新增基础设施) |
---
### 2.9 场景 8 · DAO 协作网络(能力共创 / 能力共享 / 能力使用分发)
> **场景来源**:用户 2026-09-19 定义「A 网络的一个重要场景是 DAO」,并给出三条拍板 —— ① **价值凭证现在不做、预留扩展空间**(本项目是**面向全球的开源项目**)② **平台只做互联和项目协作**:能力共创、能力共享、能力使用分发 ③ **预留扩展空间,先用最低成本的方式生成密钥与核验**。
**参与方**:`U`(OPC 个体)· `平台`(互联层 + 协作层)· `A` · `B` · `桥` · `目录`(能力目录)· `LOG`
#### 2.9.1 前置澄清(两条,缺一则本场景不成立)
1. 🔴 **DAO 自己无法完成区块链信息服务备案** —— 备案第 8 条要求真实身份认证(组织机构代码 / 身份证号),而 DAO 既非法人、通常也未登记为合伙。律所口径:「未注册为法人、合伙企业的 DAO……**无法合规从事区块链信息服务**」。⇒ **平台必须是已登记主体并承担备案与实名,DAO 只作为平台上的组织形态存在**。
2. ⛔ **平台范围收窄(本轮拍板)** —— 平台只做两件事:**① 互联**(身份、寻址、桥、网络)**② 项目协作**(能力注册 / 匹配 / 调用授权 / 分发路由 / 贡献记录)。⛔ **不做**:资金、代币、法律主体代持、内容运营、撮合定价。
#### 2.9.2 时序步骤
| 步 | 动作(参与方) | 落层 | 该步的安全属性 |
|---|---|---|---|
| 1 | **能力注册**:提交能力描述 → 生成 `cap_id`(内容寻址)+ `meta_hash`(U→平台→A) | A | ✅ 能力可公开发现、不可篡改;⛔ 价格与结算方式**不上链**(避免落入"定价服务"定性) |
| 2 | **协作组织创建**:定义成员集合 → 计算**成员资格树根**(Merkle root)→ 上链 `root + 治理规则哈希`(平台→A) | A | ✅ 只公开 root ⇒ **成员名单不公开**(最低成本的成员隐私) |
| 3 | **成员加入**:生成身份密钥(**V0 最低成本,见 §3.6**)→ 提交公钥 → 平台签发**可验证凭据(VC)** → 入树、链上只更新 root(U↔平台) | 设备/B/A | 私钥不出设备;✅ 成员表加密存 B,链上只有 root |
| 4 | **项目立项**:任一提案 → 提案内容哈希 + 截止块高上链(U→A) | A | ✅ 提案可验证、不可改 |
| 5 | **治理表决**:用身份密钥**签名投票**;提交时附 **Merkle 包含证明**证明"我在成员集合内"(U→A) | A | ✅ 投票权可验证、**身份不公开**;⚠️ V0 不隐藏"投票权大小"(V1 由 ZK 补) |
| 6 | **贡献记录**:成果内容哈希上链 + 相关成员**签名确认**(谁认领 / 谁验收)(U→A) | A | ✅ 贡献可追溯、不可抵赖;⚠️ **不产生"贡献值多少"**(见 2.9.4 硬伤 3) |
| 7 | **分账登记**:**规则哈希**上链(比例、里程碑判定条件)+ 成员签名确认;**资金由付款方链下直接付给各方**(U→A,资金**不经平台**) | A / 链下 | 🔴 规则可验证但**钱不走链、不过平台**(§2.9.1 范围收窄 + 237 口径) |
| 8 | **能力分发(调用)**:查目录 → 请求调用 → 能力方签发**调用凭据**(V0 = 签名 token,含 scope/过期/被调用方 `anon_id`)→ 平台**只做路由与分发** | A / 平台 | ✅ 平台不经手内容明文与资金;凭据可离线验证、短 TTL 可即时撤销 |
| 9 | **退出 / 解散**:退出 ⇒ 链上 root 更新 + 桥映射删除 + B 层个人信息删除(PIPL 47);解散 ⇒ 链上写"已解散"墓碑,规则哈希保留 | A/B/桥 | ⚠️ 链上匿名记录保留(账本即资产);🔴 **技术解散 ≠ 义务终止**(质保 / IP / PIPL / 税务) |
| 10 | **审计**:全部治理与协作事件写只追加日志 + 锚定(LOG) | LOG | 不可抵赖;⚠️ 需独立锚定方(判据 19) |
#### 2.9.3 数据落点汇总
| 内容 | 落层 |
|---|---|
| 能力元数据哈希 / 成员资格树 root / 提案 / 投票承诺 / 贡献哈希 / 分账**规则**哈希 / 解散墓碑 | **A 层** |
| 成员实名 / 联系方式 / 对公主体 / 成员表 / 调用凭据索引 / 退出与删除义务 | **B 层** |
| `anon_id ↔ user_id` 映射 | **桥** |
| ⛔ 代币 / 铸币权 / 余额 / 分红 / 抵押兑换 / 对外签约主体 / 成员真实身份 | **不上链** |
#### 2.9.4 五处硬伤(对"OPC + DAO"叙事的批判,必须如实写明)
1. **代币抵押 + 自动分账 = 银发〔2021〕237 号红线** —— 律所口径:DAO「因其作为基础建设的代币工具的广泛使用,**目前在中国尚无合法的立足之处**」。⇒ 本轮拍板:**现在不做**。
2. **资金腿不在链上** —— OPC 收入来自法币客户;"自动分账"要资金上链 ⇒ 法币通道被禁、稳定币被禁 ⇒ **境内不可实现**,只能"链上记账 + 链下付款"(步 7 即此形态)。
3. **贡献度不可链上验证** —— 合约能执行"按约定比例分",算不出"谁的贡献是多少"。⇒ 链只解决**规则不可篡改**,不解决**输入数据真实性**(garbage in, garbage out)。
4. **法律主体缺位** —— 无主体 ⇒ 不能签约 / 收费 / 开票 / 应诉;实务上**高概率被认定合伙 ⇒ 无限连带责任**(《合伙企业法》第 2 条);**成员退出后仍可能因链上记录被追责**;**税盾缺失**。⇒ "项目结束即可解散"只解散技术实体,义务不终止。
5. **治理现实被美化** —— 一币一票 = 财阀制(与"贡献可验证"的取向相反);投票率长期个位数;"临时组 DAO"冷启动无信用。⇒ 需设**法定人数(quorum)** + 委托投票,⛔ 不得用"沉默即同意"。
#### 2.9.5 失败模式与处置
| 失败 | 后果 | 处置 |
|---|---|---|
| 成员身份私钥丢失 | 无法投票 / 签名 / 被授权 | 用 §3.6 的设备密钥 + Passkey 生物解锁;⛔ **不得用数据侧 MK 分片替代**(职责分离) |
| 成员表泄露(平台侧) | 匿名性局部失效 | 成员表加密存 B 层 + 访问双人授权;V1 迁 ZK 后**平台也不再需要成员表** |
| 投票率过低 | 治理形同虚设 | 法定人数 + 委托投票 + 未达标即"未通过"(⛔ 无"沉默即同意") |
| 能力描述与实际交付不符 | 交付争议 | 链上只有哈希 ⇒ **争议靠线下 + 平台仲裁规则**,⛔ 链不解决 |
| 被要求平台代收代付 / 代为分账 | 越出平台范围且触发 237 风险 | **直接拒绝**;平台只提供"规则与履约凭证登记" |
| 项目解散后仍被追责 | 责任落回成员个人 | 协议中明确责任主体 = 成员个人或其登记主体;不承诺"解散即免责" |
| 贡献记录因成员退出被删 | 账本失去意义 | 链上只留**匿名化**记录(去映射 anon_id)⇒ ⚠️ 定性须法律意见(§5 第 1 项) |
#### 2.9.6 结论
**A 网络对 DAO 的定位 = 可验证的协作与能力分发账本;⛔ 不是自治的金融组织。**
本场景的全部价值在于"**跨 OPC 协作的信任与可验证性**",而**不需要**任何价值凭证 —— 这也正是"现在不做、预留扩展"可以成立的原因。
---
## 3. 多用户逻辑推演
### 3.1 多租户 key/DEK 隔离模型
**先给唯一的判据**(其余全由此推出):
> **「平台是否需要解这条数据?」——需要 ⇒ 密钥由租户级 `KEK_t` 派生(平台侧,KMS 持有);不需要 ⇒ 密钥由用户级 `KEK_u` 派生(用户侧,平台不可计算)。**
**分层模型**
| 层 | 密钥 | 生成/持有 | 用途 | 平台可否计算 |
|---|---|---|---|---|
| **L0 根** | `MK`(32 B) | 用户设备 CSPRNG;Shamir 2-of-3 分片(设备 / B / T3) | 用户密钥树的根;包裹 DEK_data | ⛔ 不可(仅 1 片) |
| **L1 租户** | `KEK_t` | KMS/HSM 持有;每租户一把 | 封装 B 层 value 的 DEK;封装用户分片 Sh2 | ✅ 可(KMS 内) |
| **L2 用户** | `KEK_u = HKDF(MK, "kek-u", tenant_id, user_id)` | 用户侧派生 | 派生全部域密钥 | ⛔ 不可 |
| **L3 域** | `DK_idx = HKDF(KEK_u,"dk-index")` | 用户侧派生(**不存储**) | 盲索引 token 的域密钥 | ⛔ 不可 |
| L3 | `DK_kv_key = HKDF(KEK_u,"dk-kv-key")` | 用户侧派生 | B 层 KV 的 key_token(防节点看出同属一人) | ⛔ 不可 |
| L3 | `DEK_kv(u, cls)` | 由 `KEK_t` 包裹的独立 DEK(按字段类:实名/联系方式/支付/风控) | B 层 value 加密(**平台授权下可解**) | ✅ 可(授权 + 审计) |
| L3 | `DEK_data(u, ds)` | 用户侧生成;用 `MK` 包裹后存 A 层 | A 层数据本体加密 | ⛔ 不可 |
| L3 | `DK_hash(u)`(可选) | 用户侧派生 | 加盐内容哈希(§2.4 冲突二) | ⛔ 不可 |
| L3 | `DK_bridge` | 平台侧,独立存储(⛔ 不在 KMS 常规域) | 生成 `anon_id` | ✅ 可(双人授权) |
| **L4 记录** | `rk = HKDF(DEK_data,"rec",rec_id,version)` | 派生,不存储 | 单条/单版本加密 | ⛔ 不可 |
**⛔ 域分离硬约束**(主文档 §4.2 约束 3 的展开):每一次派生**必须带唯一 label**(`"dk-index"` / `"dk-kv-key"` / `"rec"` / …)+ 唯一 ID(tenant_id / user_id / rec_id / version)。**禁止任何密钥跨域复用** —— 攻破 key 空间不得推出 value 密钥。
**「每租户一 DEK」的判定:❌ 不是**
| 候选 | 优点 | 缺点 |
|---|---|---|
| 每租户一把 DEK | 密钥数量最少、管理简单 | 🔴 一把被破 ⇒ 整租户全解(爆炸半径 = 整租户);无法按用户轮换;租户内用户间**可以互相解密**(越权) |
| **租户 KEK(仅封装)+ 用户级密钥**(推荐) | 爆炸半径 = 单用户;可单用户轮换;用户间天然隔离 | 密钥对象数 ∝ 用户数(但见下方"KMS 对象数"的化解) |
**🔴 一处必须澄清的成本误区**:有人担心"每用户密钥 ⇒ KMS 对象数爆炸"。实际上:
- **MK 不进 KMS**(用户生成,平台只有分片);
- 分片由**租户级 `KEK_t`** 封装 ⇒ **KMS 里的对象数 ∝ 租户数,不是用户数**;
- `KEK_u`/域密钥是 **HKDF 派生**(不存储、不进 KMS);
- `DEK_data` 用 MK 包裹后存 A 层 ⇒ **平台侧零 KMS 依赖**;
- 只有 `DEK_kv`(B 层 value)需要平台可解 ⇒ 由 `KEK_t` 包裹(密文存普通加密存储,**只有 KEK_t 本身在 KMS**)。
- ⇒ **KMS 对象数 = 租户数**(如 1,000)—— 这是完全可运营的量级。✅
**租户隔离的第二个必要件:每租户独立 salt**
- 盲索引域密钥已按用户区分,但仍需**每租户独立 salt** 参与 token 派生,否则同一标识(如邮箱)在**不同租户**下产生**相同 token** ⇒ 可跨租户判定"这两个账号是同一人"。
- 代价:**零存储增量**(token 长度不变),只多一次 HKDF。⇒ 无理由不做。
### 3.2 并发写入:B 层私有链的共识与冲突处理
**结论先行**:**跨用户无冲突(密钥空间天然不相交);同 key 冲突必须走"乐观并发控制 + 版本号",⛔ 禁止 last-write-wins。**
| 冲突类型 | 是否发生 | 机制 |
|---|---|---|
| 不同用户并发写 | ❌ 不冲突 | 域密钥不同 ⇒ `key_token` 空间不相交;共识负责**定序**,天然串行化 |
| 同一用户不同 key 并发写 | ❌ 不冲突 | 同上 |
| **同一 key 并发写**(同用户两设备改同一条) | ✅ 会 | **乐观并发控制(CAS)**:交易声明 `expected_version`,不匹配即拒绝;冲突返回客户端 rebase(类 git) |
| **热点 key**(计数器 / 配额 / 全局配置) | ✅ 会 | 分片计数器 / CRDT 计数器 / 预分配号段(⚠️ 见下方 CRDT 判据) |
| 跨 shard 原子事务 | ⚠️ 设计上应避免 | 两阶段提交代价高 ⇒ **把强不变量收敛到单 shard** |
**⛔ 明确禁止的做法**
- **last-write-wins 用于用户数据** ⇒ 静默丢数据(用户会认为"我明明改了");
- **CRDT 用于金额/配额等有不变量的数据** ⇒ CRDT 只在**可交换、可幂等**时才安全。判据:**这个操作交换后结果是否相同?** 集合类(标签、收藏)可用 OR-Set / LWW-Register;金额必须强一致。
**幂等与去重**:客户端重试必须带 `request_id`;A/B 两层链**天然按 txid 去重**,重复提交不会重复生效。
**最终性与体验的取舍(必须写进产品设计)**
- 用户数据的写入**必须等共识确认**(⛔ 不做"乐观确认")——因为丢数据的代价远高于多等 1–2 秒;
- ⇒ 写入延迟 = 共识延迟(秒级)⇒ 前端须用**异步确认模式**(提交后显示"处理中",确认后变"已保存"),而不是假装立刻成功。
**性能上限**:共识决定 TPS 上限(自研链要优化的正是这一点,主文档 §3.4.6);**热 key 会成为首个瓶颈** ⇒ 先分区、再考虑提高共识吞吐。
### 3.3 跨用户数据共享/授权("平台不可解"前提下)
**核心判断**:平台的零知识使得"平台代转授权"**不成立** ⇒ 授权必须发生在**密钥层**,而不是 ACL 层。
| 候选 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| **A 数据集级密钥 + 逐接收者包裹**(本文推荐) | 共享数据集用独立 `DEK_g`;授权 = 用接收者公钥 `wrap(DEK_g, PK_B)`;平台只搬运密文包 | ✅ 平台零知识保持;粒度到数据集;撤销可做(换版本 + 重包裹);实现成熟 | 撤销需重加密受影响数据;大量接收者时 wrap 数量 ∝ 接收者数 |
| B 代理重加密(PRE) | 平台代理把 A 的公钥密文转成 B 可解的密文,代理不看明文 | 数据所有者可离线 | ⚠️ 代理自身是信任点(需 PRE 方案的安全性证明);实现库少 |
| C 属性基加密(ABE / KP-ABE) | 策略写在密文里,凭属性密钥解密 | 一对多共享天然、粒度好 | 🔴 撤销困难、密钥管理复杂、性能开销大、生产级实现少 ⇒ **当前成熟度不足以作主方案** |
| D 平台代转(ACL 层) | 平台持密钥代解密再转给接收者 | 实现最简单 | ⛔ **破坏平台零知识**(平台必须持可用密钥) ⇒ 与架构前提矛盾,不采用 |
**推荐形态(A 的工程细化)**
- **共享数据集的 DEK 版本化**:`DEK_g_v1 → DEK_g_v2`;
- **撤销一个成员** = 生成 `DEK_g_v2`、对**剩余成员**重新 wrap、存量数据**惰性重加密**(读时重加密 + 写时强制 v2);
- **平台可见的部分**:授权图(谁授权了谁、某数据集有几个授权)⇒ ⚠️ **这本身是元数据泄露面**;缓解:授权记录放 B 层且 value 加密,key 为 `HMAC(DK_kv_key, receiver‖dataset)`,进一步可用**匿名授权槽位**(平台只见"数据集有 N 个授权",不见身份对应)。
- **⚠️ 不可逆性提醒**:授权一旦给出且数据已被 wrap,**已复制的明文无法收回**。撤销只影响未来访问,⛔ 不能让用户误以为"撤销 = 收回"。
- **平台零知识是否被削弱?** 不 —— 平台仍不可解。被削弱的是**用户之间的私密性**(B 能读 A 的数据),而这正是用户主动授权的。
### 3.4 规模推演:10 / 1 万 / 100 万用户
#### 3.4.1 基准画像(先固定假设,否则量级不可比)
| 参数 | 取值 | 说明 |
|---|---|---|
| `R` 记录数/用户/年 | **100** 条 | 轻量口径(结构化记录为主) |
| `s` 平均记录明文 | **2 KB** | ⚠️ 若含媒体则按 50 KB 另算(见 3.4.4) |
| `F` 每个记录的可查字段数 | **5** | 决定索引条目数 |
| `m` 链上每条记录元数据 | **256 B** | 含 anon_id(32) + content_hash(32) + rec_id(16) + version(4) + token 列表(20) + blob_ptr(64) + ts(8) + 对齐 |
| `e` 密文膨胀 | **1.05×** | AES-GCM + 封装 + 版本头 |
| `V` 版本保留数 | **3** | 保留 3 个历史版本 |
| `W` B 层写入放大 | **3 笔/记录** | KV 写 + 索引更新 + 审计锚 |
#### 3.4.2 主表(含计算过程)
| 项目 | 计算式 | 10 用户 | 1 万用户 | 100 万用户 |
|---|---|---|---|---|
| 记录数 | `N_u × R` | 1×10³ | 1×10⁶ | 1×10⁸ |
| **盲索引条目** | `记录数 × F` | 5×10³ | 5×10⁶ | **5×10⁸** |
| 截断位数 `b`(目标平均 3 行/查询) | `⌈log₂(条目数/3)⌉` | 11 bit | 21 bit | **28 bit** |
| 索引存储 | `条目数 × (16 B 引用 + ⌈b/8⌉)` | 5×10³×18 B ≈ **90 KB** | 5×10⁶×19 B ≈ **95 MB** | 5×10⁸×20 B ≈ **10 GB** |
| A 层链上元数据 | `记录数 × m` | 256 KB | 256 MB | **25.6 GB** |
| 密文 blob(明文) | `记录数 × s` | 2 MB | 2 GB | 200 GB |
| 密文 blob(密文) | `× e` | 2.1 MB | 2.1 GB | **210 GB** |
| 含版本保留 | `× V` | 6.3 MB | 6.3 GB | 630 GB |
| B 层 KV(实名等) | `N_u × 2.2 KB` | 22 KB | 22 MB | **2.2 GB** |
| 用户分片存储 | `N_u × 200 B` | 2 KB | 2 MB | **200 MB** |
| B 层写入笔数/年 | `记录数 × W` | 3×10³ | 3×10⁶ | **3×10⁸** |
| 峰值写入 TPS | `笔数 × 10 ÷ (365 × 86400)` | 0.001 | 0.95 | **95** |
| 峰值读 TPS(读:写=10:1) | `× 10` | 0.01 | 9.5 | **951** |
| KMS 对象数 | `= 租户数`(非用户数) | 1 | 10 | 1,000 |
**计算示例(100 万用户,逐步展开以便复核)**
1. 记录数 = 1,000,000 × 100 = **1×10⁸** 条/年;
2. 索引条目 = 1×10⁸ × 5 = **5×10⁸** 条;
3. 截断位数 = ⌈log₂(5×10⁸ / 3)⌉ = ⌈log₂(1.667×10⁸)⌉ = ⌈27.32⌉ = **28 bit**(占 4 B);
4. 索引存储 = 5×10⁸ × (16 B + 4 B) = 5×10⁸ × 20 B = **10 GB**;
5. 链上元数据 = 1×10⁸ × 256 B = 2.56×10¹⁰ B = **25.6 GB**;
6. 密文 blob = 1×10⁸ × 2 KB = 2×10¹¹ B = 200 GB;×1.05 = **210 GB**;×3 版本 = **630 GB**;
7. B 层写入 = 1×10⁸ × 3 = 3×10⁸ 笔/年;峰值 = 3×10⁸ × 10 ÷ (365 × 86,400) = 3×10⁹ ÷ 3.1536×10⁷ ≈ **95 TPS**。
> ⚠️ **v1.3 更正(本轮核算发现)**:本行原为 `笔数 × 10 / 86400`,且 1 万 / 100 万两格按「×10」递推(3.5 / 347)——**两处都不对**:`笔数` 是**笔/年** ⇒ 除数须为 **365 × 86400 = 3.1536×10⁷**;且用户数 ×1000 ⇒ TPS 亦 ×1000。**正确值:100 万用户 ≈ 95 TPS(读 951 TPS)、10 用户 ≈ 0.001 TPS**。方向性结论(写可承载、读不可穿共识层)不变,原数值偏大 **3.65×**。
#### 3.4.3 三条从量级里读出来的判断
1. **截断位数必须随总量对数增长**:`b = ⌈log₂(N/3)⌉` ⇒ 每 ×10 数据量,`b` 只增加 **3.32 bit**(约 0.4 B/条目)。⇒ 这是**可运营的**,不是膨胀问题。**但前提是被索引字段基数足够高**——低基数字段无论截断多少位都无法控制返回行数(每桶天然超大)。这正是"⛔ 不给低熵字段建盲索引"的**第二重理由**(第一重是频率还原)。
2. **KMS 不是瓶颈,索引与审计才是**:KMS 对象数 ∝ 租户数(1,000 级);而**索引 10 GB 是查询热路径**(需内存/SSD + 分片),**审计日志是增速最快的项**——按每用户每月 20 次操作 × 500 B ≈ **10 KB/年/用户 ⇒ 100 万用户 = 10 GB/年**,且**只增不减**(判据:审计保留策略必须定)。
3. **写入可承载,读不可直打共识层**:峰值写 95 TPS 落在私有共识链(PBFT 类 1,000–3,000 TPS 口径)能力内;但**读 ≈ 951 TPS** 已抵到该口径**下沿** ⇒ 查询路径**必须走只读副本 + 索引层缓存**,不得穿过共识。
#### 3.4.4 含媒体内容的口径(另一条曲线)
若 `s = 50 KB`(含图片/短视频封面等):
| 用户数 | 明文 | 密文(×1.05) | 含 3 版本 |
|---|---|---|---|
| 10 | 50 MB | 52.5 MB | 158 MB |
| 1 万 | 50 GB | 52.5 GB | 158 GB |
| 100 万 | **5 TB** | 5.25 TB | **15.75 TB** |
⇒ 此时**对象存储成本与带宽成为主要成本项**,链上部分(元数据)不变。⚠️ 具体存储费用属"花钱"项 ⇒ §5。
#### 3.4.5 规模增长的非线性风险(必须提前设计)
| 风险 | 何时出现 | 处置 |
|---|---|---|
| 索引条目超过单分片容量 | 千万级 → 亿级条目 | 按 `token` 前缀预分片;查询扇出控制 |
| 链上状态库膨胀 | 亿级记录 | 状态快照 + 冷数据归档(⚠️ 与删除权/不可篡改性联动) |
| 审计日志无界增长 | 从第一天起 | 定保留策略 + 分层(热/冷)+ 定期锚定后归档 |
| 单 key 热区(计数器) | 十万级并发 | 分片计数器 |
| 租户数量增长 | 1,000 → 10,000 | 租户 KEK 数量增长,KMS 扩容(仍是低量级) |
### 3.5 多用户下的元数据泄露面与缓解
#### 3.5.1 可见面清单(谁在什么位置能看到什么)
| 泄露面 | 可见者 | 内容 | 危害 |
|---|---|---|---|
| **访问模式** | 链节点 / 平台 | `anon_id` + 何时查了哪个 token | 推断作息、活跃度、兴趣 |
| **搜索模式** | 链节点 / 平台 | 相同 token 反复出现 | **同 token = 同值**(等值泄露);聚类"同一查询对象" |
| **频率分布** | 链节点 | 各桶/各 token 的出现次数 | 低基数字段可**频率还原**明文类别 |
| **规模与节奏** | 全网(A 层公开) | 每用户记录数、更新频率、增长曲线 | 商业情报 / 用户画像 |
| **授权图** | 平台 | 谁授权给谁、共享数据集有几人 | 社交关系泄露 |
| **时间关联** | 平台 | 注册时间与首次写入的间隔 | 可辅助识别真人/机器人 |
| **分片请求日志** | 平台 | 谁在何时请求了 Sh2 | 可识别"正在恢复/换设备"的用户 |
#### 3.5.2 攻击模型(四种必须防的)
| 攻击 | 机制 | 关键前提 |
|---|---|---|
| **频率分析** | 若攻击者知道总体分布(如"18–25 岁占 30%"),可把 token 频率映射回明文类别 | 需外部辅助分布 ⇒ **低基数字段致命** |
| **计数攻击** | 已知"有 N 个用户属于某组",从桶大小反推 | 需外部计数信息 |
| **链接攻击** | 桥表泄露 ⇒ 全部 token 历史**立即实名化**,且不可撤回 | 需拿到桥表 |
| **差分/注入探测** | 攻击者可控地插入一条已知记录,观察是否产生相同 token,反推他人值 | ✅ **截断 HMAC 部分缓解**:截断后新记录会与既有记录碰撞,无法精确反推(这正是"截断还能防试探性写入"的原理) |
#### 3.5.3 缓解矩阵(本文新增三条,与主文档 §5.6 合并)
| 手段 | 防哪个 | 代价 |
|---|---|---|
| 查询填充(定长响应 + 假记录填到固定行数) | 访问模式、规模泄露 | 带宽/存储开销 |
| 批处理 + 延迟随机化(时间粒度粗化到窗口,如 5 min 桶) | 时间关联、搜索模式 | 查询延迟上升 |
| 门限解密策略(查询解密需 N-of-M 授权) | 内鬼批量抓取 | 协作成本、延迟 |
| 输出过滤(单次返回行数硬上限) | 批量抓取 | 大结果集需分页(⚠️ 分页本身又泄露查询次数 ⇒ 需合并计费/配额) |
| 索引槽位混淆(每条记录建固定 K 个槽,部分为随机假槽) | 字段数与真实基数 | 索引膨胀 K 倍(K=2 即 +100%) |
| **匿名 ID 轮换**(每会话/每周期换 `DK_idx`) | 长期访问模式关联 | ⚠️ **索引需重建** ⇒ 仅在"轮换周期 ≥ 数据更新周期"时可行 ⇒ 高风险场景才做 |
| **查询配额 + 行为基线告警** | 慢速批量抓取 | 需运维投入 |
| 只读副本隔离(读流量不经过共识节点) | 节点侧访问模式聚合 | 副本一致性窗口 |
#### 3.5.4 诚实的结论
> **统计攻击无法完全消除**,只能压到"攻击者需要**外部辅助信息 + 大量观测**才成立"的水平。
> ⇒ 这条是验收判据 10(元数据泄露已评估)的落点,也是"**号称加密但被流量分析打穿**"的分水岭。
> ⇒ ⛔ 因此对外表述**不能用**"加密后无法分析",准确表述是"**内容不可解,模式被最小化**"。
### 3.6 能力层:密钥生成与核验的最低成本实现(v1.1 新增 · 依据用户拍板)
> 用户拍板:「**预留扩展空间,先用最低成本的方式生成密钥与核验**」。⇒ 本节按"**V0 零新增基础设施 → V1 只留接口**"两段写。
#### 3.6.1 V0 · 最低成本(零额外基础设施,全部浏览器原生能力)
| 用途 | 最低成本做法 | 成本 | 安全属性 |
|---|---|---|---|
| **身份密钥生成** | 设备 **WebCrypto**(Ed25519 / P-256,`extractable: false`)或 **Passkey / WebAuthn**(私钥进设备安全芯片) | **0**(浏览器原生,无服务器组件) | 私钥不出设备;Passkey 另得生物识别解锁与跨设备同步 |
| **成员资格核验** | **Merkle 包含证明**(成员集合 root 上链,成员只提交 path) | **0**(一次哈希链计算) | 证明"我在集合内"而**不公开成员表**;⚠️ 不隐藏"我参与了"这一事实 |
| **投票 / 贡献确认** | **Ed25519 签名** `sign(vote‖attestation, 身份私钥)` | **0** | 不可抵赖;可离线签、可批量验 |
| **治理规则完整性** | 规则文档哈希上链(版本化) | **0** | 规则不可篡改、可追溯变更 |
| **能力调用授权** | 能力方签发**签名 token**(scope + 过期 + 被调用方 `anon_id`) | **0** | 可离线验证;短 TTL ⇒ 可即时撤销 |
| **密钥恢复(轻量)** | 设备密钥 + 平台签发的**恢复凭据**(需实名 + 二次认证 + 冷却期) | 0(复用 §2.2 认证链路) | 不引入新组件;⚠️ 平台可协助恢复 ⇒ 属"受限信任",须审计 |
**🔴 V0 明确不做**:ZK 证明 · TEE · 门限签名 · 链上代币 · 链上余额 · 链上定价。
**🔴 V0 全部为"证明后端可替换"设计**:接口按 `prove(claim) → proof` / `verify(proof, claim) → bool` 抽象,V1 只换实现,⛔ 不动上层调用方。
#### 3.6.2 V1 · 预留扩展点(现在只留接口,⛔ 不实现、不排期)
| 扩展点 | 升级方向 | 触发条件(⛔ 不预设时间) |
|---|---|---|
| 匿名投票 | Merkle 包含证明 → **ZK 成员资格证明**(SP1 / RISC Zero / OpenVM,或 circom + Groth16) | 出现"连投票权大小也不能暴露"的需求 |
| 节点盲验证 | 无 → **有效性证明**(主文档 §3.4.2 的死结解) | B 层节点数上升、需要不看数据即验状态 |
| 价值凭证 | 无 → 可选**非转让、非兑换**的贡献积分 | ⚠️ 合规口径未定(§5 第 1 项),且**仅限境外部署形态** |
| 身份密钥 | 设备密钥 → 门限签名 / 社交恢复 | 出现"身份密钥丢失"的量级问题 |
#### 3.6.3 三条设计纪律
1. 🔴 **身份密钥与数据密钥职责分离** —— 身份密钥(签名 / 投票 / 授权)在设备上,**不参与 A 层数据的加解密**;数据侧仍走 `MK` + Shamir 2-of-3(§3.1)。⛔ 不得用同一把密钥既签名又解密。
2. 🔴 **扩展点是"接口预留",不是"功能占位"** —— V0 走纯签名 + Merkle;代码里⛔ 不得出现"等 ZK 上线再说"的空实现、半成品开关或死代码分支(否则等于埋一条假路径)。
3. 🔴 **面向全球开源 ⇒ 分层合规**(本轮拍板的关键推论)—— 开源主仓**默认不含任何价值凭证能力**;代币 / 积分类扩展**只能作为独立可选插件存在,且仅用于境外部署形态**,⛔ 不进主仓默认路径、⛔ 不在境内部署中出现。
⇒ **这是"现在不做"与"预留扩展空间"两句话能同时成立的唯一方式**:底座中性、扩展外挂、地域可分。
---
### 3.7 中继 / 节点信誉:分层方案与落地建议(v1.2 新增 · 依据用户提问)
> 用户提问(原话要点):「**🛡️ 可信中继网络 … 节点信任:将中继节点的历史表现(延迟、成功率)记录在链上,用智能合约自动筛选可靠节点。**」
> **一句话判定**:方向对(信誉应当客观化、可举证),但「**逐条记在链上 + 合约自动筛选**」这个形态**在当前乃至全球开放初期都不成立**;正确形态是**四层分工** —— 链**只做「周期性信任锚」**,实时选路必须留在链下。
#### 3.7.1 四条技术判断(为什么「逐条上链 + 合约筛选」做不成)
**判断 1 · 智能合约不会观测,只会读别人喂进去的数**
- 合约的执行环境决定它无法主动测量网络延迟 / 连通率;这类量必须由**合约之外**的某一方测量后再写进去。
- ⇒ **谁是喂数方,谁就掌握了「判定谁可靠」的实质权力** —— 把筛选搬到链上并不自动去中心化,只是把中心从「选路代码」挪到「喂数者」(与 §2.4 桥表同理:**链不消除信任点,只移动信任点**)。
- 判据:链保证 **完整性**(写进去的改不了),⛔ **不保证真实性**(写进去的本身可能就是假的)。
**判断 2 · 真正缺的不是「链」,而是「多方独立观测」**
- 现状(源码取证):延迟来自 **PONG 的 rtt**、成功率来自**注册 / 心跳结果** —— **全部由被观测者自己那条链路采集** ⇒ 节点可以对自身坏表现「少报」。这是**自证**,不是**他证**。
- 补法不是上链,而是:**同一台 relay 由 ≥3 个互不信任的观测者分别测量,聚合取中位数** —— 单点撒谎(或单点网络抖动误判)不改变结论。
- ⇒ 这一步**不需要链**,却能直接把「输入可信」提升一档,**是当前唯一真缺口**。
**判断 3 · 量级上「逐条上链」不可行**
- 设每条信誉样本上链一次:**100 节点 × 每 30 s 一条 ≈ 3.3 TPS**(单链勉强)→ **1,000 节点 ≈ 33 TPS**(已吃掉单链很大一块)→ 若按「**每次转接都记**」(转接量 ≫ 节点数,约 ×100 量级)⇒ **数千 TPS**,**超出单链能力**。
- 而且这类样本 **99% 永远无人读取** ⇒ 等于为极小概率的争议场景**支付常态成本**。
- 正确做法:**高频样本落链下**(可聚合、可滚动窗口、可丢弃),**只有聚合摘要周期上链**。
**判断 4 · 时间尺度不匹配:共识秒级 vs 选路毫秒级**
- 选路必须在**毫秒**内出决定;链的最终性是**秒级**(跨地域更慢)—— 差 **3–4 个数量级**。
- ⇒ **链不能当实时筛选器**。链上能承担的只有「**周期性信任锚**」:把某时刻的信誉快照钉住,供事后争议 / 申诉举证。
#### 3.7.2 分层方案(四层各归其位)
| 层 | 回答什么问题 | 现在的实现 | 现状 |
|---|---|---|---|
| ① 准入 / 身份 | 「**这台机器是不是我们信任的?**」—— 一机一钥 + 离线信任根 + 本地校验 + 单台吊销 | 覆盖网络 `identity.ts`(四层密钥模型;离线信任根照抄 Tailscale Tailnet Lock 思路) | ✅ **已有** |
| ② **观测**(本方案核心缺口) | 「**它的表现(延迟 / 成功率)是谁测的?**」—— ≥3 个**互不信任**的观测者分别测,聚合取中位数 | 现为**自采**(PONG 的 rtt + 注册 / 心跳结果) | ⚠️ **缺** |
| ③ 信誉载体 | 「**凭什么相信这个结论没被事后改过?**」—— 高频样本**链下**累积 + **周期性把聚合摘要锚定到 A 层** | 无 | 未做(**不急**) |
| ④ 选路决策 | 「**这次选谁?**」—— **毫秒级、读本地缓存快照**,⛔ 不查链 | 覆盖网络 `placement.ts`:`score = w(0.55·speed + 0.45·load) − failurePenalty × recentFailures`,满载为唯一硬门 | ✅ **已有** |
> **一句话记法**:**身份在准入层 · 真值在观测层 · 证据在信誉层 · 决定在选路层**。
> 🔴 **信誉不能当安全边界**:某节点「是否可信」由**准入层身份**判定(层 ①);信誉只回答「**这次选谁更快**」。⛔ 不得用「信誉低」代替「吊销密钥」。
#### 3.7.3 三步落地建议(严格按序,⛔ 不可跳步)
| 步 | 做什么 | 为什么这一步先做 | 前置依赖 | 成本量级 |
|---|---|---|---|---|
| **①** | **补「多方观测」**:同一 relay 由 **≥3 个独立观测者**分别测延迟 / 成功率,聚合取中位数;观测者**不共享**测量口径 | **不需要链**就能把「输入可信」从**自证**提到**他证** —— 当前**唯一真缺口** | 无(复用现有 relay 链路) | 低 |
| **②** | **信誉快照锚定**:周期性(如每 10 min 或每小时)把聚合摘要写入 A 层 | 用途明确且**有限** —— 争议 / 节点申诉时**可举证**、**不可事后篡改**;⛔ 不承担实时功能 | ① 必须已成立(否则锚上去的是假数据) | 低(一次哈希上链) |
| **③** | **链上规则重排**(**仅周期性**) | 只有当**第三方节点可自主加入、选点规则需要公开裁决**时才值 | ① + ② 均成立 | 中(合约 + 治理) |
⛔ **明确不做**:**「每笔转接上链」** · **「合约实时筛选节点」** · **「用链上延迟数据作为选路输入」**。
#### 3.7.4 判据:什么时候「把信誉放上链」才值
> **须同时满足两条**:
> ① **观测者与被观测者互不信任**(数据来源天然不可信 ⇒ 必须多方独立);
> ② **筛选结果需要对外举证**(争议裁决 / 准入决定 / 对外审计)。
>
> **现状**(节点全部自运维、同属一个运营主体)⇒ **两条都不满足** ⇒ **现在不需要链**,缺的是**多方观测**。
> **全球开放后**(第三方节点自主加入)⇒ **只有第 ② 条成立,且只成立于「周期摘要」这一小块** ⇒ ⛔ **不是「每笔上链 + 合约筛选」**。
#### 3.7.5 与既有设计的衔接(⛔ 不另起炉灶)
- **复用,不新建**:准入层直接复用 `identity.ts`(一机一钥 + 离线信任根 + 本地校验 + 单台吊销);选路层直接复用 `placement.ts`(毫秒级本地打分,**天生不依赖链**)。**本方案只新增「层 ② 观测」这一块**。
- **上链量对比**:本方案 = **每小时 1 条摘要**,与节点数**无关**(O(1));「逐条上链」= O(节点数 × 采样频率 × 转接次数) ⇒ **两者差 3 个数量级以上**(推导见 §3.7.1 判断 3)。
- **可分段交付**:即使将来完全不做第 ② / ③ 步,**只做 ① 也能独立交付价值**(选路更稳、少被单点坏数据带偏);反之若先上链却没有 ①,锚的是一堆自证数据 —— **方向反了**。
- **未验证项(须实测,⛔ 不猜)**:① 单 relay 的连接 / 内存上限(现仅有 `relay-mem-calibrate.mjs` **单机标定**,**无规模曲线**)② 控制面(47)的 `hostId` 命名空间与 DB 登记在 100 节点时**是否成单点** ③ 候选链目录变更流程(删 `/var/lib/dshs/overlay/directory.json` + 二次重启控制面)在加节点时的**运维瓶颈**。
#### 3.7.6 结论
让「选谁」这件事(a)**输入可信**、(b)**结论可举证**,才是目的;**「上链」只是(b)的一种手段**。
⇒ 当前(自运维)只缺 **(a)的实现 = 多方观测**,**不需要链**;全球开放后需要的是 **(b)的一小块 = 周期摘要锚定**。
⇒ ⛔ 完整形态**永远不是**「每次转接写链 + 合约实时筛选」,而是**四层分工 + 链只做周期性信任锚**。
---
### 3.8 目标形态推演:3 台骨干 + 1,000 节点 + 50 万终端(v1.3 新增 · 依据用户提问)
> 用户提问(原话):「**假设要部署3台骨干服务器 和1000台节点 以及500000个终端设备,这A B两层链如何运行,普通服务器能否运行需要什么配置,现在的覆盖网络能否支撑运行**」
> 本节全部数值沿用 §3.4.1 基准画像(`R=100` / `s=2 KB` / `F=5` / `m=256 B` / `e=1.05` / `V=3` / `W=3`),与 §3.4.2 同口径。
#### 3.8.1 一句话结论(三条)
1. **数据面完全不是瓶颈**:50 万终端全年只产生 A 层链上元数据 **12.8 GB**、密文 blob **323 GB**(含 3 版本),摊到 1,000 节点每台每年 **0.97 GB**。
2. **两处形态级硬伤**(不是容量问题,是设计问题):① **3 台骨干做 B 层共识 ⇒ 拜占庭容错 `f = 0`**(只防宕机,不防作恶)② **1,000 节点跑经典 PBFT ⇒ `O(n²)` = 每轮约 10⁶ 条消息**,不可行。
3. **现有覆盖网络撑得住 1,000 节点(单台中继容量 7,515,占用 13.3%),撑不住 50 万终端**:终端全挂中继需 **67 台**(2C2G 口径)或 **17 台**(4 GB 专用口径);且 **目录结构硬上限 = 8 个中继地址 / 一份目录**(`directory.ts:70`),现有机制**下发不了**这么多中继。
#### 3.8.2 规模账(50 万终端)
| 项目 | 计算式 | 50 万终端 | 100 万对比 |
|---|---|---|---|
| 记录数 / 年 | `N_u × 100` | 5×10⁷ | 1×10⁸ |
| 盲索引条目 | `× 5` | 2.5×10⁸ | 5×10⁸ |
| 截断位数 `b` | `⌈log₂(条目/3)⌉` | **27 bit**(4 B) | 28 bit |
| 索引存储 | `条目 × (16 B + 4 B)` | **5 GB** | 10 GB |
| A 层链上元数据 / 年 | `记录数 × 256 B` | **12.8 GB** | 25.6 GB |
| 密文 blob(含 3 版本) | `记录数 × 2 KB × 1.05 × 3` | **323 GB** | 630 GB |
| 媒体口径(`s=50 KB`,含 3 版本) | `× 50 KB × 1.05 × 3` | **8.06 TB/年** | 15.75 TB |
| B 层 KV | `N_u × 2.2 KB` | **1.1 GB** | 2.2 GB |
| 用户分片 | `N_u × 200 B` | **100 MB** | 200 MB |
| **峰值写 TPS** | `笔数 × 10 ÷ (365 × 86400)` | **≈ 48** | 95 |
| **峰值读 TPS** | `× 10` | **≈ 476** | 951 |
| KMS 对象数 | `= 租户数` | ≤ 1,000 | 1,000 |
**每台节点(1,000 台均摊)**:非媒体 **0.97 GB/年**;媒体口径 **24.2 GB/年**(均已含 3 副本)。⇒ **普通 100 GB 盘即可(媒体口径建议 1 TB)**。
#### 3.8.3 A / B 两层怎么跑(角色分配)
| 层 | 谁在跑 | 做什么 | 50 万终端下的量 |
|---|---|---|---|
| **A 层**(公开链 + 云对象存储) | 1,000 节点 + 3 台骨干 | 链上元数据 12.8 GB/年;blob 走对象存储(**不进链**);1,000 节点做**分片持有 + 可验证** | 每台 0.97 GB/年(非媒体)/ 24.2 GB/年(媒体) |
| **B 层**(私有共识链) | **3 台骨干**(本文建议 4 台) | KV 全量 1.1 GB(实名 / 密钥分片 / 桥表);峰值写 ≈ 48 TPS | 单台常驻 1.1 GB 状态 + 索引热路径 |
| 覆盖网络(互联层) | 3 台骨干 + 1,000 节点(有公网 IP 者可升格中继) | 信令、打洞协调、兜底转发 | 1,000 节点在册仅占单台中继 **13.3%** |
| 终端(50 万) | 用户设备 | 只拨出;客户端加密;盲索引 token 在设备侧算 | **零平台侧成本**(§3.6 V0 全浏览器原生) |
**A 层共识形态(现在是空白,必须定)**
- ⛔ **1,000 节点不能跑经典 PBFT**:消息量 `O(n²)` ⇒ `n=100` 时 10⁴ 条、`n=1,000` 时 **10⁶ 条/轮**(每轮按 500 B 计 ≈ 500 MB),带宽与 CPU 都不成立。
- ✅ 三条可行路(代价由低到高):① **周期 Merkle root 多签锚定**(最省,与 §3.7「链只做周期性信任锚」同一结论)② **抽样委员会**(VRF 选 100–200 节点轮值出块)③ **分层共识**(1,000 台分 33 组 × 30 台 ⇒ 组内选代表 ⇒ 33 节点代表层)。
**B 层共识形态(硬伤,必须二选一)**
- BFT 门槛 `n ≥ 3f+1`:**3 台 ⇒ `f = 0`**;容 1 台作恶需 **4 台**,容 2 台需 **7 台**。
- ⇒ 3 台只能做 **CFT(Raft 类)**:可容 1 台**宕机**,**不能容 1 台作恶**(无法区分"宕机"与"撒谎")。这与 §2.6 用的 `N=4 / f=1` 口径**不一致** ⇒ 要么改 4 台,要么在安全声明里如实写"3 节点仅崩溃容错",且 §2.6b(节点被攻破)在 B 层**无解**。
#### 3.8.4 普通服务器能不能跑 / 配置单
**结论:能跑,但"角色"决定档位 —— 2C2G 能当节点或中继,当不了骨干。**
| 角色 | 数量 | CPU | 内存 | 磁盘 | 带宽 | 依据(实测口径) |
|---|---|---|---|---|---|---|
| **骨干**(B 层共识 + 控制面 + 桥) | 3(建议 **4**) | **8 核** | **32 GB** | NVMe 1 TB | 200 Mbps–1 Gbps | B 层状态 1.1 GB + 索引 5 GB 热路径 + 共识验签(CPU 密)+ 45% 余量 |
| 中继(**2C2G 云轻量**,可用内存 ≈1 GB) | **67** | 2 核 | 4 GB | 40 GB | 100 Mbps | `MEM_PER_HOST` 0.06 MB ⇒ `C_MEM` 16,700 ⇒ `MAX_HOSTS` **7,515** |
| 中继(**4 GB 专用**,裸机给 relay) | **17** | 2–4 核 | 4–8 GB | 40 GB | 100 Mbps | `C_FD` 65,536 成新上限 ⇒ `MAX_HOSTS` **29,491** |
| **普通节点**(A 层分片) | 1,000 | **2 核** | **4 GB** | **100 GB**(含媒体 ⇒ 1 TB) | 10 Mbps | 0.97 GB/年(非媒体)/ 24.2 GB/年(媒体,含 3 副本) |
| 终端 | 500,000 | 用户设备 | — | — | — | 只拨出;WebCrypto / Passkey(§3.6 V0) |
**两条"没配就崩"的配置项**
1. 🔴 **中继 fd 上限必须拉起**:`FD_PER_HOST = 4` ⇒ fd 还是默认 1024 时**单台只能装 256 台**(不是 7,515)。必须 `LimitNOFILE = 262144`(47 实测值)。
2. 🔴 **`--max-hosts` 必须显式下发**:默认 `0` = **不限**(`main.ts:70`)⇒ 不限等于既无硬门也无软门,超载时表现为"**静默变慢**"而非"明确拒绝"。按 §5.2 公式下发(47 / 106 现为 7,515)。
#### 3.8.5 现有覆盖网络能不能支撑(逐项判定)
| 维度 | 现有能力(实测 / 取证) | 判定 |
|---|---|---|
| 1,000 节点在册 | 单台中继 7,515 ⇒ 1,000 = **13.3%** | ✅ **够**(且只用得上 1 台;第 2 台今天是容灾不是容量) |
| 50 万终端挂中继 | 7,515 / 29,491 每台 ⇒ 需 **67 / 17 台** | ❌ **现有 2 台远远不够** |
| 目录下发 | `MAX_ENTRIES = 8`(`directory.ts:70`,防放大设计) | ❌ **硬上限**:一份目录最多 8 个地址 ⇒ 下发不了 17–67 台 ⇒ 必须改目录结构(分片 / 二级目录) |
| 控制面带宽 | 心跳 `6.7 B/s × 50 万 = 26.8 Mbps` | ✅ 3 台骨干(各 100 Mbps)可承载,约占 9% |
| 数据面 | 峰值读 476 TPS × 2 KB ≈ **0.95 MB/s** | ✅ 可忽略 |
| **带流量 per-host 内存** | 0.06 MB/台是**空闲会话**实测;每流高水位 **256 KB**(`server.ts:101`)+队列上限 **1 MB**(`:98`) | ⚠️ **最大不确定项**:终端满流时 per-host 是 MB 级 ⇒ **7,515 只在"以空闲会话为主"时成立**(未测已登记) |
| 1,000 节点共识 | 经典 BFT 为 `O(n²)` | ❌ 需抽样委员会 / 分层(§3.8.3) |
| 3 台骨干 BFT | `n ≥ 3f+1` ⇒ `f = 0` | ❌ 须 4 台,或如实降级为 CFT |
| 加中继的运维 | 目录变更需"删 `directory.json` + 二次重启控制面" | ⚠️ 加 17–67 台时是瓶颈 ⇒ 需先做**目录热更新** |
> **净判定**:覆盖网络在「**1,000 节点**」这一维上已经够用(7.5× 余量);在「**50 万终端**」这一维上不够,而**缺的不是机器、是两处机制** —— ① 目录只能下发 8 个中继地址 ② per-host 内存只有空闲会话实测值。
#### 3.8.6 按序要补的三件事
1. **量测"带流量 per-host 内存"** —— 唯一还没量的关键口径;它同时决定"17 台还是 67 台"与"终端能不能挂中继"。
2. **改目录结构** —— 支持 ≥64 个中继地址 + **热更新**(取消二次重启控制面)。
3. **定 A 层共识形态(§3.8.3 三选一)+ 把骨干改为 4 台**(两处形态硬伤)。
---
### 3.9 终端升格为子节点:现有方案支持到哪一步(v1.4 新增 · 依据用户提问)
> 用户提问(原话):「**假设50W终端之间有公网IP的设备也能升级为子节点呢,现有方案支持这样的情况吗**」
> 判据先行:**"子节点"是三个不同的档位,能力与成本差一个量级** —— 必须分开判,不能笼统答"支持/不支持"。
#### 3.9.1 先分档(三档"子节点")
| 档 | 能力 | 门槛 | 代价 |
|---|---|---|---|
| **① 被连方** | 别人能连到它(host↔host 流) | 在册 host + **声明端口** + 回环监听 + 一机一钥 | 需**原生客户端/守护进程** |
| **② 内容子节点** | 帮同组 peer 取块 / 持有块 | peer 声明 + 分组隔离 + 读侧复算 | 块缓存配额(默认 **64 MiB**) |
| **③ 中继子节点** | 帮别人转发与会合 | **公网入向可达** + 控制面登记 + 目录下发 | 凭据运维面(万级) |
#### 3.9.2 判定:①② **已支持**,③ **只到设计、未到实现**
- **① 已支持**:`server.ts:153` —— relay 侧密钥表为空 ⇒ **所有 `HELLO` 被拒(默认拒绝)**;`:1176` —— worker「注册即开回环监听、**必须声明端口**」;`keys.ts` 每 host 一密钥(爆炸半径 = 那一台)。
- **② 已支持**:`content/peer.ts:31` 的 `PeerDeclaration{name, network, group, holds, epoch}` + 分组键 `<network>|<group>` + **跨组显式拒绝并计数**;发现源**就是 relay 的在册会话表**(`peer.ts:24`,⛔ 不新开公网口);取块走 `source.ts:57` 五档链,`peer` 档已在装配点接线并**复算块 id**(不符即丢弃、不算命中)。
- **③ 未实现**:`接续入口` 已定「**有公网 IP 的节点升格为中继候选**」(清单 §3 关键决定),但**目录里的 `relays` 由签发的目录文档给出**(`directory.ts:305`,`slice(0, MAX_ENTRIES)`)⇒ **代码里没有"自动升格"路径**;现有第二台中继(106)的升格是**人工执行**(T19 / S8)。
#### 3.9.3 五条硬门(代码级,决定"能不能做到")
1. 🔴 **纯浏览器终端做不了 ①** —— 要当被连方就得**声明端口 + 开回环监听**,而 relay 默认且建议只绑 `127.0.0.1`(`server.ts:150`)、`no-ports` 一律拒绝 ⇒ **Web 终端只能"拨出+取块",不能"被连"**。要当子节点必须是**原生客户端/桌面守护进程**。
2. 🔴 **升格必须由控制面登记并下发密钥** —— **"自动升格" ≠ "自动生效"**;没有凭据那一步,HELLO 直接被拒。
3. 🔴 **目录是比机器数量更前置的墙** —— `MAX_ENTRIES = 8`(`directory.ts:70`)⇒ 即便升格出 2.5 万台子节点,**新终端也发现不了它们**(见 §3.8.5 同一堵墙)。
4. ⚠️ **"有公网 IP" ≠ "入向可达"** —— `directory.ts:435 isPublicHost` 只剔除回环与私网;**家宽 NAT / 运营商 CGNAT 下"本机看到公网 IP"与"外部能连进来"是两件事** ⇒ 升格判据必须是**入向可达实测**,⛔ 不是"我拿到一个公网地址"。
5. ⚠️ **打洞能力不能当既成事实** —— `direct/punch.ts:23` 原文已留档:机器断言证明的是"**这段打洞逻辑**在 NAT 穿透场景下成立",⛔ **不是**"公网一定能打洞"。
#### 3.9.4 升格后能省多少(容量口径)
- **约束是出带宽,不是内存**:47 的 352 KB/s 是**云轻量出带宽封顶**,不是 relay 栈上限(上行方向实测 12,213 KB/s)⇒ **一台上行 100 Mbps 的家宽子节点,可承接流量是同档云轻量的数十倍**;但全网必须按**最慢的那台**兜底 ⇒ **中继仍需保留**(设计本就是 45% 余量 + 443/TCP 兜底)。
- **每端口 64 条并发流**(`MAX_STREAMS_PER_PORT = 64`,实测)⇒ **内容子节点单端口只能同时服务 64 个取块请求**;热门块会立刻打满 ⇒ 必须多端口/多子节点分散(Delivery Optimization 式多源)。
- **每节点块缓存默认 64 MiB**(`CONTENT_STORE_MAX_BYTES = 67,108,864 B`,与 relay 的 `MEM_PER_HOST_MB` 预算**独立**)⇒ 真要当内容子节点,须上调该值并固化进参数表,否则命中率极低。
- **净收益**:若 **5% 终端可升格**(2.5 万台)⇒ 中继容量需求从 17–67 台降到「**只需兜底数台**」(信令 + NAT 严格者);且子节点之间可直连 ⇒ 目录只需下发**会合点**,不必下发全部子节点。
- ⚠️ **前置条件**:必须先有 §3.7 步 ① 的**多方观测**,否则节点质量参差会直接拖垮选路(`placement.ts` 的分数只对"输入可信"负责)。
#### 3.9.5 按序要补的五件事
1. **定档位**(①②③ 是三种能力):先做 ①②(代码已就绪),③ 走「**候选池 + 半自动升格**」而非全自动。
2. **控制面凭据的批量登记/吊销**(万级量级)—— 复用 `identity.ts` 的一机一钥 + 单台吊销;这是真正的运维面瓶颈。
3. **改目录结构**(≥64 地址 + 热更新,§3.8.6 第 2 条同一件事)。
4. **补"入向可达"探测** —— 把"有公网 IP"与"外部真能连进来"分开判定(硬门 4)。
5. **参数表固化子节点档位值**:`CONTENT_STORE_MAX_BYTES`(现 64 MiB)、`MAX_STREAMS_PER_PORT`(现 64 条)。
---
### 3.10 依赖顺序裁决:要不要先优化网络、先做链会不会返工(v1.5 新增 · 依据用户提问)
> 用户提问(原话):「**现在有必要优化吗,不优化后续做链会有影响吗,先做链后续在优化网络是不是会返工**」
> **裁决:不必现在做容量类优化;先做链也不会返工 —— 但前提是现在把「三条复用点 + 两个口径」写死(成本 = 写文档,不是写代码)。** 真正会返工的只有一类情形:**链另起一套身份或寻址**。
#### 3.10.1 判据:返工从哪来
**返工来自「同一件事被定义两遍」,不来自「晚做优化」。**
- **优化** = 在既有接口**内部加东西**(可叠加、可回滚、幂等)⇒ 后置**不产生返工**;
- **口径 / 协议分叉** = 把**同一个概念定义两次**(不可叠加,必有一方被重写)⇒ 这一类**必须现在定**。
⇒ 逐项只问一句:**这个动作会不会产生「第二套定义」?**
#### 3.10.2 逐项裁决(§3.8.6 三件 + §3.9.5 五件)
| 项 | 性质 | 后置的后果 |
|---|---|---|
| 带流量 per-host 内存量测 | 量测 | ⛔ 不返工(只改参数值与台数) |
| 多方观测(≥3 观测者) | 新增一层 | ⛔ 不返工;**选路质量**依赖它,但不阻塞链 |
| 入向可达探测 | 量测 | ⛔ 不返工 |
| 控制面凭据批量登记 / 吊销 | 运维工具 | ⛔ 不返工 |
| 参数表固化(64 MiB / 64 条流) | 参数 | ⛔ 不返工 |
| **目录结构(≥64 地址 + 热更新)** | **协议**(客户端要长期兼容) | ⚠️ **会变兼容债**:能改,但存量终端升不动 |
| A 层共识形态 / 骨干 3 → 4 台 | **链自身的设计与部署** | — 不属"网络优化",是链的开工前置 |
⇒ **网络侧 6 项里只有"目录协议"一项会变成兼容债**,其余 5 项全是加法,后置做**不触碰链的数据模型**。
#### 3.10.3 现在就要定死的五条(成本 = 写文档,不是写代码)
1. **节点身份**:链上任何「节点 / 验证者 / 存储持有者」的资格判定,**唯一口径 = `identity.ts`**(一机一钥 + 离线信任根 + 本地校验 + 单台吊销)⇒ ⛔ 链自建第二套身份 = **必返工**。
2. **寻址与会合**:链节点之间怎么找到彼此,**唯一口径 = 覆盖网络**(`placement.ts` 选路 + 目录会合)⇒ ⛔ 链自建第二套寻址 = **必返工**。
3. **锚定落点**:链要锚定就**锚到 A 层**(§3.7 结论),⛔ 不新建第三条链。
4. **口径一 · 命名空间**:`network_id`(`ops` / `u:<userId>`)与 hostId 逻辑名(`<network>/<hostId>`)—— 链上锚定数据**一旦以某个 id 方案为依据,改口径就要迁数据**。
5. **口径二 · 世代**:沿用既有 `epoch` 思路(`content/peer.ts` 已用「epoch 不一致 ⇒ 不作为候选」)⇒ 链的版本 / 世代走同一套,⛔ 另立一套版本号。
(注:`identity.ts` 的**离线信任根**是整条线的信任锚 —— 它一旦上链参与资格判定,就是全链的信任起点,改它的代价最高。)
#### 3.10.4 一句话回答三问
- **现在有必要优化吗** ⇒ **不必** —— 逐项核对后,**没有一项构成链的阻塞**。
- **不优化对做链有影响吗** ⇒ **有且只有一处**:目录若先按「≤8 地址」上线,客户端会按这个格式解析 ⇒ 后期改结构要付**兼容成本**(不是返工,是存量设备升不动)。
- **先做链再优化网络会返工吗** ⇒ **不会**,前提是 §3.10.3 那五条现在写死;**若不写死,返工点恰好落在「身份 / 寻址」这一处**,而非网络优化的其他方面。
#### 3.10.5 建议的执行顺序
| 序 | 动作 | 性质 | 能否后置 |
|---|---|---|---|
| 1 | 冻结 §3.10.3 五条(写进主文档 / 接口注释) | 口径 | ⛔ **现在做**(零代码) |
| 2 | 定链的两处形态(A 层共识三选一、骨干改 4 台) | 链的设计 | ⛔ 链开工前 |
| 3 | 做链(复用覆盖网络的身份与寻址) | 建设 | — |
| 4 | 目录协议改造(≥64 地址 + 热更新) | 协议 | ⚠️ 与链**同期或紧随**(越晚越贵) |
| 5 | 其余优化(带流量内存量测 / 多方观测 / 凭据工具 / 参数固化 / 入向探测) | 加法 | ✅ 任意时点,**不返工** |
---
### 3.11 账号密码能否上链 · 1000 万用户与 1000 万并发登录(v1.6 新增 · 依据用户提问)
> 用户提问(原话):「**链上存 用户账号密码等信息,1000万用户 1000万同时登录 能支持并发吗,是不是无法像数据库那样做分布式 主从库那样容易扩展性能**」
> **两句话判定**:① **账号密码不该上链**(不是性能问题,是设计错误)② **"1000 万同时登录"的瓶颈是 KDF,与"链 or 库"无关** —— 换数据库一样要付这笔账。用户关于**写扩展性**的判断是**对的**。
#### 3.11.1 账号密码为什么不该上链(三条判据)
**数据该放链上的判据(三条须同时满足)**:① 需要多方对**同一份状态**达成不可篡改的共识;② **写入低频**;③ **公开可验证**有实际收益。
**账号密码与登录三条全不满足**,且另撞两条硬冲突:
- ⛔ **链上区块对全部节点可见且永久** —— 即使只存**摘要**,它也是"全网可见 + 攻击者拥有**无限时间**"的离线爆破目标。方案红线只是"A 层永不出现明文",**摘要仍须按高价值资产对待**。
- ⛔ **链只能追加、不可删改** —— 改密码 / 注销都会在链上留下**旧摘要**,攻击面**永久累积**(与 §2.4 冲突一同一个病)。
- ⛔ **认证是高频读 + 高频写** —— 而链的每一笔写都要走共识(见 §3.11.3)。
⇒ **正确落点**:密码摘要(Argon2id / bcrypt)留在**链下应用侧**;链上最多存"身份存在性"的**匿名锚**(HMAC token,与 §2.4 / §3.1 匿名 ID 同口径),且低频。**B 层只存实名与密钥分片(§2.3 已定),⛔ 不存密码。**
#### 3.11.2 「1000 万同时登录」的真实瓶颈 = KDF(与链/库无关)
| 登录窗口 | 请求率 | KDF 参数 | 需要的核 | 需要的内存 |
|---|---|---|---|---|
| 1 分钟 | 166,667 req/s | 75 ms / 64 MiB | 12,500 核 | **781 GB** |
| 5 分钟 | 33,333 req/s | 75 ms / 64 MiB | 2,500 核 | 156 GB |
| 5 分钟 | 33,333 req/s | 75 ms / **19 MiB** | 2,500 核 | **46 GB** |
| 30 分钟 | 5,556 req/s | 75 ms / 19 MiB | 417 核 | 7.7 GB |
⇒ **这张表在数据库方案下一模一样** —— 瓶颈是 `KDF 参数 × 并发数`,不是存储选型。
⇒ 结论:**"1000 万同时登录"只能靠"会话复用 + 排队限流 + 参数标定"化解**,⛔ 不能靠换存储化解:
① 登录成功签发**长 TTL 会话令牌**(后续请求**不再算 KDF**);② 登录入口**令牌桶限流 + 排队**;③ KDF 参数按"可接受延迟"标定(19 MiB 档位内存降 3.4×)。
#### 3.11.3 用户的判断是对的:链的**写**扩展性确实不如库(但要分清读/写)
| 能力 | 关系库主从 | 链 | 差别 |
|---|---|---|---|
| 加**只读**副本 | ✅ 线性 | ✅ **一样**(只读副本 + 索引层缓存) | ⛔ 无差别 |
| 加**写入**能力 | ✅ 分库分表(改路由即可) | ⚠️ **只能分片链**(每片独立共识,**跨片无原子性**) | 🔴 **真正差别** |
| 扩容粒度 | 表 / 库 / 实例 | **链**(整片) | 粒度粗 |
| 改历史 | ✅ UPDATE / DELETE | ⛔ **只能追加** | 与删除权冲突(§2.4) |
| 成员变更 | 加从库即可 | ⚠️ 需**共识成员变更协议** | 比"加从库"重 |
| 写延迟 | 毫秒 | **共识秒级** | 差 3 个数量级(§3.7 判断 4) |
⇒ 一句话:**「读」像库一样好扩;「写」只能分片,且片内不能像主从那样自由加写节点。**
#### 3.11.4 本方案在 1000 万用户下的两处硬结论
- 🔴 **B 层必须分片**:1000 万用户 ⇒ B 层峰值写 **951 TPS**,已抵 PBFT 类单链上限(1,000–3,000 TPS 口径)**下沿** ⇒ 建议 **8 片**(每片 125 万用户 / 119 TPS),16 片更稳(每片 62 万 / 60 TPS)。⚠️ 分片后**跨片无原子事务** ⇒ 跨片操作要走两阶段 / 补偿,设计上应避开。
- 🔴 **登录事件不上链**:每天 3 次/用户 ⇒ 日均 347 TPS、**峰值 3,472 TPS**(**超单链能力**);每天 1 次 ⇒ 峰值 1,157 TPS 亦在临界 ⇒ 登录只上"**日聚合摘要**"(1 条/天),与 §3.7「链只做周期性信任锚」**同构**。
#### 3.11.5 与既有结论的一致性
- 与 §3.7(链只做周期锚定)/§3.10(不产生第二套定义)一致:KDF 用成熟库,⛔ 不自研密码学。
- 与主文档红线一致:A 层永不出现明文;B 层只存密钥**分片**;链上不设密码字段。
---
### 3.12 链上 / 链下边界与链的引入时机(v1.7 新增 · 依据用户拍板)
> 用户拍板原话:「**还是区分链上和链下的数据是对的,后续做DAO和在线游戏时在考虑链**」
#### 3.12.1 这条拍板定了两件事
| # | 定了什么 | 性质 |
|---|---|---|
| 1 | **链上 / 链下分离**是正确设计,继续执行 | **确认既有原则**(与 §2.4 / §3.7 / §3.11 同向) |
| 2 | **链的引入时机 = 后续做 DAO 与在线游戏时再考虑** | **排期决策**(⛔ 不是架构变更) |
**一句话判定**:这是**排期决策,不是架构变更** —— 它不推翻 §3.6 的 V0 / V1 两段式,而是把「链能力」整体归入 **V1+**,并要求 V0 里每一处「本该由链提供的能力」都先有**链下等价物**。
#### 3.12.2 为什么"链"在 V0 可以被拿掉而不塌(三项链下等价物)
链对外提供的其实是三样东西,三样都能先用链下方式做到 —— 区别只在「**谁来保证**」:
| 链提供的能力 | V0 链下等价物 | 升级为链时改什么 |
|---|---|---|
| **① 时序不可否认**("这条记录在 T 时刻已存在") | **Merkle 根 + 可信时间戳锚**(§3.6.1 已定),锚可由**用户自留副本** | **只换锚的存放处**,数据模型不变 |
| **② 多方一致性**(互不信任的几方对同一状态达成一致) | **多方各留一份 + 摘要互签 + 定期对账** | **只换仲裁方**("对账" → "共识") |
| **③ 防篡改日志**(只能追加、不能改历史) | **哈希链**(每块含前块哈希)—— 它本身就是"单方链" | **只换写入权归属**("平台写" → "多方写") |
**关键**:三项的升级动作全都是「**把单方改成多方**」,⛔ 不动数据结构、⛔ 不动密钥分层、⛔ 不动 API 形状。⇒ 与 §3.10 判据一致:**链的引入不产生返工**。
#### 3.12.3 V0 唯一需要定死的硬约束
> 🔴 **凡对外宣称「不可篡改」的地方,必须能由用户自己举证,⛔ 不得表述为「平台保证不可篡改」。**
- **做法**:一律用「**Merkle 根 + 签名 + 由用户自己留存副本**」实现;平台只提供"把根再签一次"的便利,⛔ 不把"信任平台"当作唯一凭据。
- **理由**:这句话在 V0 是**诚实的**(平台确实能改),引入链后**自动变成可举证的真命题**(根已上链)⇒ **文案与接口都不用重写**。反之,V0 若写"平台保证不可篡改",链引入时不是升级,而是**推翻既有承诺**。
#### 3.12.4 为什么 DAO 与在线游戏恰好"需要用链"
两者都**同时命中 §3.7.4 的上链判据**(观测者与被观测者互不信任 **且** 结果需对外举证):
| 场景 | 为什么链下不够 | 落层 |
|---|---|---|
| **DAO**(§2.9) | 治理结果必须"**任何单方**都改不了",且要对**非成员**举证 ⇒ 中心化对账天然不被采信 | **A 层**(公开可验证的锚 + 规则哈希) |
| **在线游戏** | 跨服 / 跨运营方的物品与状态要互认,且要**防内部私改**(运营方本身就是参与者之一)⇒ 与被审计方同侧的数据库不能作凭据 | **B 层**(私有共识链)+ 高频状态走链下 |
⚠️ **在线游戏的额外约束**:游戏是**高 TPS + 低延迟**负载,⛔ 不可能逐笔上链 ⇒ 只能「**链下执行 + 链上结算**」(批量结算 / 定期锚定)。这与 §3.7 的结论**同构**(链做周期性信任锚、实时留在链下)⇒ **同一个模式复用两次**,不需要为游戏另立一套。
#### 3.12.5 边界与交付
- ✅ **已按此拍板落地**:§3.6(V0 能力层)不变 | §3.7(链只做周期锚)不变 | §3.11(认证与链解耦)不变 —— **三处方向一致,本轮无冲突需裁决**。
- ⛔ **本文未做**:不预估 DAO / 游戏的排期,⛔ 不预设链选型(上链判据已给出,选型留到触发时再定)。
- ⏳ **触发条件(写明用法)**:出现「**多互不信任方 + 需对外举证**」的需求即为触发点;届时按 §3.7.4 判据 + 本节 §3.12.2 的「换锚 / 换仲裁方 / 换写入权」三处替换点逐项对齐。
---
## 4. 本文新增的验收判据建议(15–33,须并入主文档 §6)
| # | 判据 | 通过标准 | 由来 |
|---|---|---|---|
| 15 | **删除真效力可验证** | 删除后:① OSS 回读 404(含版本/回收站)② 密钥副本零残留 ③ 桥映射已清除 ④ 抽样备份命中 0 | 场景 4 |
| 16 | **并发写入不丢数据** | 两设备并发改同一条 ⇒ 后提交者被拒绝并收到冲突提示(⛔ 无静默覆盖) | §3.2 |
| 17 | **恢复演练含密钥轮换** | 模拟"设备丢失且可能被解锁" ⇒ MK + 全部 DEK_data 轮换成功,旧分片失效 | 场景 3 |
| 18 | **客户端可验证性** | 用户侧可校验"运行的客户端 = 已登记构建";比对不一致必告警 | 场景 7 路径 7 |
| 19 | **审计不可停锚** | 存在**独立于平台**的锚定/验证方;停锚 N 小时内必有外部告警 | 场景 7 |
| 20 | **分片不可单点取用** | 解封 Sh2 需多角色授权;单管理员全权限操作**无法**单独取到可用分片 | 场景 6b |
| 21 | **治理可验证且成员不公开** | 仅凭公开数据可验证"某票有效",但**无法反推投票人身份或成员表** | 场景 8 |
| 22 | **平台不经手资金与内容** | 全量清点平台接口:**无**收款 / 付款 / 分账执行接口;能力调用路径不落地内容明文 | 场景 8 + 拍板 2 |
| 23 | **可替换证明后端** | 身份 / 成员资格核验走统一 `prove/verify` 抽象;V0(签名 + Merkle)与 V1(ZK)**可互换而不改上层** | §3.6 |
| 24 | **主仓无价值凭证** | 开源主仓全量检索:**零**代币 / 积分 / 余额相关能力;相关能力仅以独立插件形式存在于境外部署 | §3.6.3 + 拍板 1 |
| 25 | **观测非自证** | 同一 relay 的延迟 / 成功率由 **≥3 个互不信任的观测者**分别采集,聚合取中位数;单点撒谎不改变结论 | §3.7 |
| 26 | **信誉锚定可举证且不拖累实时** | 周期摘要可在 A 层被第三方复核;**选路路径不含链调用**(实测选路延迟不受上链影响) | §3.7 |
| 27 | **带流量容量口径已实测** | 存在"每 host 有活跃流"时的 per-host 内存实测值(⛔ 不用空闲会话外推);据此重算并下发 `RELAY_MAX_HOSTS` | §3.8.5 |
| 28 | **目录可承载多中继且热更新** | 单份目录可下发 ≥64 个中继地址(或分层目录);**新增中继无需重启控制面**即生效 | §3.8.5 |
| 29 | **入向可达是实测值而非推断值** | 子节点资格判定取自**外部入向连通实测**;⛔ 不接受"本机看到公网地址"作为判据(区分 NAT / CGNAT) | §3.9.3 |
| 30 | **子节点可批量登记与吊销** | 万级子节点凭据可批量下发与**单台吊销**;吊销后台账与在册会话**同时**消失(⛔ 不残留可用凭据) | §3.9.5 |
| 31 | **链侧无第二套身份与寻址** | 全量检索链侧代码与配置:**不存在**独立于覆盖网络的密钥表 / 在册表 / 目录表;链上资格判定与寻址**均引用** `identity.ts` / `placement.ts` 同一份口径 | §3.10.3 |
| 32 | **认证与链解耦** | 全量检查登录路径:**无链调用**、链上**无密码摘要字段**;登录只以**日聚合摘要**形式上链;并发登录经会话复用 + 限流后**不再触发 KDF** | §3.11 |
| 33 | **「不可篡改」可由用户自证** | 全量检索对外文案与 API:**无**"平台保证不可篡改"表述;所有此类承诺均可由用户用「Merkle 根 + 签名 + 自留副本」**独立复核** | §3.12.3 |
---
## 5. 待拍板(⛔ 本文不自决,需你定夺后再回填主文档)
### 5.0 已拍板(2026-09-19 19:0x · 用户三条 · 本文已按此落地)
| # | 拍板(原话要点) | 落点 | 对下方待拍板项的影响 |
|---|---|---|---|
| 1 | 「**现在不做,预留扩展空间(这是面向全球的开源项目)**」 | §2.9 步 7 · §3.6.2 · §3.6.3 · 判据 24 | 底座保持中性(主仓零价值凭证能力) |
| 2 | 「**平台只做互联和项目协作的作用:能力共创、能力共享、能力使用分发**」 | §2.9.1 · §2.9.3 · 判据 22 | **平台范围定项**:⛔ 不引入资金与法律主体职能 ⇒ 下方第 9 / 10 项仍待拍板,但已被此条收窄 |
| 3 | 「**预留扩展空间,先用最低成本的方式生成密钥与核验**」 | **§3.6(V0 = 设备密钥 + Merkle 包含证明 + Ed25519 签名,零新增基础设施)** | **第 6 项(zkVM 资源来源)降级为"预留、不进当前排期"** ⇒ 当前**不需要** GPU 与证明运维线 |
| 4 | 「**分层方案和建议不错 可以记录下来**」(对 19:30 提问「节点信任:把中继节点历史表现记在链上、用智能合约自动筛选可靠节点」的回应) | **§3.7(新增整节)** + §0 第 8 条 + 判据 25 / 26 | **记录性拍板**(认可分层方案)⇒ 下方第 14 项(多方观测者由谁承担)成为**步 ① 的真实前置** |
| 5 | 「**还是区分链上和链下的数据是对的,后续做DAO和在线游戏时在考虑链**」 | **§3.12(新增整节)** + §0 第 13 条 + 判据 33 | **排期性拍板**:链能力整体归入 **V1+**,V0 取链下等价物 ⇒ 下方第 6 项(zkVM 资源来源)与第 16 项(A 层共识三选一)**均不进当前排期**,保持"预留"状态 |
> 排序:先合规口径(决定架构底线),再成本(决定排期),最后产品/安全策略(各有优劣的真取舍)。
**1. 合规口径 —— 链上"匿名化哈希 + 去映射 anon_id"是否构成 PIPL 意义上的"非个人信息"(含 DAO 场景的贡献 / 投票记录)**
- 这是**删除权能否成立的前提**,未经法律意见不能写进方案。
- 候选 A:直接采信"匿名化后不属个人信息",据此设计删除流程。
- 优点:架构不需要为删除权做额外妥协;实现最直接。
- 缺点:若定性被推翻,链上将出现无法删除的个人信息 ⇒ 需重做架构。
- 候选 B:先取执业法律意见,再定架构细则(本文默认按此挂起)。
- 优点:风险最低;口径可写进用户协议与监管沟通材料。
- 缺点:需要外部成本与时间,S0 排期被拉长。
- 候选 C:不依赖定性 —— 直接按最保守口径设计(链上只存加盐哈希,彻底放弃第三方独立验证)。
- 优点:无论定性如何都站得住。
- 缺点:牺牲公开可验证性(产品的对外卖点之一)。
**2. 合规口径 —— 司法配合请求在"A 层技术上不可解"时的定性**
- 问题:平台无法提供 A 层明文,**是否构成"拒不配合"**?须法律意见。
- 候选 A:按"技术上不可行"书面回复并说明密钥架构。
- 优点:符合架构现状,无需改动。
- 缺点:责任边界未定,存在被认定不配合的风险。
- 候选 B:预先与主管部门沟通备案(说明"单方不可解、合谋可解"的事实)。
- 优点:把不确定性前置解决。
- 缺点:可能引出新的监管要求(如被要求保留可解密通道)⇒ 反过来冲击架构。
**3. 影响面 —— 2-of-3 中是否保留"平台片"**
- 候选 A:保留平台片(本文默认沿用主文档)。
- 优点:丢设备可恢复;合规配合作业有技术通道。
- 缺点:**平台 + T3 串谋即可解开全部用户数据**,对外不能宣称"任何人不可解"。
- 候选 B:去掉平台片(2-of-3 = 用户设备片 + 用户密码派生片 + T3 片)。
- 优点:平台彻底退出 ⇒ "连串谋也不可解"成立。
- 缺点:丢设备 + 忘密码 = **永久丢失**;司法配合彻底无通道。
**4. 影响面 —— B 层形态:value 落链 vs 链下存密文(本文 §2.4 的 b2 建议)**
- 候选 A(本文建议):链上只存锚 + 墓碑,value 密文在链下受控存储。
- 优点:删除权真满足;不可篡改语义保留;删除可证明。
- 缺点:与 v1.1 已表述的"KV 链"形态有落差;需处理备份影子副本。
- 候选 B:维持 value 直接落链,用"状态裁剪 + 销毁 DEK"应对删除。
- 优点:形态符合原表述;链条完整。
- 缺点:**"不可解" ≠ "已删除"** ⇒ 删除权可能不被认定为已履行(⚠️ 又回到合规口径 1)。
**5. 成本 —— 自研链的团队与预算(20 人以上 / 年 500 万量级口径)**
- 候选 A:按主文档分阶段(FISCO BCOS 先行,逐步替换)。
- 优点:业务未验证前不投重资产。
- 缺点:两次建设、迁移成本。
- 候选 B:直接组建自研团队。
- 优点:一步到位。
- 缺点:业务未验证即投重资产;招聘周期长。
**6. 成本 —— zkVM 证明层的资源来源(自购 GPU vs 证明外包)**
- 候选 A:批量证明 + 自购 GPU($24–48K 量级硬件)。
- 优点:成本可控、数据不出域。
- 缺点:需新增 GPU 运维线;低延迟能力受限。
- 候选 B:证明外包(证明市场)。
- 优点:无需资产、弹性。
- 缺点:引入第三方依赖;证明输入数据的信任边界需重新论证。
- 候选 C:暂不引入(B 层先不做盲验证)。
- 优点:省一条运维线。
- 缺点:B 层节点要验状态就得看数据 ⇒ 与"加密安全优先"冲突(主文档 §3.4.2 的死结 unresolved)。
**7. 产品策略 —— 前端投毒防护做到哪一档**
- 候选 A:CSP + SRI(最低档)。
- 优点:零额外成本。
- 缺点:几乎挡不住有平台权限的攻击者。
- 候选 B:可验证构建 + 透明日志登记(推荐起点)。
- 优点:可检测、可举证;对用户可展示。
- 缺点:需建立构建流水线与发布流程。
- 候选 C:原生客户端 + 代码签名(或开源客户端)。
- 优点:防护最强。
- 缺点:开发与分发成本最高;开源涉及商业权衡。
**8. 安全可用性 —— 门限参数 2-of-3 与 3-of-5**
- 候选 A:2-of-3(沿用)。
- 优点:协调成本低;用户少找一方。
- 缺点:容错差(同时丢 2 方即永久丢失)。
- 候选 B:3-of-5。
- 优点:恢复概率显著提升。
- 缺点:**任 3 片串谋的门槛更低**(风险面扩大);用户需维护更多托管关系。
**9. 影响面 —— 第三方托管方(T3)由谁承担**
- 需具备:独立法人 / 独立管理域(最好独立司法辖区)、SLA 约定分片可导出、独立验证能力。
- 候选 A:引入专业托管机构。
- 优点:独立性容易满足;有合规资质。
- 缺点:持续成本;引入对外依赖与合同约束。
- 候选 B:自建第二个平台(同实控人)。
- 优点:成本低、可控。
- 缺点:**独立性不成立 ⇒ 门限安全性退化为"单方持有 2 片"**,架构承诺失效(本文明确不推荐)。
**10. 影响面 —— 数据出境:链节点与对象存储的地域**
- 需定:A 层公开链节点、B 层私有链节点、对象存储区域。
- 候选 A:全境内。
- 优点:出境合规最简单。
- 缺点:跨云/跨地域容灾能力受限;成本可能更高。
- 候选 B:境内外混合(冗余更强)。
- 优点:容灾更好。
- 缺点:触发数据出境评估(⚠️ 且"密文出境 + 密钥不出境"的定性需专业意见)。
**11. 真取舍 —— `DK_idx` 由用户侧派生(默认)还是平台侧持有**
- 候选 A:用户侧派生(本文默认)。
- 优点:平台无法替用户构造 token ⇒ 访问模式不能被平台任意扫描。
- 缺点:查询需用户设备在线;服务端代理能力弱(离线/搜索体验受限)。
- 候选 B:平台侧持有。
- 优点:支持服务端代理查询,体验好。
- 缺点:平台获得完整访问模式可见性(虽仍不可解密内容)。
**12. 合规口径 —— 用户协议中"链上不可删"的告知是否足以豁免**
- 候选 A:以显著方式告知并取得单独同意。
- 优点:成本最低。
- 缺点:PIPL 47 条属法定义务,**同意未必能豁免**(须法律意见)。
- 候选 B:按最保守口径设计(见第 1 项候选 C)。
**13. 对外承诺 —— 开源许可证选择与"境外价值凭证插件"的分发方式**(**由拍板 1「面向全球的开源项目」直接引出**)
- 候选 A:主仓用宽松许可(Apache-2.0 / MIT),价值凭证类扩展另仓另许可。
- 优点:全球采用门槛最低,生态最容易起量;与"底座中性"的定位一致。
- 缺点:无法阻止他人(含境内主体)自行加上代币层 ⇒ 平台对"被用于 237 禁止用途"的控制力弱。
- 候选 B:主仓用 AGPL-3.0,商业使用走双轨授权。
- 优点:可对商用施加约束,保留商业授权空间。
- 缺点:企业采用意愿显著下降;AGPL 的网络服务条款常被大厂直接排除。
- 候选 C:主仓宽松许可 + 单独的**可接受使用政策(AUP)**明文禁止代币化用途。
- 优点:兼顾采用率与合规姿态;不靠许可证而靠政策表达边界。
- 缺点:政策无强制力,只具声明与事后追责依据的价值。
**14. 影响面 —— 步 ① 的「多方观测者」(≥3)由谁承担**(**由 §3.7 三步建议第 ① 步直接引出**)
- 需具备:观测者之间**互不信任**、网络位置不同(不同云 / 不同地域)、口径一致但**各自独立上报**。
- 候选 A:平台自建 3 个观测点(不同云厂商 + 不同地域)。
- 优点:立刻可做,无需第三方协调;测量口径完全一致。
- 缺点:**同属一个主体 ⇒ 严格说仍是「自证」**,只消掉「单机抖动误判」,没解决「观测者与被观测者同主体」。
- 候选 B:现有 relay 节点互测(每台观测其余节点)。
- 优点:零新增资源;规模越大观测面越广。
- 缺点:**互相观测的流量随节点数 O(n²) 增长**;节点同属一个运营主体时,同样不解决「独立」问题。
- 候选 C:引入独立第三方观测(外部探针 / 节点运营方互测 + 公开口径)。
- 优点:**唯一真正满足「互不信任」的做法**;结果可对外举证(对齐 §3.7.4 第 ② 条)。
- 缺点:引入对外依赖与成本;口径对齐与数据回传需设计。
- 👉 **本文倾向**:现在走 **A**(先把「单点误判」消掉,成本近零),把 **C** 作为全球开放后的目标形态;**B** 只作补充探针,⛔ 不当作「独立观测」。
**15. 成本 / 形态 —— 骨干服务器 3 台还是 4 台**(**由 §3.8.3 引出**)
- 事实:BFT 门槛 `n ≥ 3f+1` ⇒ **3 台 `f = 0`**(只容崩溃、不容作恶);容 1 台作恶需 **4 台**,容 2 台需 7 台。
- 候选 A:维持 3 台,并在安全声明里如实写"仅崩溃容错"。
- 优点:省一台机器与一份运维;与当前预算一致。
- 缺点:**无法区分"宕机"与"作恶"**;与 §2.6 的 `N=4 / f=1` 口径冲突 ⇒ §2.6b(节点被攻破)在 B 层**无解**。
- 候选 B:改 4 台,`f = 1`(本文建议)。
- 优点:与 §2.6 口径一致;能容 1 台拜占庭,"多节点共识"的对外表述站得住。
- 缺点:多一台成本与运维。
- 👉 **本文倾向 B**:一台机器的成本远低于"安全声明降级"的代价;4 节点 PBFT 每轮仅 16 条消息,**无性能代价**。
**16. 影响面 / 复杂度 —— A 层共识形态三选一**(**由 §3.8.3 引出**)
- 前提:1,000 节点跑经典 PBFT 不可行(`O(n²)` ⇒ 10⁶ 消息/轮)。
- 候选 A:**周期 Merkle root 多签锚定**(骨干多签,1,000 节点可自验)。
- 优点:最省,与 §3.7「链只做周期性信任锚」同一结论;节点零共识开销。
- 缺点:**不是"节点共识"** ⇒ 对外不能说"A 层由 1,000 节点共同出块";信任集中在骨干多签。
- 候选 B:**抽样委员会**(VRF 选 100–200 节点轮值)。
- 优点:兼顾参与度与可跑性;被选中节点数可控。
- 缺点:需实现 VRF 与轮值治理;委员会成员可能被定向攻击。
- 候选 C:**分层共识**(1,000 台分 33 组 × 30 台 ⇒ 组内选代表 ⇒ 33 节点代表层)。
- 优点:语义最接近"全网参与";可随规模扩展。
- 缺点:最复杂;两层共识的最终性延迟叠加;组划分与代表选举需治理规则。
- 👉 **本文倾向 A(先上)→ B(第三方节点起来后)**;C 仅在"必须有全网共识语义"时考虑。
**17. 形态 / 成本 —— 子节点的升格方式三选一**(**由 §3.9 引出**;档位 ①② 已就绪,此处只问 ③ 的升格路径)
- 候选 A:**全自动升格**(节点自测入向可达即自动成为中继候选)。
- 优点:零人工、规模越大越省事;天然贴合"全球开放、节点自主加入"。
- 缺点:**自测可被伪造**(节点自称"我可达"即可进候选)⇒ 必须先有 §3.7 的多方观测才能防;且**目录 8 地址上限**不解决就仍然下发不出去。
- 候选 B:**半自动升格**(候选池 + 控制面登记,凭据与目录由控制面下发)——本文建议。
- 优点:与现有"一机一钥 + 单台吊销"体系一致;凭据可控、可回滚;不需要先解决自测可信问题。
- 缺点:有一个人工/审批环节 ⇒ 规模上去后运维成本随候选数线性增长(万级时需批量工具)。
- 候选 C:**第三方节点运营方自行接入**(外部主体带资质接入,签合同与 SLA)。
- 优点:把运维面外移;适合全球开放后的骨干层。
- 缺点:引入对外依赖与合同约束;质量与响应不可控;**影响面超出本平台**。
- 👉 **本文倾向 B(先上)→ A(多方观测落地后放开)**;C 只在"骨干层需要外部主体"时才考虑。
---
## 6. 与主文档的一致性自查
| 主文档纪律 | 本文推演是否遵守 | 说明 |
|---|---|---|
| A 层永不出现明文隐私 | ✅ | 场景 1–7 全部路径复核;实名只落 B |
| B 层不公开但多节点共识 | ✅ | 场景 6 按 N=4 / f=1 推演容错 |
| 窄桥独立加密 + 双人授权 + 留痕 | ✅ | 场景 4 步 6、场景 5 步 2、场景 3 步 2 |
| ⛔ 不给低熵字段建盲索引 | ✅ 并补强 | §3.4.3 给出**第二重理由**(截断对低基数字段无效) |
| ⛔ 不用 OPE | ✅ | 范围查询走 bucket 化 + 应用层过滤 |
| ⛔ 不长期加密上链 | ⚠️ **发现一处张力** | §2.4 冲突一:B 层本身是链 ⇒ 需 §5 第 4 项拍板 |
| ⛔ 不自研密码学 | ✅ | 全文以 `HKDF/HMAC/AES-GCM/Shamir` 成熟库为前提 |
| ⛔ B 层不整钥存放 | ✅ 并补强 | §3.1 分层 + 场景 6b 组合风险 |
| ⛔ key 不用裸明文 | ✅ | 全部 `key_token = HMAC(DK_kv_key, …)` |
| ⛔ key/value 域分离 | ✅ | §3.1 域分离硬约束 |
| ⛔ 不做代币 / 发行(银发〔2021〕237 号) | ✅ **并已拍板强化** | §2.9 步 7 + §3.6.3:**开源主仓默认零价值凭证能力**,代币/积分类扩展只作境外可选插件 |
| **平台范围收窄**(拍板 2) | ✅ | §2.9.1 + 判据 22:平台只做互联与协作,⛔ 不经手资金、内容、法律主体 |
| 判据 2 平台不可解 | ⚠️ **表述需修正** | 准确表述是"**平台单方**不可解";2 片串谋可解(§2.3 / §2.5) |
| **⛔ 不为了「看起来更去中心」而把功能搬上链**(由拍板 1「现在不做、预留扩展」延伸) | ✅ | §3.7:信誉**只做周期摘要锚定**,实时选路留在链下;⛔ 不逐条上链、⛔ 合约不做实时筛选 |
| **链上 / 链下边界**(拍板 5:链的引入时机 = DAO 与在线游戏) | ✅ | §3.12:链的三样能力在 V0 **均有链下等价物**;升级只换「锚落点 / 仲裁方 / 写入权」三处,⛔ 不动数据模型 |
---
## 7. 来源
**本文为推演性内容,不引入新外部事实**;所依赖的事实、条文、实测数据全部来自三份既有文档(主文档 §9 已列全部来源),此处不重复。
**本文新增的判断(自研推演,非搜索所得)**
- 7 场景的时序拆解与失败模式矩阵(§2);
- **B 层链上删除权的三种解法**(含 b2 变体建议)与**内容哈希可枚举关联**冲突的识别(§2.4);
- **"平台不可解"的准确表述 = "平台单方不可解"**,2-of-3 的安全性上限 = "平台与第三方不串谋"(§2.3 / §2.5);
- **前端投毒是"平台不可解"体系的第一现实威胁**(§2.7 路径 7);
- **密钥分层唯一判据 =「平台是否需要解」**,以及"KMS 对象数 ∝ 租户数(非用户数)"的成本化解(§3.1);
- **截断位数与总量的对数关系** `b = ⌈log₂(N/3)⌉`,及"低基数字段截断无效"(§3.4.3);
- 规模主表的计算式与 10 / 1 万 / 100 万三档量级(§3.4);
- 元数据泄露的**四种攻击模型 + 缓解矩阵**(含匿名 ID 轮换的可行性边界)(§3.5);
- **新增 19 条验收判据建议**(判据 15–33,§4);
- **中继 / 节点信誉的四条技术判断 + 四层分层方案 + 三步落地建议**(合约不观测 · 缺口是多方观测 · 逐条上链的量级否决 · 共识秒级 vs 选路毫秒级,§3.7);
- **覆盖网络多节点身份 / 选路体系的只读取证**(v1.2 新增,⛔ **未改动任何文件**):`src/net/relay/identity.ts`(685 行 · 四层密钥模型 + 离线信任根)· `placement.ts`(210 行 · 毫秒级本地打分)· `network.ts`(289 行 · `network_id` 命名空间)· `join.ts`(435 行 · 一键加入四步)—— 用于支撑 §3.7 判断 2 与 §3.7.5 的「复用而非新建」结论。
- **3 骨干 + 1,000 节点 + 50 万终端的形态推演**(规模账 · 角色分配 · 两处形态硬伤 · 覆盖网络逐项判定,§3.8);
- **终端升格为子节点的支持度判定**(三档能力拆分 · 五条代码级硬门 · 容量口径 · 按序要补的五件事,§3.9);
- **依赖顺序裁决(优化 vs 做链)**:判据「返工来自同一件事被定义两遍,不来自晚做优化」+ 三条复用点 / 两个口径(§3.10)。
- **账号密码 / 并发登录的落点判定**:密码摘要不上链、登录只上日聚合摘要;1000 万并发登录的瓶颈是 KDF(表见 §3.11.2);链的"写"扩展只能分片、"读"扩展与库相同(§3.11)。
- **纠正 §3.4.2「峰值 TPS」行的换算错误**(年→秒除数须为 `365×86400`;100 万用户正确值为 **95 TPS / 读 951 TPS**,原值偏大 3.65×)。
- **链上 / 链下边界的可替换性证明**(§3.12):链的三样能力 → V0 链下等价物 → 升级时「只换锚落点 / 只换仲裁方 / 只换写入权」;**在线游戏的"链下执行 + 链上结算"与 §3.7 的"链只做周期锚"同构**,同一模式复用(§3.12.2 / §3.12.4)。
**DAO / OPC 场景(v1.1 新增,均为可溯源事实)**
- **WOPC(世界 OPC 生态联盟)**:2026-05-28 于厦门国际会展中心成立(金砖国家新工业革命展览会核心配套活动),使命「**建立全球 OPC+DAO 连接协议标准**」;四层星云架构中**连接层**以「TOKEN 经济(连接权凭证)+ 智能合约(全自动价值分配)+ 声誉系统(链上信用凭证)」为核心 —— 来源:海峡导报 / 新浪新闻 / 中国报业网(2026-05)
- **DAO 在中国的法律定性与责任**:北京国枫律师事务所《浅谈去中心化自治组织(DAO)的基本概念及其合规监管》—— 「DAO 因代币工具的广泛使用,**目前在中国尚无合法的立足之处**」;与**合伙企业**高度类似(《合伙企业法》第 2 / 6 / 26 条:普通合伙人**无限连带责任**、合伙人**分别缴纳所得税**)
- 天元律师事务所《DAO 亦有道》—— 「一旦被认定为合伙(**而这是高概率的**,除非另有架构安排),builder 须就其他 builder 的行为承担**无限连带责任**」;未注册为法人 / 合伙企业的 DAO「**无法合规从事区块链信息服务**」经营;成员**即使已退出**仍可能因链上记录承担责任;**税盾缺失**;中国公民 builder 可能被认定**共同犯罪**
- 学术参照:张志坚、何艺华《去中心化自治组织的法律性质及归责路径》,《天府新论》2024 年第 6 期 —— DAO = **新型非法人组织**;「**去中心化理念的再中心化事实**」(矿池 / 发起人 / 漏洞修补三重再中心化);归责采**二分**(实控人员无限连带、一般投资者有限)
**⚠️ 提示**:§5 第 1、2、12 项属合规口径问题、**第 13 项属对外承诺**,建议取得执业法律意见后定案。本文为技术推演,不构成法律意见。
---
*相关文档:`分布式数据存储与查询-架构设计与隐私保护方案_20260919.md`(主文档 v1.2)|`分布式数据链路-技术方案与落地路线_20260919.md`(通用判定与三档路线)|`面向公众资产平台与隐私金库-落地方案_20260919.md`(仅存档)*