Files
dsh_ai1net_server/docs/分布式数据链路/分布式数据链路-详细方案与逻辑推演_20260919.md
T

1384 lines
128 KiB
Markdown
Raw Normal View History

# 分布式数据链路 · 详细方案与逻辑推演
> 📌 术语:本文以「分布式」指代本项目(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`(仅存档)*