5月29日 22:35

Solidity 中如何安全地生成随机数?

Solidity 无法原生生成真随机数——block.timestampblock.difficultyblockhash 都可被矿工操纵,永远不要用于决定资金分配。安全方案分三类:Chainlink VRF(链上验证的链下随机数,生产首选)、commit-reveal(双方各提交哈希再揭示,适合两方博弈)、Randao/Drand(去中心化随机数网络,多节点协作生成)。Chainlink VRF 流程:请求时传 seed → Chainlink 链下生成随机数 + 证明 → 回调函数中验证证明后使用随机数,链上可验证不可篡改。

追问

blockhash 为什么不安全?

blockhash(block.number - 1) 看似不可预测,但矿工可以选择性打包交易——如果随机结果对自己不利就不出块。而且 blockhash 只保留最近 256 个区块,超过就返回 0。

请求约 5 万 gas,回调验证约 15-20 万 gas(含证明验证)。总成本约 0.01-0.03 ETH。用 VRF v2 的订阅模式可以预充 Link,比直接支付更灵活。NFT mint、抽奖等高频场景需要考虑成本。

commit-reveal 适合什么场景?

两个参与者博弈(如石头剪刀布):先提交 keccak256(choice + secret) 的哈希(commit),双方都提交后再揭示原始值(reveal),验证哈希匹配。缺点是需要两轮交易,用户体验差,不适合多方或高频场景。

如何防止前端运行随机数结果?

即使随机数来源安全,攻击者可以在 mempool 中看到交易结果后决定是否抢跑。对策:用回调模式(结果在下一次交易中返回,而非同一交易)、加最小延迟、或使用 Flashbots 等私有内存池。

游戏中随机数用什么方案?

小额休闲游戏用 Chainlink VRF v2(成本可控、链上可验证)。大型链游用混合方案:VRF 生成种子 → 链上伪随机函数展开成序列 → 玩家行为(提交 nonce)参与混合,兼顾公平和性能。

标签:Solidity