4

I know that the "how to generate random number" in solidity is a very common question. However, after reading the great majority of answers I did not find one to fit my case.

A short description of what I want to do is: I have a list of objects that each have a unique id, a number. I need to produce a list that contains 25% of those objects, randomly selected each time the function is called. The person calling the function cannot be depended on to provide input that will somehow influence predictably the resulting list.

The only answer I found that gives a secure random number was Here. However, it depends on input coming from the participants and it is meant to address a gambling scenario. I cannot use it in my implementation.

All other cases mention that the number generated is going to be predictable, and even some of those depend on a singular input to produce a single random number. Once again, does not help me.

Summarising, I need a function that will give me multiple, non-predictable, random numbers.

Thanks for any help.

riverwastaken
  • 285
  • 6
  • 19
  • Does this answer your question? [How-to generate a random number](https://stackoverflow.com/questions/48848948/how-to-generate-a-random-number) – Patrick Collins Jun 29 '20 at 04:32
  • And here https://stackoverflow.com/questions/52467248/how-can-we-generate-multiple-random-number-in-ethereum – Alberto Perez Oct 24 '20 at 17:34

3 Answers3

5

Here is an option:

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));
}

It generates a random number between 0-999, and basically it's impossible to predict it (It has been used by some famous Dapps like Fomo3D).

StillFantasy
  • 1,677
  • 9
  • 21
  • I think it is not a perfect solution, you still can make another smartcontract with this same logic (just hijacking msg.sender), execute it on the same tx calling the smartcontract to be attacked, and you will be knowing what random number will be given – Alberto Perez Oct 24 '20 at 13:46
  • @AlbertoPerez True, so you have to check is the tx sender address a contract or not. – StillFantasy Oct 25 '20 at 14:03
1

Smart Contracts are deterministic, so, basically every functions are predictable - if we know input, we will be and we should be know output. And you cannot get random number without any input - almost every language generates "pseudo random number" using clock. This means, you will not get random number in blockchain using simple method.

There are many interesting methods to generate random number using Smart Contract - using DAO, Oracle, etc. - but they all have some trade-offs.

So in conclusion, There is no method you are looking for. You need to sacrifice something.

:(

changhwan
  • 1,000
  • 8
  • 22
0

100% randomness is definitely impossible on Ethereum. The reason for that is that when distributed nodes are building from the scratch the blockchain they will build the state by running every single transaction ever created on the blockchain, and all of them have to achieve the exact same final status. In order to do that randomness is totally forbidden from the Ethereum Virtual Machine, since otherwise each execution of the exact same code would potentially yield a different result, which would make impossible to reach a common final status among all participants of the network.

That being said, there are projects like RanDAO that pretend to create trustable pseudorandomness on the blockchain.

In any case, there are approaches to achieve pseudandomness, being two of the most important ones commit-reveal techniques and using an oracle (or a combination of both).

As an example that just occurred to me: you could use Oraclize to call from time to time to a trusted external JSON API that returns pseudorandom numbers and verify on the contract that the call has truly been performed.

Of course the downside of these methods is that you and/or your users will have to spend more gas executing the smart contracts, but it's in my opinion a fair price for the huge benefits in security.

José Molina
  • 529
  • 2
  • 7