[Ethereum] Random number generation in certain range

contract-designoraclessolidity

I need to add a random number function in my smart contract. Is it best to use Oraclize and e.g. random.org? It's not a lottery which means the random number generation does not require heavy security.

Best Answer

Responding to comments...

Although you say it does not require heavy security, I feel it is worthwhile to mention that a simple hash function would be predictable. For example, keccak256(now) can be calculated, trivially, by another contract that calls into your contract. By working it out ahead of time, it will know, in advance, what your hash function will produce. This works because the time is "now" (same) in both contexts.

Setting the predictability concern aside, you would convert a hash function to a uint, e.g. uint(keccak256(now)) and this will yield a number in the range of 0-2^256-1. You would scale that number to the desired range and precision with divisors and offsets.

Hope it helps.

UPDATE

Scaling is a general programming concern not unique to Solidity. We're just going to take a number with known range and adjust it for another range.

pragma solidity 0.5.1;

contract Randomish {

    uint public constant MAX = uint(0) - uint(1); // using underflow to generate the maximum possible value
    uint public constant SCALE = 500;
    uint public constant SCALIFIER = MAX / SCALE;
    uint public constant OFFSET = 100; 


    // generate a randomish  number between 100 and 600.
    // Warning: It is trivial to know the number this function returns BEFORE calling it. 

    function randomish() public view returns(uint) {
        uint seed = uint(keccak256(abi.encodePacked(now)));
        uint scaled = seed / SCALIFIER;
        uint adjusted = scaled + OFFSET;
        return adjusted;
    }
}
Related Topic