如何用区块链合约做一个赌博应用?
writting date: 2018-09-21 13:46:49
去中心化,匿名,可信。除了做电子货币之外,区块链仿佛是为赌博量身定制的一般。 那么问题来了,如何实现一个赌博应用呢。。
我在参考了一些代码后做了个测试,有兴趣的可以传到主链上试试(一切后果自负。这里只做技术探讨。 我参考了国外大佬写的一些代码,但出处已经找不到了。
Any possibly related consequence is your own.
oraclize
所有的赌博都依赖一个【公开透明高可信的随机因素】。比如赌球赌马,比赛结果就放在那里,谁也不可能伪造;同时又没有人能够真正预知比赛结果(假如没有黑幕)。 你甚至可以赌下周五伦敦的气温。
那么问题来了,如何生成一个可信的随机数呢。 你说,在给定范围内random一个integer不就行了嘛? 可是程序内部生成的数字,赌徒可不买账,谁知道你是不是操纵了这个结果呢。 的确有人利用random.org之类的随机数生成服务来赌博,但是他们是不是一家谁又能证明呢。
所以就有了oraclize这个东西,它给智能合约提供了一个现实世界的api,通过它你可以在合约里动态获取货币汇率,天气情况,等等乱七八糟的数据,十分强大。但这里只说一下它的随机数服务。
oraclize的随机数生成原理可以看这里,它保证了随机数不会被操纵(除非天下矿工都是你)
使用方法概述一下是这个样子的:
0.你需要在一开始导入oraclize的库,并声明你的合约using oraclize:
|
|
btw,关于solidity版本,我在测试代码的时候4.20是稳定运行的,可最新版会出现一些不可名状的错误,我不知道为什么。
1.这个服务不是免费的,你必须支付一定的佣金。需要把这部分eth放在msg的value里面,而不是通过支付gas的方式。所以获取随机数的函数应该写成payable的
|
|
这里生成的是随机的0或1
2.服务提供方响应请求后,如果成功获取了随机数,就会通过回调的方式来告诉你结果,因此对应地,也需要一个处理callback的函数,用于接收,验证和处理结果。而且这一步产生的gas费用也是需要你支付的(wtf)
|
|
这里首先要确认消息的发送方是否就是可信的的随机数提供方(防止其他人伪造结果) 代码里的RandomNumber是合约类中的成员变量。
Gambling is the demon , stay away:
基于上面的随机数,可以设计一个类似猜硬币正反的合约,两个人参与,各付一块钱押金,猜正反,赢家通吃。 下面的代码,为了方便调试,许多变量我写成public了,真正使用的话应该private。
|
|
这是合约的各种成员变量和事件。
接下来是构造函数:
|
|
需要注意的是,因为后面需要把奖池里的eth付给赢家,所以构造函数必须是payable的。
下面的代码用来接受投注:在调用这个方法时,应该把金额放在value里面(因此这个方法必须是payable的),前面规定投注必须是1个ETH。
|
|
接下来把前面提到的请求随机数和回调函数抄一遍,这儿不重复了
获取随机数之后就可以检测赢家是谁并付款了
|
|
再下面就是个坑了,虽然说我们请求的是“随机数”,但是oraclize还给我们的随机数是字符串形式,为了省一步转换,在下注的环节中也使用字符串来接受玩家的猜测数字。
那么问题来了,在solidity里面字符串怎么比较呢。。 最普遍的方法是这个样子的:
|
|
肥肠无语。。不过还有种比较heck的方法可以更简单地比较字符串中的数字
|
|
用的是hash函数来比较两个字符串,‘1’和‘0’的hash显然是不一样的,但是如果字符串没这么简单,那就不好说了。
checkingWinner()中的stringsEqual封装了一下使用compareStrings对比RandomNumber变量和输入字符串的逻辑。两行代码,这里就不写了。
反正至此你就可以跟朋友赌博去了。
THIS IS A TEST
下面是一个测试。 之前说了,oraclize是收费的,为了无限制地测试,可以使用oralize官方给出的在线ide,注意要把测试环境设置成Javascript VM. 如果她说 compiler not yet loaded , 试试关掉adBlock,并且把你的校园网关了,自己拿手机开个热点。别问我怎么知道的。
部署看上去是这样子的
接下来投个注试试: 不要忘记把value写成1 ether
接下来换一个账户,投“1”
之后看一下合约的状态:奖池里已经有两块钱了
再调用一下设置随机数函数,这个点完了得等会儿再看结果,结果不是立刻返回给你的 注意下,这一步,你第一次用的时候是免费的,这是oraclize的政策,后面再用就得付费,费用通过value支付。具体付多少可以看官网的价格。
随机数设置好以后,就可以揭晓赢家啦。 调用checkingWinner函数: 恭喜这位60c玩家获得两块钱。
improve
这个合约为了简单,省略了各种操作,还可以完善一下,比如
- 设置一个initialize函数,把所有变量恢复初始状态,使合约可以重用
- 可以设置更复杂的规则,更多的参加人数和可变的投注额。让投注较多的赢家赚更多
- 你可以当庄家,不过需要根据概率设置好赔率,否则就亏了。。
- 除了随机数,还有各种玩法,毕竟oraclize那么强大呢,在线赌球也不是不行
- 你可以从奖池里抽取(大笔的)佣金,同时调用随机数api产生的费用也应该这么付。
[+] click to leave a comment [+]
>> SEND COMMENT <<