以太坊蜜罐智能合约之新颖的赌博游戏区块链

曲速未来安全区 2018-07-21 17:05
分享到:
导读

区块链的去中心化给博彩行业带来了新的机遇,然而久赌必输这句话也不无道理。

1. 加密轮盘赌轮

合约关键代码如下:

该合约设置了一个 1-20 的随机数

secretNumber, 玩家通过调用 play() 去尝试竞猜这个数字,如果猜对,就可以取走合约中所有的钱并重新设置随机数 secretNumber。这里存在两层猫腻。第一层猫腻就出在这个 play()。play() 需要满足两个条件才会运行:msg.value >= betPrice,也就是每次竞猜都需要发送至少 0.1 个以太币。number <= 10,竞猜的数字不能大于 10。

由于生成的随机数在 1-20 之间,而竞猜的数字不能大于 10, 那么如果随机数大于 10 呢?将不会有人能竞猜成功!所有被用于竞猜的以太币都会一直存储在智能合约中。最终合约拥有者可以通过 kill() 函数取出智能合约中所有的以太币。

在实际的场景中,我们还遇到过生成的随机数在 1-10 之间,竞猜数字不能大于 10 的智能合约。这样的合约看似保证了正常的竞猜概率,但却依旧是蜜罐智能合约!

1.2 开放地址彩票

合约关键代码如下:

OpenAddressLottery 的逻辑很简单,每次竞猜,都会根据竞猜者的地址随机生成 0 或者 1,如果生成的值和 LuckyNumber 相等的话(LuckyNumber 初始值为 1),那么竞猜者将会获得 1.9 倍的奖金。对于安全研究人员来说,这个合约可能是这些蜜罐智能合约中价值最高的一个。在这里,我们将会使用一个 demo 来说一说 Solidity 编译器的一个 bug:

在运行 test() 之前,addr、b、c、d 的值如下图所示:

在运行了 test() 之后,各值均被覆盖。

这个 bug 已经被提交给官方,并将在 Solidity 0.5.0 中被修复。

截止笔者发文,Solidity 0.5.0 依旧没有推出。这也就意味着,目前所有的智能合约都可能会受到该 bug 的影响。我们将会在 3.2.2 节 中说一说这个 bug 可能的影响面。想了解蜜罐智能合约而非 bug 攻击面的读者可以跳过这一小节

对于该蜜罐智能合约而言,当 forceReseed() 被调用后,s.component4 = tx.gasprice*7; 将会覆盖掉 LuckyNumber 的值,使之为 7。而用户生成的竞猜数字只会是 1 或者 0,这也就意味着用户将永远不可能赢得彩票。

1.3 以太币竞争游戏

合约关键代码如下:

这个智能合约有趣的地方在于它设置了最大转账上限是 50 finney,最小转账下限是 2 wei(条件是大于 1 wei,也就是最小 2 wei)。每次转账之后,最大转账上限都会缩小成原来的一半,当总转账数量大于等于 100 finney,那就可以取出庄家在初始化智能合约时放进的钱。

假设我们转账了 x 次,那我们最多可以转的金额如下:50 50(1/2)^1 50(1/2)^2 50(1/2)^3 ...... 50(1/2)^x

根据所学的知识我们可以知道,该数字将会永远小于 100

50(1/2)^0 50(1/2)^1 50(1/2)^2 50(1/2)^3 ...... < 50*2

该智能合约中设置的赢取条件就是总转账数量大于等于 100 finney。这也就意味着,没有人可以达到赢取的条件!

合约 智能 竞猜 bug 数字
分享到:

1.TMT观察网遵循行业规范,任何转载的稿件都会明确标注作者和来源;
2.TMT观察网的原创文章,请转载时务必注明文章作者和"来源:TMT观察网",不尊重原创的行为TMT观察网或将追究责任;
3.作者投稿可能会经TMT观察网编辑修改或补充。


专题报道