返回论坛
智能合约安全审计技术分享 — 随机数
查找币:余老师
|
学术研究
|
2025-12-05 23:00
|
11 次浏览
|
0 条回复
查找币
学术研究
安全研究
Web3安全
区块链安全
查找币 - 专业Web3安全服务
🔐 钱包恢复服务 | 💰 加密货币找回 | 🛡️ 区块链安全审计
专业团队,安全可靠,成功率高 | Professional Team, Secure & Reliable, High Success Rate
**作者:小白@查找币安全团队**
## 背景概述
在之前的文章中,我们探讨了 delegatecall 函数的特性以及正确的使用方式。本文将带领大家深入了解智能合约中经常使用的随机数。
## 前置知识
智能合约开发中常常需要使用随机数,例如彩票和流行的 NFT 数字藏品的属性等。目前常见的随机数获取方式有两种:使用区块变量生成随机数和使用预言机生成随机数。接下来我们将介绍这两种方法的特点:
### 使用区块变量生成随机数
常见的区块变量包括:
- block.difficulty(uint):当前区块难度
- blockhash(uint blockNumber) returns (bytes32):给定区块的哈希
- block.number(uint):当前区块号
- block.timestamp(uint):当前区块时间戳
从区块数据生成随机数可能会限制普通用户预测随机数的可能性,但无法阻止矿工作恶的行为。矿工可以选择是否广播挖出的区块,从而影响随机数结果。因此,使用区块变量生成随机数更适用于一些非核心业务的应用。
### 使用预言机生成随机数
预言机是为生成随机数种子而设计的链上或链下服务。无论是依赖第三方服务还是自己搭建链下服务,都存在一定的安全风险。因此,使用链下服务获取随机数依赖于可信且稳定的第三方服务。
## 漏洞示例
以下是一个猜数字赢以太的漏洞示例合约:
```solidity
pragma solidity ^0.8.13;
contract GuessTheRandomNumber {
constructor() payable {}
function guess(uint _guess) public {
uint answer = uint(keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp)));
if (_guess == answer) {
(bool sent, ) = msg.sender.call{value: 1 ether}("");
require(sent, "Failed to send Ether");
}
}
}
```
## 漏洞分析
在该合约中,使用了 abi.encodePacked 和 keccak256 两个函数:
- `abi.encodePacked` 对参数进行编码,`solidity` 提供两种编码方法:`encode` 和 `encodePacked`。
- `keccak256` 是哈希算法,用于将任意长度的输入压缩成 64 位的 16 进制数字。
合约部署者使用上个区块的区块哈希和区块时间作为随机数种子生成随机数。然而,这种弱随机数可能导致安全风险。
## 审计者角色
审计者在审计过程中遇到随机数应特别关注随机数种子来源。几乎所有使用区块变量的方法都难以避免矿工作恶的可能性。当遇到使用第三方提供的随机数种子时,应提醒项目方确认来源的可靠性,避免第三方作恶或硬件问题。建议项目方接入知名预言机来获取安全的随机数。
本文参考于《Solidity by Example》[参考链接](https://solidity-by-example.org/hacks/randomness)。
---
**本文由查找币安全团队整理发布**
往期回顾:
- [从 The Saudis NFT 事件浅析 EIP-2535 钻石协议](#)
- [熊市新考验 —— XCarnival NFT 借贷协议漏洞分析](#)
- [智能合约安全审计入门篇 —— delegatecall (2)](#)
- [保护你的钱包!假钱包全景追踪](#)
- [查找币科技成为国家级数字文创规范治理生态矩阵首批协作发展伙伴](#)
**查找币导航**
- [查找币科技官网](https://www.查找币.com/)
- [查找币区官网](https://查找币.io/)
- [查找币 GitHub](https://github.com/查找币)
- [Telegram](https://t.me/查找币team)
- [Twitter](https://twitter.com/@查找币_team)
- [Medium](https://medium.com/@查找币)
- [知识星球](https://t.zsxq.com/Q3zNvvF)