回收 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)、记忆修复前备份。
128 KiB
分布式数据链路 · 详细方案与逻辑推演
📌 术语:本文以「分布式」指代本项目(2026-09-19 由「去中心化」更名);引用原文、DAO 专有名词与行业泛指保留原措辞。
版本 v1.7 | 2026-09-19 | 状态:推演完成 · 待评审 主文档:
分布式数据存储与查询-架构设计与隐私保护方案_20260919.md(v1.2 · md5788f2a3a574733eae35cea3404550a7f) 推演基准:分布式数据链路-技术方案与落地路线_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. 本文结论(十三条)
- 架构在 7 个场景下逻辑自洽,但有 3 处真实的冲突点必须在 S0 解决:① B 层"链上不可删" vs PIPL 47 条删除权(§2.4)② 内容哈希的"公开可验证" vs "删除后不可枚举关联"(§2.4)③ zkVM 盲验证与 B 层"平台授权可解"的边界(§2.5)。
- 2-of-3 门限只防"单方",不防"平台 + 第三方串谋"(§2.3 / §2.5)。这是全架构比桥表更危险的残余风险——桥表泄露泄露身份,双片串谋直接泄露全部数据明文。必须如实写进安全声明。
- 最现实的攻击不是密码学被破,而是前端投毒(§2.7):平台控制客户端下发通道 ⇒ 可窃取用户 MK。所有"平台不可解"的承诺都建立在这条之上,必须用可验证构建 + 透明日志登记来收窄。
- 多租户密钥的分水岭只有一条判据:「平台是否需要解」(§3.1)。需要解 ⇒ 由租户级 KEK_t 派生(平台侧);不需要解 ⇒ 由用户级 KEK_u 派生(用户侧,平台不可计算)。不是"每租户一把 DEK"。
- 百万用户在写入量级上是单链可承载的(§3.4:峰值约 95 TPS),真正的门槛在三处:盲索引条目(约 10 GB,且是查询热路径)· 审计日志增速(约 10 GB/年,只增不减)· 读流量(约为写的 10 倍 ⇒ 约 951 TPS)。⇒ 查询必须走只读副本 + 索引层缓存,不得穿过共识层。
- 统计攻击无法消除,只能压到"需要外部辅助信息 + 大量观测"才成立(§3.5)。这是验收判据 10 的落点,也是"号称加密但被流量分析打穿"的分水岭。
- DAO 是第 8 个场景,且它的前置条件是"平台承担备案与实名"(§2.9)—— 🔴 律所口径:未登记为法人/合伙的 DAO 无法合规从事区块链信息服务,所以 DAO 自己备案做不到,只能是平台上的组织形态。本轮三条拍板(价值凭证现在不做但预留 · 平台只做互联与协作 · 先上最低成本密钥与核验)已落地为 §2.9 + §3.6。
- 「把中继节点表现记在链上、用合约自动筛选」这个形态不成立,正确形态是四层分工(§3.7):合约不会观测(要人喂数 ⇒ 中心只是换了位置)· 当前真正缺的是 ≥3 个独立观测者(不是链)· 逐条上链在 1,000 节点时 ≈ 33 TPS 而 99% 样本无人读 · 共识秒级 vs 选路毫秒级差 3–4 个数量级 ⇒ 链只做「周期性信任锚」,实时选路留在链下。上链成立的唯一判据 = 观测者与被观测者互不信任 且 筛选结果需对外举证(§3.7.4)。
- 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 个地址)。 - 终端升格为子节点:①② 已支持、③ 只到设计(§3.9):"子节点"是三档不同能力 —— ① 被连方(声明端口 + 回环监听 + 一机一钥,已支持,但纯浏览器终端做不到)· ② 内容子节点(peer 声明 + 分组隔离 + 取回复算,已支持)· ③ 中继子节点(公网入向可达 + 控制面登记 + 目录下发,无自动升格代码路径,106 升格是人工)。五条硬门里最前置的是目录 8 地址上限(升格出 2.5 万台也发现不了)与**"有公网 IP"≠"入向可达"**。
- 依赖顺序:不必先优化网络,先做链也不返工(§3.10):判据是**「返工来自同一件事被定义两遍,不来自晚做优化」** —— 网络侧 6 项里只有目录协议会变兼容债,其余 5 项全是加法、后置不触碰链的数据模型;现在必须定死的是三条复用点(节点身份、寻址与会合、锚定落点)+两个口径(命名空间、世代),⛔ 不写死则返工点恰好落在「身份 / 寻址」。
- 账号密码不上链、登录事件不上链;1000 万并发登录的瓶颈是 KDF 不是存储(§3.11):密码摘要留在链下应用侧(链上最多存匿名锚);"链 vs 库"在登录并发上不是变量(同样的 KDF 账);用户的判断正确 —— 链的写扩展只能分片、片内不能像主从那样加写节点,但读的扩展与库相同。1000 万用户在 B 层必须分片(峰值写 951 TPS 已抵单链下沿 ⇒ 8 片 / 每片 119 TPS)。
- 链上 / 链下分离定为原则;链的引入时机 = 做 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 会用到这一点)。 - ⇒ 这不是设计缺陷,但必须如实写进安全声明,⛔ 不能对外宣称"任何人都无法解密"。
- 缓解手段(三层叠加,缺一层则风险显著上升):
- T3 必须为独立法人 / 独立管理域(最好独立司法辖区)——同一实控人手中 ⇒ 等同单点;
- T3 的片用 T3 独立 KEK 保护 ⇒ 平台侧即使拿到 T3 的存储也无用;
- 取 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(必须写进安全声明的软肋)
对"平台不可信"模型,客户端加密是唯一防线,而前端投毒可击穿它。
缓解手段(按强度递增):
- CSP + SRI(子资源完整性)+ 禁止动态注入脚本;
- 可验证构建:发布物带签名,构建哈希登记到只追加透明日志(用户可校验"我运行的代码 = 已登记的代码",类比 Certificate Transparency);
- 原生客户端 + 代码签名 + 系统级校验;
- 开放客户端源码(⚠️ 商业权衡,需拍板);
- 最彻底:本机应用 + 可复现构建。
⚠️ 诚实结论:前端投毒属于不可完全防住的一类攻击,只能降低概率 + 提高可检测性。这是所有"零知识"平台共同的软肋,⛔ 不能对外声称"绝对不可解"。
审计留痕设计(三平面分离)
| 平面 | 内容 | 存储 | 权限 | 保留 |
|---|---|---|---|---|
| 业务日志 | 业务操作 | 常规存储 | 运维可读 | 常规 |
| 密钥使用日志 | 谁、何时、对哪个 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 前置澄清(两条,缺一则本场景不成立)
- 🔴 DAO 自己无法完成区块链信息服务备案 —— 备案第 8 条要求真实身份认证(组织机构代码 / 身份证号),而 DAO 既非法人、通常也未登记为合伙。律所口径:「未注册为法人、合伙企业的 DAO……无法合规从事区块链信息服务」。⇒ 平台必须是已登记主体并承担备案与实名,DAO 只作为平台上的组织形态存在。
- ⛔ 平台范围收窄(本轮拍板) —— 平台只做两件事:① 互联(身份、寻址、桥、网络)② 项目协作(能力注册 / 匹配 / 调用授权 / 分发路由 / 贡献记录)。⛔ 不做:资金、代币、法律主体代持、内容运营、撮合定价。
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"叙事的批判,必须如实写明)
- 代币抵押 + 自动分账 = 银发〔2021〕237 号红线 —— 律所口径:DAO「因其作为基础建设的代币工具的广泛使用,目前在中国尚无合法的立足之处」。⇒ 本轮拍板:现在不做。
- 资金腿不在链上 —— OPC 收入来自法币客户;"自动分账"要资金上链 ⇒ 法币通道被禁、稳定币被禁 ⇒ 境内不可实现,只能"链上记账 + 链下付款"(步 7 即此形态)。
- 贡献度不可链上验证 —— 合约能执行"按约定比例分",算不出"谁的贡献是多少"。⇒ 链只解决规则不可篡改,不解决输入数据真实性(garbage in, garbage out)。
- 法律主体缺位 —— 无主体 ⇒ 不能签约 / 收费 / 开票 / 应诉;实务上高概率被认定合伙 ⇒ 无限连带责任(《合伙企业法》第 2 条);成员退出后仍可能因链上记录被追责;税盾缺失。⇒ "项目结束即可解散"只解散技术实体,义务不终止。
- 治理现实被美化 —— 一币一票 = 财阀制(与"贡献可验证"的取向相反);投票率长期个位数;"临时组 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,000,000 × 100 = 1×10⁸ 条/年;
- 索引条目 = 1×10⁸ × 5 = 5×10⁸ 条;
- 截断位数 = ⌈log₂(5×10⁸ / 3)⌉ = ⌈log₂(1.667×10⁸)⌉ = ⌈27.32⌉ = 28 bit(占 4 B);
- 索引存储 = 5×10⁸ × (16 B + 4 B) = 5×10⁸ × 20 B = 10 GB;
- 链上元数据 = 1×10⁸ × 256 B = 2.56×10¹⁰ B = 25.6 GB;
- 密文 blob = 1×10⁸ × 2 KB = 2×10¹¹ B = 200 GB;×1.05 = 210 GB;×3 版本 = 630 GB;
- 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 三条从量级里读出来的判断
- 截断位数必须随总量对数增长:
b = ⌈log₂(N/3)⌉⇒ 每 ×10 数据量,b只增加 3.32 bit(约 0.4 B/条目)。⇒ 这是可运营的,不是膨胀问题。但前提是被索引字段基数足够高——低基数字段无论截断多少位都无法控制返回行数(每桶天然超大)。这正是"⛔ 不给低熵字段建盲索引"的第二重理由(第一重是频率还原)。 - KMS 不是瓶颈,索引与审计才是:KMS 对象数 ∝ 租户数(1,000 级);而索引 10 GB 是查询热路径(需内存/SSD + 分片),审计日志是增速最快的项——按每用户每月 20 次操作 × 500 B ≈ 10 KB/年/用户 ⇒ 100 万用户 = 10 GB/年,且只增不减(判据:审计保留策略必须定)。
- 写入可承载,读不可直打共识层:峰值写 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 三条设计纪律
- 🔴 身份密钥与数据密钥职责分离 —— 身份密钥(签名 / 投票 / 授权)在设备上,不参与 A 层数据的加解密;数据侧仍走
MK+ Shamir 2-of-3(§3.1)。⛔ 不得用同一把密钥既签名又解密。 - 🔴 扩展点是"接口预留",不是"功能占位" —— V0 走纯签名 + Merkle;代码里⛔ 不得出现"等 ZK 上线再说"的空实现、半成品开关或死代码分支(否则等于埋一条假路径)。
- 🔴 面向全球开源 ⇒ 分层合规(本轮拍板的关键推论)—— 开源主仓默认不含任何价值凭证能力;代币 / 积分类扩展只能作为独立可选插件存在,且仅用于境外部署形态,⛔ 不进主仓默认路径、⛔ 不在境内部署中出现。 ⇒ 这是"现在不做"与"预留扩展空间"两句话能同时成立的唯一方式:底座中性、扩展外挂、地域可分。
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 一句话结论(三条)
- 数据面完全不是瓶颈:50 万终端全年只产生 A 层链上元数据 12.8 GB、密文 blob 323 GB(含 3 版本),摊到 1,000 节点每台每年 0.97 GB。
- 两处形态级硬伤(不是容量问题,是设计问题):① 3 台骨干做 B 层共识 ⇒ 拜占庭容错
f = 0(只防宕机,不防作恶)② 1,000 节点跑经典 PBFT ⇒O(n²)= 每轮约 10⁶ 条消息,不可行。 - 现有覆盖网络撑得住 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) |
两条"没配就崩"的配置项
- 🔴 中继 fd 上限必须拉起:
FD_PER_HOST = 4⇒ fd 还是默认 1024 时单台只能装 256 台(不是 7,515)。必须LimitNOFILE = 262144(47 实测值)。 - 🔴
--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 按序要补的三件事
- 量测"带流量 per-host 内存" —— 唯一还没量的关键口径;它同时决定"17 台还是 67 台"与"终端能不能挂中继"。
- 改目录结构 —— 支持 ≥64 个中继地址 + 热更新(取消二次重启控制面)。
- 定 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 五条硬门(代码级,决定"能不能做到")
- 🔴 纯浏览器终端做不了 ① —— 要当被连方就得声明端口 + 开回环监听,而 relay 默认且建议只绑
127.0.0.1(server.ts:150)、no-ports一律拒绝 ⇒ Web 终端只能"拨出+取块",不能"被连"。要当子节点必须是原生客户端/桌面守护进程。 - 🔴 升格必须由控制面登记并下发密钥 —— "自动升格" ≠ "自动生效";没有凭据那一步,HELLO 直接被拒。
- 🔴 目录是比机器数量更前置的墙 ——
MAX_ENTRIES = 8(directory.ts:70)⇒ 即便升格出 2.5 万台子节点,新终端也发现不了它们(见 §3.8.5 同一堵墙)。 - ⚠️ "有公网 IP" ≠ "入向可达" ——
directory.ts:435 isPublicHost只剔除回环与私网;家宽 NAT / 运营商 CGNAT 下"本机看到公网 IP"与"外部能连进来"是两件事 ⇒ 升格判据必须是入向可达实测,⛔ 不是"我拿到一个公网地址"。 - ⚠️ 打洞能力不能当既成事实 ——
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 按序要补的五件事
- 定档位(①②③ 是三种能力):先做 ①②(代码已就绪),③ 走「候选池 + 半自动升格」而非全自动。
- 控制面凭据的批量登记/吊销(万级量级)—— 复用
identity.ts的一机一钥 + 单台吊销;这是真正的运维面瓶颈。 - 改目录结构(≥64 地址 + 热更新,§3.8.6 第 2 条同一件事)。
- 补"入向可达"探测 —— 把"有公网 IP"与"外部真能连进来"分开判定(硬门 4)。
- 参数表固化子节点档位值:
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 现在就要定死的五条(成本 = 写文档,不是写代码)
- 节点身份:链上任何「节点 / 验证者 / 存储持有者」的资格判定,唯一口径 =
identity.ts(一机一钥 + 离线信任根 + 本地校验 + 单台吊销)⇒ ⛔ 链自建第二套身份 = 必返工。 - 寻址与会合:链节点之间怎么找到彼此,唯一口径 = 覆盖网络(
placement.ts选路 + 目录会合)⇒ ⛔ 链自建第二套寻址 = 必返工。 - 锚定落点:链要锚定就锚到 A 层(§3.7 结论),⛔ 不新建第三条链。
- 口径一 · 命名空间:
network_id(ops/u:<userId>)与 hostId 逻辑名(<network>/<hostId>)—— 链上锚定数据一旦以某个 id 方案为依据,改口径就要迁数据。 - 口径二 · 世代:沿用既有
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(仅存档)