W3Schools



如果我正在为某种(赌博)游戏撰写智能合约,我该如何安全地生成一个随机数?需要注意哪些最佳实践和安全权衡取舍?

contract-designsecuritygambling
12个回答
12

你可以用HTTPS://API.random.org/JSON-RPC/1/ which gives you a random source of data through JSON and Oraclize which allows you to make use of the feed inside an Ethereum contract and optionally have it strongly authenticated as having come from random.org. (Along with existing methods of using the hash of the block, timestamp, and such.)

你会“信任”random.org来为你提供随机数据。您可以通过使用多个随机源来降低风险。


6

简短的回答是你不能。 RANDAO工作,但速度很慢,如果你的游戏很受欢迎,人们就会有强烈的动机来应用最后一个数字。

我建议使用oracle来提供随机性。 (如Tjaden Hess的Notes and Alternatives 2c中所述。)两个主要的好处是你可以强烈断言你的号码独立于任何其他赌注,这对定价使用该号码的风险至关重要。其次,熵吞吐量实际上没有限制。如果存在神谕市场,那么您可以利用区块链的不可撤销历史来模拟特定神谕与玩家勾结的可能性。当然,玩家,房子和神谕都提供自己的熵。可以根据需要添加诸如白名单,黑名单,断言非共谋等的其他特征。


6

由于不同的合同确保不同的价值, at the RANDAO频谱的另一端是简单的BLOCKHASH.

如果BLOCKHASH可能适合您的目的,强烈建议您查看问题(以下只是一个片段):

什么时候BLOCKHASH可以安全地用于随机数?什么时候不安全?

作为一般规则,BLOCKHASH只能安全地用于随机   如果价值的总量取决于质量的数量   通过挖掘单个区块,随机性低于矿工的收入。


17

请注意,根据linagee的建议,您不仅仅信任random.org,您还信任Oraclize。 Oraclize发布了一个TLS公证证明,他们给你的数据确实来自random.org,但这还不足以解决这个问题:我们需要知道这是只要 data they got from random.org. Otherwise they could keep trying and throwing away random numbers from random.org until they got one which won their bet, and you would have no way of detecting this.


1

让我们假设您使用块哈希来决定彩票赢家,而矿工A参与该彩票并购买一张彩票。然后,如果他们不适合他的票,他就会开采许多有效的街区并扔掉它们。

在实践中,矿工扔掉的每个有效区块都要花费他5个铜。如果您的彩票的赔率是如此,那么矿工A必须创造1 000 000个有效区块,直到他找到一个适当的区块让他获胜,他将丢弃5 000 000个醚。

如果你的彩票的主要胜利是1 000 000醚,那么矿工扔掉5 000 000 eth以赢得1 000 000是毫无意义的。


3

在我看来,这里提出的各种建议都有一个共同的模型,其中智能合约充当服务器本质上是一个常规的单服务器/多客户端架构,而且很多问题是矿工将对系统进行游戏 - 这就是当存在单个可信服务器时一直存在的问题。

为什么不把它放在一边而根本不涉及随机数生成过程中的合同?

类似彩票的游戏可能会以这种方式运作:

  • 每个赌徒向彩票合同提交包含费用,所需“挑选”号码和加密随机种子值的交易。如果同一个赌徒想要选择另一个号码,那么只需要付费和选择 - 种子是每个赌徒,而不是每个赌注。

  • 投注结束后,赌徒发送另一笔交易 - 这次只包含解密他种子的钥匙。

  • 在每个人都提供了解密密钥(或足够的时间流逝)之后,每个赌徒都会获取所有密钥和加密种子并计算“真实”随机数 - 可能只是解密种子的模数和。如果它是赌徒的选择之一,则向合同发送交易,使合同验证赌徒提供种子,验证交易中提供的中奖号码实际上是否正确并且被赌徒选中,并且然后奖励奖金。

这里有很多挥手和遗留的细节,但我相信基本的想法是合理的。


1

我有一个基于Tjaden协议的想法,我在这里概述:

这种方法是对以太坊彩票的声音和/或新颖吗?

它解决了必须在彩票中存入大额保证金的问题。会很感激一些反馈。


0

这个流程怎么样:

1)每个用户生成一个字符串“我是彩票的一部分,我的号码是8272143”(秘密),其中8272143是自选的号码。

2)每个用户使用自己选择的密码(秘密)加密自己的字符串

3)每个用户发布加密的字符串,所以现在每个人都可以看到所有加密的字符串

4)当决定不允许更多参与者时,所有用户都发布他们自己选择的密码并且所有字符串都被解密。不发布密码的用户将被排除在获胜之外。

5)每个人都可以确认,每个玩家都说出了他们密码的真相,因为字符串的第一部分必须是“我是彩票的一部分而我的号码是”,所以此时无法伪造另一个号码。

6)现在连接所有字符串,并生成散列。这个哈希是最后的随机数! In case of a lottery, you could pick the number closest to the hash, but this is just a case specific detail.

这样,就没有等待块完成了。只有强制解密字符串才能获得优势。使用足够强的加密可以避免这种情况。

(我是这个领域的新秀,如果这只是胡说八道的话,我就袒露。)

更新:

我意识到,如果两个客户一起工作,最后一个客户可以选择等待发布他的密码并被排除,以防他的朋友以这种方式获胜。 一个解决方案可以是,所有用户在线路上都有一定数量的ETH,他们将不得不支付他们的密码。总而言之,这个解决方案并不是很性感,我承认。


0

来自Oraclize的Marco来自这里。 您可以使用Oraclize随机数据源,它可以利用a莱杰 Trusted Execution Environment.

你可以阅读一篇介绍这里 and some examples 这里.

随机数据源比使用带有TLSNotary的Random.org和使用blockhash确定随机数更安全,并且它比其他提交显示方案更难和更昂贵。


0

产生随机数的另一种方式可以是将各种随机源分配到平台中以便为获胜的票证播种。例如,我们可以使用世界主要证券交易所交易的每只股票收盘价的分数。几乎不可能让所有证券交易所共同努力篡改乐透。

收盘价格由各种服务显示,包括雅虎,谷歌,彭博等,因此他们可以作为一种公共分类帐来验证价格是否正确。

此外,由于许多直接交易员,算法,公司交易员等涉及改变这些价格,几乎不可能预测最后交易价格将是什么或等待最后一秒成为最后一个交易的人。股票。


0

请尝试以下算法以防止作弊。

这个想法是使用块的哈希值,但矿工/参与者和组织者不知道块号以防止作弊。

  1. 在开始组织者定义随机uint64 - 钥匙号码 to be used in the winner random number calculation. The uint number is big enough and known to organizer only on start.
  2. 组织者修复了钥匙号码 by providing hash of sum - the number plus current block hash (as a salt). The key hash is stored in the Lottery contract and available for all the participants. Then key hash is used to prevent organizers cheating and fixes the key number.
  3. 参与者购买门票,彩票合约存储所有参与者地址。地址也用于获胜者计算。
  4. 当满足条件时(例如,所有门票都被出售或者产生必要数量的块或仅在一段时间之后),组织者开始赢家计算。
  5. 组织者提供存储的钥匙号码 and confirms the number is exactly the same by calculating the key hash (entered on init).
  6. 钥匙号码 is added to the sum of addresses and we got mod 255 of the sum to detect number of block which hash is used to detect winner. Key number + address1 + address2 ... + addressN % 255 = number of winner block (the block hash is used to get winner number)

对于想要猜测中奖号码的人来说,不可能得到号码 - 在合同中我们只是哈希的号码。这个数字是相当大的uint64(或者可能更大),以防止“打乱”数字。 对于组织者来说,这个数字是固定的,并且是徒劳的,因为必须知道所有的门票所有者地址才能计算出胜利者。

意见?逻辑中的任何漏洞?

我创建一个单独的问题 but it could be answered here as well.