Generating acceptable randomness on POA with Solidity


#1

The goal: generate random numbers on player input, similar to a dice roll.

From cursory exploration of Google, ETH Stackexchange, Medium, here’s my impression of the topic:

  • randomness is really hard. Especially with blockchains, due to their deterministic nature.
  • solutions relying on timestamps, blockhashes, block difficulty are vulnerable to local simulations to get the desired output.
  • if there is monetary value tied to the transaction, miner collusion can happen beyond a certain threshold.

I’m thinking of using future blockhashes rather than instant. The player initiates the “dice roll” with his selected odds through one transaction. Then, after at least 1 block, he sends another transaction that will settle the dice roll, using the previously provided values and the “future” block hash (now mined).

I assume there’s no way to guess a future blockhash in advance. Is this assumption correct?

Likewise, because on POA we have validators who stake their identity and alternate mining blocks at regular intervals, collusion would be an easy-to-spot social suicide.

Let’s assume the above is correct. My current implementation for a random number is as follows:

uint(keccak256(abi.encodePacked(blockhash(resolveBlock[msg.sender]), resolveBlock[msg.sender]))) % 100;

where “resolveBlock[msg.sender]” is the next block number from the previous transaction.

It seems to generate a random number from 0 to 99, and I’m not seeing any problem with it. But, I’m green behind the ears in computer science, and I would love to know if anyone spots a problem with the idea. :slight_smile:


#2

I assume there’s no way to guess a future blockhash in advance. Is this assumption correct?

Yes, it’s very hard to calc a hash of the future block because nobody knows in advance which transactions and data will be there: https://ethereum.stackexchange.com/questions/2100/what-is-a-block-hash

Likewise, because on POA we have validators who stake their identity and alternate mining blocks at regular intervals, collusion would be an easy-to-spot social suicide.

If we’re not talking about big money profit which could be got as a result of such collusion, then your solution based on blockhash can be used, I guess.

Maybe it’s better to save two or three future block numbers and then get their hashes when they mined, to increase entropy (instead of one block you’re saving in resolveBlock).

There also RANDAO can be used to get random seed, but RANDAO requires the participation of some addresses which should be interested in committing/revealing their secret numbers.


#3

If we’re not talking about big money profit which could be got as a result of such collusion, then your solution based on blockhash can be used, I guess.

Maybe it’s better to save two or three future block numbers and then get their hashes when they mined, to increase entropy (instead of one block you’re saving in resolveBlock ).

It would likely be trivial amounts if at all. Saving 2 blocks rather than one sounds like a great solution, too. I think it wouldn’t be a problem to make the user wait for >10s rather than >5s for these specific actions, given that there’s at least a 5s wait.

Thank you! :slight_smile:


#4

@SnailKing Please keep in mind that in solidity you can only access 256 range blocks which means if you made a commit for block 1, then a player can spam the network for next 256 blocks in order to get blockhash 0. So you have to account that in smart contract:

 if (block.number - gameBlock < 256) {
   //cancel game or something
} 

We have done an audit for randomness in
https://dragonereum.io/ game where we found a number of vulnerable issues with RNG.
https://github.com/peppersec/public-audit-reports/blob/b78dfc9feee1f85f5e69a564eab7f8801f80bc39/reports_pdf/Dragonereum-audit-report.pdf

Please let us know if you would be interested in auditing your game @ hello@peppersec.com


#5

Thanks @rstorm! I was aware of that peculiarity, but really should have specified it for any lurker out there. Good stuff!

It’s very early for my own game, but your Dragonereum audit was a nice read. Some familiar mistakes… Some interesting suggestions for fixes. :slight_smile:


#6

I’m glad to help. Let me know if there is anything I can do for you.