Random Number Generator in Solidity

How would you implement an RNG in solidity?

It seems obvious to me that in order to prevent miners from cheating the RNG, any randomisation used for contracts will have to be based on something the miners cannot manipulate, meaning they cannot affect the result, or know it ahead of time.

@shanzida Definitely, cryptokitties did it in an interesting manner. It's still subject to abuse, but less so. There's also orcalize, or using bitcoin's hash as a seed for RNG.

try out this
//THIS SMART CONTRACT IS CONSUMING A LOT OF GAS
//THIS IS DEMONSTRATION OF RANDOM NUMBER GENERATOR
//DO NOT USE IT FOR PRODUCTION

pragma solidity ^0.4.8;

contract Lottery {

mapping (uint8 => address[]) playersByNumber ;

address owner;

function Lottery() public {
    owner = msg.sender;
    state = LotteryState.Accepting;
}

enum LotteryState { Accepting, Finished }

LotteryState state; 

function enter(uint8 number) public payable {
    require(number<=250);
    require(state == LotteryState.Accepting);
    require(msg.value > .001 ether);
    playersByNumber[number].push(msg.sender);
}

function determineWinner() public {
    require(msg.sender == owner);
    
    state = LotteryState.Finished;
    
    uint8 winningNumber = random();
    
    distributeFunds(winningNumber);

    selfdestruct(owner);
}

function distributeFunds(uint8 winningNumber) private returns(uint256) {
    uint256 winnerCount = playersByNumber[winningNumber].length;
            require(winnerCount == 1);
    if (winnerCount > 0) {
        uint256 balanceToDistribute = this.balance/(2*winnerCount);
        for (uint i = 0; i<winnerCount; i++) {
            require(i==0);
            playersByNumber[winningNumber][i].transfer(balanceToDistribute);
        }
    }
    
    return this.balance;
}

function random() private view returns (uint8) {
    return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251);
}

}

But wait? can we trust miners?

@sarahmullen This idea of collecting hashes, then numbers, then generating pseudorandom number based on them, are used and implemented in Randao, think like a DAO for generating random number. I strongly encourage to go further to their documents.

okay let me check that out

For generating a random number in an Ethereum smart contract you can use the following contract / functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
contract random {
/* Generates a random number from 0 to 100 based on the last block hash */
function randomGen(uint seed) private constant returns (uint randomNumber) {
return(uint(sha3(block.blockhash(block.number-1), seed ))%100);
}

/* generates a number from 0 to 2^n based on the last n blocks */
function multiBlockRandomGen(uint seed, uint size) private constant returns (uint randomNumber) {
    uint n = 0;
    for (uint i = 0; i < size; i++){
        if (uint(sha3(block.blockhash(block.number-i-1), seed ))%2==0)
            n += 2**i;
    }
    return n;
}

}