区块链(01):两份签名都正确,账本仍会冲突
00 篇里的数据库负责所有订单的顺序。去掉这个唯一权威,买家用同一可花费输入签发两笔意图:第一笔向卖家支付 70,第二笔向攻击者支付 70。两条消息在本地 secp256k1 密钥下分别得到合法的 ECDSA 签名。验签成功不意味着两笔都能入同一本账。
先修:区块链(00):从中心化订单基线开始 的事务/重试,理解“相同输入”指代同一份可消费状态。此处消息是人为编码的 教学域 + 订单号 + 收款方 + 输入标识 + 金额,不是 Bitcoin 原始交易或其签名预映像。
四个问题,四个检查点
flowchart LR
I[两笔冲突意图] --> A[授权: 各自验签]
A --> V[有效性: 输入尚未消费]
V --> O[排序: 先应用哪一笔]
O --> H[共同历史: 重组和确认]
S[可任意造账号] -->|不能按账号简单计票| O
授权回答“是否由这把私钥签署了这些字节”,并不回答“签署者只签过一笔”。状态检查回答“针对当前状态,这个输入可否使用”;两笔分别面对同一个旧状态时都可能通过,但顺序执行后只能有一笔消费输入。排序回答“网络用哪份有效历史更新状态”;抗女巫回答“为什么创建一万个身份不会得到一万倍投票权”。合成实验只实测第一项及 05 篇的顺序状态检查,后两项需要真实网络协议和状态证据。
| 场景 | 由谁承担成员管理 | 规则与审计的信任边界 |
|---|---|---|
| 中心化 SQLite | 数据库管理员 | 单一事务排序;其他机构信任其记录与备份 |
| 许可成员复制 | 联盟组织/身份签发者 | 预设投票权与故障预算;移除成员需治理 |
| Bitcoin 类开放网络 | 任何 peer 可加入 | 不按 peer 数量计票;有效候选历史按累计工作比较,实际安全仍取决于算力与网络假设 |
PoW 要限制的是竞争历史的资源成本,不是检查某人的真名。持有更多 peer 地址不应自动变成更多算力;也不能从“每个节点都能验交易”推出“所有节点即时看到同一笔交易”。一个节点拒绝中继的接收策略、共识规则和链选择分别生效。即使两个节点暂时选了不同候选历史,观察者也不能凭本地接收顺序声称交易已有确定终局。
设两个节点暂时分区:A 只接到卖家收款意图,B 只接到攻击者收款意图。即便双方对签名、余额和脚本使用相同规则,也会在不同“当前状态”上判断可花费性。恢复通信后要依据协议选择有效历史,撤回输掉的分支对本地未花费集合的影响;卖家的后台不能仅因为 A 曾经回传交易 ID 就永久标记交付成功。这里没有模拟 PoW 竞争,也没有证明超过多少确认必然安全。确认风险取决于攻击资源、传播与同步假设,不是固定百分比或单次节点观测可以推断。
许可网络可用预先签发的成员身份限制一人多票,代价是把发证、成员变更和串谋预算交给联盟治理;开放网络无需先授予账号,但必须为历史竞争定义另一种稀缺资源或外生权重。PBFT 的固定成员法定集合与 PoW 竞争不是一组可以互换的投票名词;PoS 权重也不等于“按登录账号投票”。
在 test_two_valid_conflicting_intents_and_mutation 中,临时私钥分别签署指向 seller 和 attacker 的消息,二者验签返回 Verified OK;拿第一笔签名去验第二笔消息退出码非零。测试只声明签名字节性质,私钥在临时目录删除。若见到 Verified OK 就发货,最终哪笔消费输入还未知。这是应用侧的失败分支,不是验签函数的错误。
两道练习
- 推导:一个节点先见到对卖家的支出,另一个节点先见到对攻击者的支出;没有共识时,签名与接收时间能选出唯一结果吗?答案:不能。签名只能验证每份消息;节点本地顺序不同,必须用共同的历史选择规则,并对重组提供业务补偿策略。
- 修改输入:交叉验证两笔已签意图:保持第一笔签名,换收款方后验签应怎样?若重新用原私钥签第二笔呢?答案:原签名与改后消息不匹配;重新签署的第二笔可以验签成功,但与第一笔争用同一输入,状态执行最多接受其中一笔。
test_models.py覆盖前两个判断,最后一个由 05 篇的有限模型验证。
可迁移的判断方式是先拆开授权、状态有效、排序和共同历史,再选取数据库/许可成员/开放网络所需的不同治理和故障假设。已经有明确写入者时,公链的开放成员成本不一定值得支付。
参考资料与核验边界
- Bitcoin 白皮书,第 2–5 节(待联网核验);当前 PDF 403。PoW 的细节与当代节点实现须另读冻结版 Core 源码与功能测试,SHA 尚未冻结。
- 旧系列 分布式系统(E03):IPFS、SUNDR 与 Bitcoin 的开放网络信任模型 仅用于先修桥接,不代替一手协议核对。
系列导航:区块链(00):从中心化订单基线开始 · 01 冲突与成员 · 区块链(02):哈希之前,先说清究竟签了哪些字节 · 区块链(03):签名证明授权了哪条消息 · 区块链(04):Merkle 包含证明需要可信根 · 区块链(05):同一笔支付在 UTXO 与账户账本里的两种状态迁移。


