4.3 The Commit-Reveal Scheme

在透明的公有链上,所有交易数据在广播瞬间即对全网可见。如果仲裁员直接提交投票结果(例如 Vote: YES),后续的仲裁员将能够看到先投者的选择。这将导致严重的镜像攻击 (Mirroring Attack) 或 搭便车 (Free-riding) 行为——仲裁员不再独立分析证据,而是盲目跟随早期投票者的选择,破坏了谢林点博弈所需的“独立判断”假设。

为了解决这一问题,OmniPact 实施了严格的 Commit-Reveal(承诺-揭示) 双阶段投票协议。

4.3.1 Phase 1: The Commit Phase

在此阶段,仲裁员已经做出了判决,但必须将判决结果“密封”后上链。我们利用单向哈希函数来实现这一“数字信封”。

1. 本地计算 (Local Computation)

仲裁员客户端在本地生成以下数据:

  • Vote (): 判决结果(例如:1 代表买家胜,2 代表卖家胜)。

  • Salt (): 一个高熵的随机数(例如 256位的大整数)。Salt 是防止暴力破解的关键。

2. 哈希生成 (Hash Generation)

仲裁员计算承诺哈希 $C$:

Ci=Keccak256(ViSiAddressi)C_i = \text{Keccak256}(V_i \parallel S_i \parallel \text{Address}_i)
  • : 数据拼接操作。

  • Address Binding: 将发送者地址纳入哈希计算,防止其他恶意节点直接复制(Replay)该哈希值来伪造投票。

3. 提交上链 (On-Chain Submission)

仲裁员调用 commitVote(bytes32 commitment)。

  • 链上仅存储哈希值

  • 隐私性:由于哈希函数的单向性,且 未公开,外界(包括其他仲裁员)无法从 反推出

  • 注意:此阶段需要支付 Gas 费。

4.3.2 Phase 2: The Reveal Phase

commitPeriod 结束(例如 24 小时后),协议进入揭示阶段。此时,所有仲裁员必须公开其原始数据以验证承诺。

1. 数据公开 (Data Exposure)

仲裁员调用 revealVote(uint256 vote, uint256 salt)。

2. 链上验证 (On-Chain Verification)

智能合约重新执行哈希计算,并与阶段一存储的承诺进行比对:

Solidity

  • 一致性检查: 如果仲裁员试图在揭示阶段更改投票(例如看到别人都投了 A,自己想改投 A),由于他无法找到一个新的 使得 (哈希碰撞),交易将被拒绝。

4.3.3 Security Analysis: Preventing Mirroring (安全性分析:防御镜像攻击)

1. 防御彩虹表攻击 (Salt Generation)

如果仅计算 Keccak256(Vote),由于 $V$ 的取值空间极小(通常只有 2-3 个选项),攻击者可以通过穷举瞬间破解哈希。

引入随机 Salt ($S$) 极大地扩展了输入空间,使得暴力破解在计算上不可行。OmniPact SDK 会自动在本地生成强随机 Salt 并加密存储在用户设备端。

2. 强制独立性 (Enforced Independence)

由于在 Commit 阶段结束前,没有任何真实投票信息泄露,所有仲裁员被迫独立查阅证据并做出判断。当 Reveal 阶段开始时,所有人同时亮牌,此时再想修改结果已经不可能。

3. 未揭示惩罚 (Non-Reveal Penalty)

如果仲裁员在 Commit 阶段提交了哈希,但在 Reveal 阶段发现自己属于少数派,为了避免被罚没,他可能会选择“不揭示”(放弃投票)。

为了遏制这种行为,OmniPact 规定:Commit 但不 Reveal 的行为,等同于弃权,并将受到轻微的信誉分扣除惩罚。 这确保了仲裁员有动力完成整个流程。


该机制是去中心化投票系统中最经典的密码学原语,通过详细解释 Salt 的作用和 Address Binding 的必要性,展示了协议在细节设计上的严密性。