一个 BSV 网络上的井字棋游戏合约
Posted freedomhero
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个 BSV 网络上的井字棋游戏合约相关的知识,希望对你有一定的参考价值。
一个纯粹的点对点游戏,可以让玩家不通过游戏公司就能玩。数字签名提供了部分解决方案,但是如果仍然需要可信的第三方来防止欺骗,那么就失去了它的主要优势。我们提出了一种利用 BSV 网络解决欺诈问题的方案。具体来说,就是把游戏完全放到链上:不仅仅是游戏数据,还包括游戏逻辑。我们通过实现一个井字棋游戏来演示这个方案。
实现
游戏开始时,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 来支付手续费。
我们仅以井字棋为例展示了如何实现点对点的游戏。底层思路可以用于各种游戏(象棋、围棋、扑克等)上链来实现点对点。还可以扩展到多个玩家等等,我们也期待看到更多的应用案例。
以上是关于一个 BSV 网络上的井字棋游戏合约的主要内容,如果未能解决你的问题,请参考以下文章