稳定性 - 生成不依赖于输入的不可预测的随机数



我知道固体中的"如何生成随机数"是一个非常常见的问题。但是,在阅读了绝大多数答案后,我没有找到适合我的情况。

对我想做的简短描述是:我有一个对象列表,每个对象都有一个唯一的 id,一个数字。我需要生成一个包含 25% 这些对象的列表,每次调用函数时随机选择。 不能依赖调用函数的人提供输入,这些输入将以某种方式影响结果列表的可预测性。

我发现唯一给出安全随机数的答案是这里。但是,这取决于参与者的意见,旨在解决赌博场景。我不能在我的实现中使用它。

所有其他情况都提到生成的数字将是可预测的,甚至其中一些依赖于单个输入来产生单个随机数。再一次,对我没有帮助。

总而言之,我需要一个函数,它可以给我多个不可预测的随机数。

感谢您的任何帮助。

这是一个选项:

function rand()
public
view
returns(uint256)
{
uint256 seed = uint256(keccak256(abi.encodePacked(
block.timestamp + block.difficulty +
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) +
block.gaslimit + 
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)) +
block.number
)));
return (seed - ((seed / 1000) * 1000));
}

它生成一个介于 0-999 之间的随机数,基本上无法预测它(它已被一些著名的 Dapp 使用,如 Fomo3D(。

智能合约是确定性的,所以,基本上每个函数都是可预测的——如果我们知道输入,我们就会知道,我们应该知道输出。而且你不可能在没有任何输入的情况下获得随机数——几乎每种语言都使用时钟生成"伪随机数"。这意味着,您不会使用简单的方法在区块链中获得随机数。

有许多有趣的方法可以使用智能合约生成随机数 - 使用DAO,Oracle等 - 但它们都有一些权衡。

所以总而言之,没有你正在寻找的方法。你需要牺牲一些东西。

:(

在以太坊上绝对不可能100%随机。原因是,当分布式节点从头开始构建区块链时,它们将通过运行在区块链上创建的每笔交易来构建状态,并且所有这些都必须达到完全相同的最终状态。为了做到这一点,以太坊虚拟机完全禁止随机性,因为否则每次执行完全相同的代码都可能产生不同的结果,这将使网络的所有参与者无法达到共同的最终状态。

话虽如此,像RanDAO这样的项目假装在区块链上创建可信赖的伪随机性。

无论如何,有一些方法可以实现假丹主义,这是两种最重要的提交揭示技术,并使用预言机(或两者的组合(。

作为我刚刚想到的一个例子:您可以使用 Oraclize 不时调用受信任的外部 JSON API,该 API 返回伪随机数并在合约上验证调用是否确实已执行。

当然,这些方法的缺点是你和/或你的用户将不得不花费更多的汽油来执行智能合约,但在我看来,这对于安全方面的巨大好处来说是一个公平的价格。

最新更新