Solidity 生成不可重复随机数源码

场景

在合约中某些时候需要生成不可重复的随机数,比如NFT的TokenId由已开始的自增序列改为散列随机出现在可允许的范围内。就像开盲盒一样,可以随机开出。同时以太坊的随机数安全性是未知的,因为生成随机数的所有数值在生成之前都是可见的。如果需要生成真随机数可以使用”预言机“。

代码

contract TestHash{
    //散列随机数的范围,此处为6,表明最终的随机数范围 [1,6]
    uint constant public TOKEN_LIMIT = 6;
    //散列数组,用于解决随机时出现重复数值的情况
    uint[TOKEN_LIMIT] public indices;
    //该方法被调用了多少次,等于已经产生的随机数数量。
    uint nonce;
    function randomIndex() public returns (uint) {
        uint totalSize = TOKEN_LIMIT - nonce;
        uint index = uint(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize;
        uint value = 0;
        if (indices[index] != 0) {
            value = indices[index];
        } else {
            value = index;
        }

        // Move last value to selected position
        if (indices[totalSize - 1] == 0) {
            // Array position not initialized, so use position
            indices[index] = totalSize - 1;
        } else {
            // Array position holds a value so use that
            indices[index] = indices[totalSize - 1];
        }
        nonce++;
        // Don't allow a zero index, start counting at 1
        return value+1;
    }
    
}

解释

这段代码的逻辑,仔细思考一下其实不难的。 index是产生随机数,具体做法是将一段bytes进行sha256哈希。然后得到一个uint256长整型对上确界取模。上确界就是总数减去已产生的次数比如总数是6个如果调用这个方法已经产生了2个随机数那么此时的上确界就是4。这段代码解决多次随机到同一个数(上面提到每次调用产生不不重复的数)的方式是,如果随机数相同则把当前的上确界返回,同时把下一个上确界赋值给当前indices数组随机数索引的位置,等待下一次调用。

这段代码的源码来源于 Meebits 的主网合约。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值