一个 BSV 网络上的井字棋游戏合约

一个纯粹的点对点游戏,可以让玩家不通过游戏公司就能玩。数字签名提供了部分解决方案,但是如果仍然需要可信的第三方来防止欺骗,那么就失去了它的主要优势。我们提出了一种利用 BSV 网络解决欺诈问题的方案。具体来说,就是把游戏完全放到链上:不仅仅是游戏数据,还包括游戏逻辑。我们通过实现一个井字棋游戏来演示这个方案。

一个 BSV 网络上的井字棋游戏合约_第1张图片

实现

游戏开始时,Alice 和 Bob 每个人都把一定数量的 BSV 锁定在一个合约里。然后,他们发送签名过的交易与这个有状态的合约进行交互,来轮流行动。如果一方获胜,获胜方将赢走所有锁定在合约里的比特币。如果出现平局,玩家则各自拿回自己的币。下面是核心的合约代码,代码含义参见注释。

public function move(int n, Sig sig, int amount, SigHashPreimage txPreimage) {
        require(Tx.checkPreimage(txPreimage));
        require(n >= 0 && n < BOARDLEN);

        bytes play = this.is_alice_turn ? ALICE : BOB;
        PubKey player = this.is_alice_turn ? this.alice : this.bob;

        // ensure it's player's turn
        require(checkSig(sig, player));
        // make the move
        this.board = ArrayUtil.setElemAt(this.board, n, play);
        this.is_alice_turn = !this.is_alice_turn;


        bytes outputs = b'';
        if (this.won(this.board, play)) {
            // winner takes all
            bytes outputScript = Utils.buildPublicKeyHashScript(hash160(player));
            bytes output = Utils.buildOutput(outputScript, amount);
            outputs = output;
        }
        else if (this.full(this.board)) {
            // draw: equally split, i.e., both outputs have the same amount
            bytes aliceScript = Utils.buildPublicKeyHashScript(hash160(this.alice));
            bytes aliceOutput = Utils.buildOutput(aliceScript, amount);

            bytes bobScript = Utils.buildPublicKeyHashScript(hash160(this.bob));
            bytes bobOutput = Utils.buildOutput(bobScript, amount);

            outputs = aliceOutput + bobOutput;
        }
        else {
            // update state
            bytes scriptCode_ = this.getStateScript();
            bytes output = Utils.buildOutput(scriptCode_, amount);
            outputs = output;
        }

        require(hash256(outputs) == SigHash.hashOutputs(txPreimage));
    }

讨论

为了便于说明,我们只展示了游戏合约中最重要的部分。有几种方法可以把它打造成一个完全可用的游戏,包括:

  • 超时:增加一些代码(例如函数)来处理玩家拒绝行动(可能因为他发现自己要输了)的情况。例如,当 Alice 行动时把nLockTime设置成距离现在1小时。如果 Bob 不在规定时间内行动,那么 Alice 就获胜并拿走所有 BSV。反之亦然。
  • 手续费:增加一个UTXO input 和找零 output 来支付手续费。

我们仅以井字棋为例展示了如何实现点对点的游戏。底层思路可以用于各种游戏(象棋、围棋、扑克等)上链来实现点对点。还可以扩展到多个玩家等等,我们也期待看到更多的应用案例。

你可能感兴趣的:(sCrypt,智能合约,区块链,智能合约)