文章目录
  1. 1. 文档更新说明
  2. 2. 前言
  3. 3. 原因
  4. 4. 如何公平获取随机数?
  5. 5. 伪随机数
  6. 6. 推荐阅读

文档更新说明

  • 最后更新 2018年04月09日
  • 首次更新 2018年04月09日

前言

  开发以太坊合约,获取随机数是一个超级大的问题,因为以太坊不支持随机数的生成.这是为什么?

原因

  我们采用反证法, 假设合约里可以生成随机数, 那么这就会出现一个问题.如果允许你生成随机数的话,那么你的合约执行结果就是完全具备随机可能了,其他节点无法直接验证你的执行结果是否合法.不诚实的节点完全可以自己随便指定一个数字,或者不停重新计算,直到你得到一个对自己有利的数字(比如赌博,竞猜游戏自己获利的数字),再打包到区块中.
  这个结果很显然是非常不公平的,因此我们是无法直接在以太坊上得到一个随机数的.

如何公平获取随机数?

  我们都知道随机数是多么重要,非常多的场景需要使用到随机数.例如竞猜,赌博,随机分配任务等应用.如果无法获取随机数那就非常遗憾了.所以我们需要解决这个问题.
  如果说,有一个可靠可信的第三方服务提供一个获取随机数的服务,那么这个功能就可以实现了.而且不管是哪一个节点,同一个区块高度获取到的随机数都是一样的,这就可以避免不诚实节点得到自己想要的数字了.而且就算不诚实节点知道自己输了游戏,他还是需要把结果打包进区块里面,不然其他节点也是得到同个结果,自己不打包还少赚矿工费呢.(文末附带方案)

伪随机数

  上面说到的不诚实节点通过作弊获利这个成本其实还是很大的, 因为你想抢在其他节点之前多次计算出一个正确的结果,这是需要非常大的算力.所以一般我们可以使用伪随机数,只要我们的游戏获利的金额比攻击成本低,那么攻击就变得毫无意义啦.
  在Solidity中最好的随机数生成器是 keccak256 哈希函数.我们可以这样来生成一些随机数

// 生成一个0到100的随机数:
uint randNonce = 0;
uint random = uint(keccak256(now, msg.sender, randNonce)) % 100;
randNonce++;
uint random2 = uint(keccak256(now, msg.sender, randNonce)) % 100;

推荐阅读

  最后引入几篇文章,可以从中学习到其他共识算法的区块链(例如PoS算法)生成随机数的方案.当然,包括了怎么在以太坊上获取随机数的方案.
区块链中的随机数
以太坊合约中如何获得真随机数

文章目录
  1. 1. 文档更新说明
  2. 2. 前言
  3. 3. 原因
  4. 4. 如何公平获取随机数?
  5. 5. 伪随机数
  6. 6. 推荐阅读