1、随机数基础:什么是真随机与伪随机,链上为什么需要随机数,常见的链上随机数应用场景

各位同学好,我是你们的老朋友。今天咱们正式开课,聊聊随机数。

说实话,我入行做区块链安全那会儿,第一个让我头疼的问题就是随机数。为什么?因为链上环境太特殊了——所有节点都在执行同一段代码,所有数据都是公开的。你想想看,在这种环境下要生成一个「别人猜不到」的数字,是不是有点反直觉?

好,咱们一步步来。

1.1 真随机 vs 伪随机:到底差在哪?

先问个问题:你手机上的「随机播放」是真的随机吗?

不是。它只是算法算出来的一个序列,看起来没有规律而已。这就是伪随机数

伪随机数的核心特征是:只要知道种子(seed)和算法,就能复现整个序列。比如经典的线性同余生成器:

// 线性同余生成器 (LCG)
next = (a * current + c) % m

你给个初始值 current,后面每个数都是确定的。这在普通软件里够用了,但在区块链上——嗯,问题很大。

那什么是真随机数

真随机数来源于物理世界的不可预测事件。比如:

  • 放射性衰变的时间间隔
  • 大气噪声的波动
  • 量子力学中的测量结果

这些事件在理论上就是不可预测的。我曾在一次安全审计中见过一个项目,他们用「鼠标移动轨迹」来生成种子——这其实也算一种物理随机源,但问题是链上没法复现这个过程。

核心区别一句话总结:

伪随机 = 算法 + 种子 → 可复现

真随机 = 物理事件 → 不可复现

1.2 链上为什么需要随机数?

你可能会想:普通程序里用随机数很正常,但区块链上每一步都要验证,要随机数干嘛?

我举个例子你就明白了。

假设你做了一个链上抽奖游戏。用户买彩票,开奖时从所有买家中随机选一个中奖者。如果这个「随机」过程可以被预测,那会怎样?

——矿工可以提前算出谁中奖,然后自己买那张彩票。或者更狠一点,直接回滚交易重试。

这就是为什么链上随机数必须满足两个条件:

  1. 不可预测性:在生成之前,任何人都无法知道结果
  2. 可验证性:生成之后,任何人都能验证这个结果是公平的

说白了,链上随机数不是为了「随机」而随机,而是为了公平

个人经验:我审计过一个DeFi项目,他们用 block.timestamp 做随机种子。结果呢?矿工可以微调时间戳来操控结果。这种漏洞我见过不下十次,每次都是血泪教训。

1.3 常见的链上随机数应用场景

好,理论讲完了,咱们看看实际中哪些地方需要随机数。

场景一:NFT 铸造

这是最典型的场景。你铸造一个NFT,它的稀有度、属性、甚至图片本身都是随机生成的。比如:

  • 某NFT项目有10000个角色,其中1%是传说级
  • 铸造时随机决定你拿到的是普通、稀有还是传说

如果随机数被操控,那传说级NFT就全被内部人拿走了。我见过一个项目,他们的随机数生成器用的是 keccak256(abi.encodePacked(blockhash, msg.sender))——这其实是可以被矿工预测的。

场景二:链上游戏

不管是卡牌游戏、回合制战斗还是盲盒机制,随机数都是核心。比如:

  • 《Axie Infinity》中的基因遗传
  • 《Dark Forest》中的星球生成
  • 各种「抽卡」游戏中的掉落率

我曾经审计过一个链游,他们用 block.difficulty 做随机源。嗯,这个值在以太坊上是可以被矿工轻微影响的。结果就是——高等级装备永远被同一个地址抽到。

场景三:抽奖与竞拍

链上抽奖、盲拍、荷兰拍等场景也依赖随机数。比如:

  • 彩票开奖:从所有参与者中随机选一个
  • 公平分发:按随机顺序分配稀缺资源
  • 治理投票:随机选取验证节点

避坑指南:我曾经接手过一个抽奖合约,它用 blockhash(block.number - 1) 作为随机种子。看起来没问题对吧?但攻击者可以写一个合约,在同一个区块内先调用抽奖函数,根据结果决定是否参与。这就是「抢跑攻击」的典型手法。

1.4 一个小总结

好了,咱们今天的内容就这些。总结一下:

概念 特点 链上适用性
真随机 物理源、不可复现 难以直接获取
伪随机 算法驱动、可复现 需要小心设计
链上随机需求 不可预测 + 可验证 必须满足两者

下一章,我会带你深入分析「为什么简单的随机数方案在链上都不安全」,以及攻击者到底是怎么钻空子的。到时候我会拿几个真实漏洞案例来讲,保证让你印象深刻。

今天就到这儿。记住:链上随机数不是技术问题,是博弈问题