求大佬搬运实现:不受单个矿工控制的链上随机数生成方法

现状

  1. CKB链上几乎没有预言机和VRF。
  2. 即使是EVM上的Chainlink,如果想每次tx都请求随机数,那也是个不小的开销。

偶然发现有人推荐了这个代码片段: 不受单个矿工控制的链上随机数生成方法

希望大佬分析一下,如果矿池的算力达到50%以上,这个算法有没有潜在的风险?
希望熟悉CKB合约的大佬,能够搬运实现一份分享出来。

核心需求的API就是通过block number获取对应的block hash。


// 原文

作者:33357

设计

既然单个矿工可以控制区块 hash,那么可以使用多个区块 hash 来生成随机数。uint256 有 256 位,可以使用最近的 256 个块的 hash 来组成随机数,并且单个区块 hash 只能决定 256 bit 中的 1 bit。

Solidity 版

pragma solidity ^0.8.20;

contract Random {
    // 获取随机数,只能用在 256 个块之前的行为
    function getRandomUsedBefore256() external view returns (uint256 random) {
        // 遍历最近的 256 个块
        for (uint256 i; i < 256; i++) {
            // 获得 (block.number - i) 区块的 hash 的最后 1 位数
            uint256 bit = uint256(blockhash(block.number - i)) & 1;
            // 最后 1 位数依次赋值给 random
            random |= (bit << i);
        }
    }
}

总结

在以上实现中,单个区块的 hash 值只能影响 1 个 bit 的数据。矿工只在 0 和 1 两个结果中选择,对链上随机数生成的影响降到了最小。但由于需要未来 256 个块的 hash 才能生成随机数,因此在所有的投注行为完成之后,必须等待 256 个块才能取随机数,不然随机性是不足的。

需要注意的是,以上所有理论建立在区块生成者是复数并且随机的基础上,如果是单机链,就没有讨论的必要了。

和这篇文章的逻辑类似,都是使用“未来的块”来决定随机数,随机性很强,因为未来的块无法预测,但是使用起来很难受

https://smallyu.net/2023/02/22/一种在区块链上生成随机数的机制/

1 Like

目前 CKB 没办法获得当前交易所在的区块高度