另一个公平掷硬币 sCrypt 合约

上篇文章中,我们使用 XOR 在比特币网络上进行了公平的抛硬币。今天我们来介绍另一种使用 Blum 原始协议 [^1] 来实现这个游戏的方法。

它包括以下步骤:

  1. Alice 选择质数 pq。 他告诉 Bob 二者乘积 N = p * q。Alice 可以选择很大的 pq ,这样 Bob 就无法进行从 N 进行反推;
  2. Bob 在 0 到 N 之间选择 x [^2],并计算 b =x² mod N。他告诉Alice 数值 b。 此步骤类似于在掷硬币之前就选择一个结果并作出承诺;
  3. Alice 计算 b 取模 N 的四个方根,分别是 xyN-xN-y。 她选择 {x,N-x}{y,N-y} 对中的一个并告诉 Bob。 该步骤对应于硬币的物理翻转;
  4. 如果 Alice 选择 {x,N-x},则 Bob 获胜,并且他可以通过告诉 Alice x 轻松证明这一点。除非 Bob 在第2步中选择了 x,否则他无法计算出这个数,因为他不知道 pq
  5. 如果 Alice 选择 {y,N-y},则她获胜。 因为 Bob 无法计算出 y,所以他不能通过告诉 Alice 这个数来作弊。

合约示例代码如下:

contract CoinToss {
    Ripemd160 alice;
    Ripemd160 bob;
    // commitments
    Sha256 aliceHash;
    Sha256 bobHash;
    // N = p * q
    int N;

    public function toss(int aliceNonce, int bobNonce, int amount, SigHashPreimage txPreimage) {
        require(Tx.checkPreimage(txPreimage));

        require(hash256(pack(aliceNonce)) == this.aliceHash);
        require(hash256(pack(bobNonce)) == this.bobHash);
        
        // Bob succeeds to guess Alice's toss
        bool head = aliceNonce == bobNonce || aliceNonce == this.N - bobNonce;

        // head -> Bob wins; tail -> Alice wins
        Ripemd160 winner = head ? this.bob : this.alice;

        // winner takes all
        bytes winnerScript = Util.buildPublicKeyHashScript(winner);
        bytes winnerOutput = Util.buildOutput(winnerScript, amount);
        require(hash256(winnerOutput) == Util.hashOutputs(txPreimage));
    }
}

[^1] Coin Flipping by Telephone: A Protocol for Solving Impossible Problems. Blum (CRYPTO 1981).
[^2] x 和 N 必须是互质的,以确保 4 个平方根

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页