fomo3d游戏区块链开发(fomo3d玩法)

摘要:无论是Fomo3D的山寨版,还是正版原版,都摆脱不了‘一轮冷却’的命运,这与其智能合约的设计缺陷有关。从契约安全发展的角度,详细分析了Fomo3D类游戏的两个问题,并提出了几种可能的解决方案。希望能有所帮助,欢迎感兴趣的朋友加入技术社区讨论。
在黑客的攻击下,Fomo3D类游戏一蹶不振。Fomo3D游戏已经正式进入第三轮。截至北京时间9月29日上午11点,这一轮奖池只累积了97.8988以太,再加上另一轮680以太,总奖池金额不到800以太,与前两轮的盛况相比惨不忍睹。
SECBIT实验室曾经写过一篇文章,分析Fomo3D类游戏的没落状态。我们简单回顾一下[1]。
图1: Fomo3D玩家参与和入场资金
上图为“Fomo3D玩家参与及入场资金”。红色代表调用契约参与游戏的人数,蓝色代表进入游戏契约的资金数量。数据曲线的峰值出现在图的左侧,对应的时间分别是7月20日和7月21日。这两天大量媒体疯狂报道Fomo3D这款现象级游戏。当时众多玩家纷纷效仿,游戏合约参与次数和入场费达到顶峰,入场费金额超过4万以太,最高参与次数超过1.8万次。巅峰过后,Fomo3D游戏人气一落千丈,8月22日左右结束第一轮,之后进入第二轮,但游戏人气一直无法恢复。
即便如此,黑客们并没有停止攻击。
图2: Fomo3D游戏契约被攻击。
上图为“Fomo3D游戏合约被攻击的情况”。在第一轮比赛高峰前后和第二轮开始后,一些黑客疯狂地利用‘空投漏洞’进行攻击,攫取高额利润[2]。在第一轮结束和第二次倒计时结束时,一些黑客疯狂地尝试‘阻断交易’攻击,企图赢得最后的大奖[3]。
不仅仅是最初的Fomo3D游戏,还有很多其他类似Fomo3D的山寨游戏都成为了黑客攻击的目标。
Fomo3D游戏的参与形式是用以太购买游戏道具,最后购买者获得‘最终大奖’。通常参与者有一定概率获得‘空投奖’,分别从主奖池和副奖池中获得。这两种奖励是游戏设计中对参与者的重要激励。这样设计的目的是用‘随机’和‘竞争’来增强游戏的趣味性,吸引更多的人投入其中,从而延长游戏时间。
然而事与愿违,由于契约代码的漏洞,掌握了攻击技能的黑客可以大概率持续获得‘空投奖励’,而‘最终奖品’也会被拥有特殊技能的黑客拿走。普通参与者很难在这类游戏中获得这两个重要的奖励。所以他们只能想象每轮比赛开始后第一时间进场,然后依靠别人的资金拿回自己的钱。但游戏最重要的两个激励机制都失效了,无法持续吸引新的资金,最终形成恶性循环。
黑客是如何利用这两个漏洞的?难道项目方就无能为力了吗?
空投漏洞分析先看‘空投奖励’。
投入游戏的所有乙醚的1%将进入二级奖池。空投概率从0%开始,每增加不低于0.1 ETH的销售订单,空投概率增加0.1%。同时,空投奖励金额也与购买金额挂钩。买0.1 ~ 1 ETH,就有25%的奖金池中奖概率。买的越多,比例越大。游戏界面会清晰显示当前中奖概率和奖池金额。
Fomo3D空投奖励的实现有两个问题:
1.合同中的‘随机数’是可以预测的。
1.判断来电者是否为合同地址的方法存在漏洞。
空投奖励取决于智能合约中生成的‘随机数’,由Fomo3D源代码中的airdrop()函数控制。
airdrop()函数中的“随机数”种子是根据各种块信息和地址计算出来的
为了防止契约自动化攻击,Fomo3D开发者还使用isHuman()阻止契约账号参与Fomo3D游戏,试图禁止玩家在契约中预测中奖随机数。
这里还有一个常见的错误。extcodesize操作符用于获取目标地址的代码大小。对于成功部署的契约,extcodesize的返回值总是大于0,因为它的地址对应于一个特定的代码。所以很多人用这种方法来判断目标地址是不是契约,Fomo3D甚至以此为依据来阻止契约调用特定的函数。但这种判断方法存在明显的漏洞,可以通过在构造新契约的过程中(即在契约构造方法中)调用游戏参与函数来规避。这是因为在构造契约的过程中,它的地址不对应任何代码,extcodesize的返回值是0 [5]。
以上两个安全问题结合在一起,最终导致黑客构造攻击契约,通过契约参与游戏,随意预测随机数,从而大大提高自己的胜率[2]。
如何修复airdrop漏洞?那么如何解决Fomo3D的‘空投漏洞’呢?
黑客可以利用上面列举的两个漏洞构造攻击契约,预测游戏契约中的‘随机数’,从而成功攻击。因此,我们只需要做以下两件事情中的一件,这样就不满足攻击所需的必要条件:
1.防止智能合约中的“随机数”预测
1.采取一种更安全的方式来判断打电话的人是不是合同。
方案1:防止智能合约中的“随机数”预测。先解决‘随机数’预测的问题吧。
“随机数”之所以在智能契约环境下容易被预测,是因为产生“随机数”的“随机源”可以被任何人轻易获得。攻击者可以构造一个攻击契约,在相同的环境下执行‘随机数’计算公式,然后得到所需的‘随机数’,作为下一步行动的判断依据。
智能合约中可用的变量几乎都是公共的,‘随机数’的计算公式需要保证所有节点的执行结果一致。因此,很难找到一种非常简洁的方法来生成不可预测的‘随机数’。
但是还是有一些稍微复杂但是可行的解决方案。例如,开发人员可以在披露(提交/披露)之前提交,或者推迟几个区块的抽签。此外,还有一些引入外部Oracle的方案,如Oraclize和BTCRelay [6]。
SECBIT lab结合Fomo3D游戏机制,介绍了一种利用\ ‘当前/未来\ ‘块的hash值来防止\ ‘随机数\ ‘被预测的方案[7]。
在以太坊智能合约中,可以通过block.blockhash()获取特定块的哈希值。该函数接受块高度作为参数,可接受的范围是除当前块之外最近的256个块。当传入其他值时,该函数返回0。
“随机数”的不安全计算方法将读取当前块的前一个块的hash block . block hash(block . number-1)作为随机源。在协定内执行block.blockhash(block.number)时返回值0。我们无法获得契约内当前块的hash,因为矿工打包执行事务时,还没有计算当前块的hash。所以我们可以认为‘当前块’的hash是‘未来的’,无法预测。
我们可以在用户第一次购买道具参与游戏时,将地址和当前块高N记录成一个数组,最后得到一个唯一的id(如following _purchase()函数所示)。
在接下来的255个方块中,用户可以使用该id再次参与游戏。此时可以正常获取高度为N的块hash,从而生成\ ‘随机数\ ‘并判断用户是否中奖(如following _airdrop()函数所示)。
55块后,用户参与游戏时的块hash在合约中无法正常获取。所以限制用户在一定时间范围内查看是否中奖,参与游戏及时领取奖励很重要。当然,对于游戏体验来说,如果用户错过了奖品,也可以参照上述原则再给他一次抽奖的机会。结合游戏规则,这里还有一些技术细节需要注意。欢迎添加小安同学微信(SECBIT_xiaoanbi),加入“SECBIT智能合约安全技术群”参与讨论。
这种方法也被用在著名的区块链纸牌游戏《被解放的众神》中,用来控制用户购买的纸牌的稀有程度。当然,我们也可以在当前高度之后使用指定数量(比如五个)的块哈希作为随机源。原理是一样的[8]。
选项2:防止合同自动化攻击。另外一个问题,我们怎么判断打电话的人是不是合同地址?
有一个简单而有效的方法。
以太坊安全开发的最佳实践中,建议尽量不要使用tx.origin,因为很多人混淆了tx。Origin with msg.sender. Tx.orign表示一个事务的发起方,而msg.sender表示每个约定调用的发起方。
如果普通账户A调用契约B,契约B又调用契约C。在合同c中,消息发送者是合同b,而发送源是账户a.Msg.sender可以是合约地址,但tx.origin永远不会是合约。因此,上述方法可以有效地防止合同调用合同。
阻塞交易的攻击分析,然后看看最后的奖励。
Fomo3D游戏有倒计时。每轮游戏结束前,最后购买道具的参与者获胜,可以拿走主奖池中将近一半的资金。因此,许多参与者会在接近尾声时发起购买交易来参与游戏。如果他们足够幸运,在最后一刻被矿工挤成块,他们就赢了。
普通人在游戏临近结束时也有类似的策略:盯紧时间,提高油费,发起交易参与游戏,然后闭上眼睛祈祷自己能成为最后一个参与者。但是,用这种方法中奖几乎是不可能的。
根据SECBIT的实验室分析,Fomo3D前两轮的赢家使用了相同的战术,他们都在比赛结束时发起了攻击交易。
胜者(黑客)调用getCurrentRoundInfo()接口,通过事先部署的攻击契约查询游戏信息,重点是剩余时间和最后一个买家的地址。当游戏剩余时间达到一个阈值,最后一个买家是自己时,通过assert()和all Gas,整个交易会失败;会被消耗;剩余时间长或者最后买家不是自己的时候,什么都不做,只消耗一点点气。
赢家(黑客)利用这种方法,发起大量类似的可变神秘交易:在极有可能成为赢家的时候,利用这些费用高昂的神秘交易,吸引矿池先打包,占领后续区块,从而使其他玩家购买钥匙的交易无法正常打包,最终加速游戏结束,大大增加自己的获胜概率。
普通玩家只能手动增加游戏结束时的气价来参与游戏,其他人则尝试使用自动脚本增加游戏结束时的气价来发起游戏交易。相比这些盲目的方法,黑客的攻击技术显然要好得多。
其实这个问题不仅会威胁到Fomo3D游戏。所有采用类似机制的智能合约,即要求玩家在一定时间范围内完成一定的竞技操作,都会受到此威胁。只要游戏奖励足够丰厚,攻击回报远大于投入,就会有人用上面提到的方法破坏游戏的公平性。
方案一:增加攻击成本,为杜绝这一问题,SECBIT实验室建议游戏开发者从游戏机制入手,切断游戏最终胜利(赢得巨额奖金)与倒计时结束(最后一笔交易被打包)之间的必然联系,最大限度降低黑客的攻击获利概率和攻击意愿。
比如我们可以修改游戏规则如下:每轮游戏结束前最后一个购买道具的参与者有获得最终奖品的概率,将这个概率调整到一个较低的值,比如5%。当倒计时结束但大奖因概率原因未正常开出时,合同会自动延长游戏一定时间。这样一来,前面提到的拦网和阻止他人参与游戏的技术,就不能保证攻击者一定会赢得最后的大奖。但黑客持续的‘阻断交易’攻击会耗费大量的气,成本会很高,最终会选择放弃攻击。
以上是示例代码,其中使用shouldRndEnd()函数控制倒计时后的获胜概率,决定这一轮游戏是否真的结束。这里,概率也取决于‘随机数’,无法预测。具体实现原理和前面说的空投概率控制代码差不多。
方案二:禁止合约调用游戏信息查询接口Fomo3D。最后的赢家之所以能够轻松攻击成功,还有一个原因就是游戏契约开通了完整的游戏进度信息查询接口,无论是普通账号还是契约账号都可以随意调用查询。这便于黑客在攻击契约内实时查询游戏状态,进而实施不同的策略,降低攻击成本,提高命中率。
所以,还有一个简单的方法可以防止Fomo3D游戏。getCurrentRoundInfo()函数由前面提到的isHuman () check的安全版本保护,可以有效避免契约自动化攻击。
总结了安全性和公平性问题的Fomo3D原版和山寨版只是‘黑客’掘金的对象,注定无法吸引更多的普通玩家。随着回合的进行,玩家会逐渐流失,这些游戏会进一步衰落。
SECBIT实验室呼吁后来者吸取教训,不要再原封不动地复制代码,不要试图只靠‘操作’来吸引新人。做一些小改动,智能合约的安全性会大大提高,去中心化的游戏可以走得更远。
参考文献[1] FOMO3D获得第二轮大奖,黑客获奖,机制漏洞成为游戏没落的主要原因,https://zhuanlan.zhihu.com/p/45330743, 2018/09/25。
[2]智能合约史上最大攻击战术曝光,盘点黑客团伙细节,https://zhuanlan.zhihu.com/p/42318584, 2018/08/17
[3] \ ‘特攻技能\ ‘,FOMO3D千万大奖得主,完全揭晓,https://zhuanlan.zhihu.com/p/42742004, 2018/08/23
[4]如何PWN FoMo3D,初学者指南,https://www . Reddit . com/r/ether eum/comments/916 xni/howtopwnfomo 3 dabeginnersguide,2018/07/23
[5]使用EVM组件获取地址代码大小,https://ether eum . stack exchange . com/questions/14015/Using-EVM-assembly-to-get-the-address-code-size,2017/04/07
[6]预测以太坊智能合约中的随机数,https://blog . positive . com/Predicting-Random-Numbers-in-ether eum-Smart-Contracts-e 5358 c6b 8620,2018/02/01
[7]在winsome . io-Future block hashes上生成随机数,https://blog . winsome . io/Random-Number-Generation-on-winsome-io-Future-block hashes-Fe 44 B1 c 61d 35,2017/05/07
[8]被解放的神,https://ethers can . io/address/0x 482 cf 6a 9 d6b 23452 c 81d 4d 0 f 0 f 139 c 1414963 f 89 #代码,2018/07/16

其他教程

电子礼花鞭炮(春节电子礼炮电子鞭炮)

2022-8-31 6:01:48

其他教程

如何在微信设置视频通话铃声(怎么设置微信视频通话来电铃声)

2022-8-31 6:03:51

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索