当前位置: 首页 > news >正文

Q7: 在区块链上创建随机数有哪些挑战?

在这里插入图片描述

欢迎来到《Solidity面试修炼之道》专栏💎。

专栏核心理念:

核心 Slogan💸💸:从面试题到实战精通,你的 Web3 开发进阶指南。

一句话介绍🔬🔬: 150+ 道面试题 × 103 篇深度解析 = 你的 Solidity 修炼秘籍。

  1. ✅ 名称有深度和系统性
  2. ✅ "修炼"体现进阶过程
  3. ✅ 适合中文技术社区
  4. ✅ 记忆度高,易于传播
  5. ✅ 全场景适用

Q7: 在区块链上创建随机数有哪些挑战?

简答:
区块链是确定性和公开的,矿工/验证者可以预测或操纵随机数来源(如区块哈希、时间戳),使得生成真正的随机数非常困难。

详细分析:
在区块链上生成随机数面临两个根本性挑战:

  1. 确定性:区块链的核心特性是所有节点必须能够独立验证交易结果。这意味着给定相同的输入,智能合约必须产生相同的输出。真正的随机性与这一要求相矛盾。

  2. 公开性:区块链上的所有数据都是公开的,包括区块哈希、时间戳、交易数据等。攻击者可以在提交交易前看到这些值,从而预测"随机"结果。

常见的不安全随机数来源:

  • block.timestamp:矿工可以在一定范围内操纵
  • block.difficulty / block.prevrandao:可预测或可操纵
  • blockhash():只能访问最近 256 个区块,且可预测
  • tx.originmsg.sender:攻击者可控

安全的解决方案:

  1. Chainlink VRF:使用可验证随机函数,提供可证明的随机性
  2. Commit-Reveal 方案:两阶段提交,防止预测
  3. 多方计算:结合多个不可控来源
  4. 预言机:从链下获取随机数

代码示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;/*** @title RandomnessExamples* @notice 演示区块链上随机数的挑战和解决方案*/// ❌ 不安全的随机数生成方法
contract UnsafeRandomness {/*** @notice 使用 block.timestamp - 不安全!* @dev 矿工可以操纵时间戳(约 15 秒范围内)*/function unsafeRandomWithTimestamp() public view returns (uint256) {// ❌ 矿工可以选择有利的时间戳return uint256(keccak256(abi.encodePacked(block.timestamp)));}/*** @notice 使用 blockhash - 不安全!* @dev 可预测,且只能访问最近 256 个区块*/function unsafeRandomWithBlockhash() public view returns (uint256) {// ❌ 攻击者可以等待有利的区块哈希return uint256(blockhash(block.number - 1));}/*** @notice 使用 msg.sender - 不安全!* @dev 攻击者完全控制自己的地址*/function unsafeRandomWithSender() public view returns (uint256) {// ❌ 攻击者可以尝试多个地址直到获得有利结果return uint256(keccak256(abi.encodePacked(msg.sender)));}/*** @notice 组合多个来源 - 仍然不安全!* @dev 虽然更复杂,但仍可预测和操纵*/function unsafeRandomCombined() public view returns (uint256) {// ❌ 所有输入都是公开或可操纵的return uint256(keccak256(abi.encodePacked(block.timestamp,block.difficulty,msg.sender)));}/*** @notice 演示攻击场景:彩票*/function unsafeLottery() public payable returns (bool) {require(msg.value == 0.1 ether, "Must send 0.1 ETH");// ❌ 不安全的随机数uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp,msg.sender))) % 100;// 如果随机数 < 50,用户获胜if (random < 50) {payable(msg.sender).transfer(0.2 ether);return true;}return false;}
}/*** @title AttackUnsafeLottery* @notice 演示如何攻击不安全的随机数*/
contract AttackUnsafeLottery {UnsafeRandomness public target;constructor(address _target) {target = UnsafeRandomness(_target);}/*** @notice 攻击:只在能赢时才参与*/function attack() public payable {// 预测随机数uint256 predictedRandom = uint256(keccak256(abi.encodePacked(block.timestamp,address(this)))) % 100;// 只在能赢时才调用if (predictedRandom < 50) {target.unsafeLottery{value: 0.1 ether}();}}
}// ✅ 安全方案 1:Commit-Reveal 模式
contract CommitRevealLottery {struct Commitment {bytes32 commit;uint256 blockNumber;bool revealed;}mapping(address => Commitment) public commitments;uint256 public revealDeadline;/*** @notice 第一阶段:提交承诺* @param _commitment 承诺哈希 = keccak256(abi.encodePacked(secret, address))*/function commit(bytes32 _commitment) public payable {require(msg.value == 0.1 ether, "Must send 0.1 ETH");require(commitments[msg.sender].commit == bytes32(0), "Already committed");commitments[msg.sender] = Commitment({commit: _commitment,blockNumber: block.number,revealed: false});}/*** @notice 第二阶段:揭示秘密* @param _secret 原始秘密*/function reveal(uint256 _secret) public {Commitment storage c = commitments[msg.sender];require(c.commit != bytes32(0), "No commitment");require(!c.revealed, "Already revealed");require(block.number > c.blockNumber + 1, "Too early");// 验证承诺bytes32 hash = keccak256(abi.encodePacked(_secret, msg.sender));require(hash == c.commit, "Invalid secret");c.revealed = true;// 使用秘密和未来区块哈希生成随机数uint256 random = uint256(keccak256(abi.encodePacked(_secret,blockhash(c.blockNumber + 1)))) % 100;if (random < 50) {payable(msg.sender).transfer(0.2 ether);}}
}// ✅ 安全方案 2:Chainlink VRF 接口示例
interface VRFCoordinatorV2Interface {function requestRandomWords(bytes32 keyHash,uint64 subId,uint16 minimumRequestConfirmations,uint32 callbackGasLimit,uint32 numWords) external returns (uint256 requestId);
}contract ChainlinkVRFLottery {VRFCoordinatorV2Interface public vrfCoordinator;bytes32 public keyHash;uint64 public subscriptionId;mapping(uint256 => address) public requestIdToPlayer;constructor(address _vrfCoordinator,bytes32 _keyHash,uint64 _subscriptionId) {vrfCoordinator = VRFCoordinatorV2Interface(_vrfCoordinator);keyHash = _keyHash;subscriptionId = _subscriptionId;}/*** @notice 参与彩票:请求随机数*/function enterLottery() public payable returns (uint256) {require(msg.value == 0.1 ether, "Must send 0.1 ETH");// 请求随机数uint256 requestId = vrfCoordinator.requestRandomWords(keyHash,subscriptionId,3, // 确认数100000, // callback gas limit1 // 随机数数量);requestIdToPlayer[requestId] = msg.sender;return requestId;}/*** @notice Chainlink VRF 回调函数* @dev 由 VRF Coordinator 调用*/function fulfillRandomWords(uint256 requestId,uint256[] memory randomWords) internal {address player = requestIdToPlayer[requestId];uint256 random = randomWords[0] % 100;if (random < 50) {payable(player).transfer(0.2 ether);}}
}

理论补充:
随机数攻击的类型:

  1. 预测攻击:攻击者在交易前计算随机数,只在有利时才提交交易
  2. 操纵攻击:矿工选择性地包含或排除交易,或操纵区块参数
  3. 重放攻击:在多个区块中尝试相同的操作,直到获得有利结果

Commit-Reveal 方案的工作原理:

  1. Commit 阶段:用户提交 hash(secret + address),不透露秘密
  2. 等待期:等待至少一个区块,确保区块哈希不可预测
  3. Reveal 阶段:用户揭示秘密,合约验证并使用 secret + blockhash 生成随机数

Chainlink VRF 的优势:

  • 使用密码学证明保证随机性
  • 链下生成,链上验证
  • 防止预测和操纵
  • 可验证的公平性

实际应用建议:

  • 低价值场景:可以使用 commit-reveal
  • 高价值场景:必须使用 Chainlink VRF 或类似方案
  • 游戏:考虑使用链下随机数 + 零知识证明
  • 抽奖:使用多方随机数贡献

相关问题:

  • Q9: 荷兰式拍卖和英式拍卖有什么区别?
  • Q37: 什么是提交-揭示方案,什么时候会使用它?
http://www.dtcms.com/a/619288.html

相关文章:

  • 宿城网站建设大连市网站制作电话
  • 做a视频网站有哪些系统优化的目的和意义
  • 网站开发外快如何优化网站打开速度
  • 城市配送联盟平台技术架构深度解析:赋能小 B 端全场景高效配送
  • 公司网站定制自己做网页怎么赚钱
  • 济南网站建设公司按需定制wordpress赞 踩插件
  • 建外贸网站的wordpress源码书籍
  • 织梦网站源码找一品资源企业网站建设费怎么账务处理
  • 如何在国外建设网站百度站长平台验证网站
  • 考研408--组成原理--day3--数字电路(补)加减乘除
  • 深圳企业网站建设推广服务wordpress extra script
  • Python的自述
  • OceanBase 常见异情况汇总
  • 江门网站建设方案开发wordpress云建站教程
  • 14.3 行业应用案例:金融、医疗、教育领域的定制化实践
  • 开发网站的基本原则做移动网站优化快
  • 人工智能技术- 语音语言- 03 ChatGPT 对话、写诗、写小说
  • 怎么制作网站上传太原建筑公司网站
  • 精密万向节能承受的最大扭矩是多少?
  • 游戏:ar从入门到落地
  • 深圳罗湖网站开发惠阳营销网站制作
  • 做门窗的建网站怎么赚钱html购物网站
  • 网络编程就是做网站么网站广告推广怎么做的
  • 【阵列配置】(1)-LSI阵列卡系统下创建\删除\扩容\迁移阵列配置热备
  • 房产网站建设方案的论文wordpress公众号导航主题
  • 多用户跨学科交流系统(4)参数校验+分页搜索全流程的实现
  • 温州市网站制作免费下载app软件官网
  • 联系人网站设计江西省住房建设部官方网站
  • 硬件架构的异构化和硬件指令集生态多样化的必然性以及Wintel商业联盟对科技进步的阻碍
  • 做美食软件视频网站有哪些为什么要做营销型的网站建设