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.

  • You can probably use keccak256(now) in your contract. I think that this function might have changed between v0.4 and v0.5, so you might want to check the official documentation for the exact syntax. – goodvibration Jun 19 '19 at 12:32
  • and how do I determine the range with keccak? – 2stefan Jun 19 '19 at 14:24

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.


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;
|improve this answer|||||
  • thanks. Since I'm relatively new to Solidity, could you further the part with scaling the uint to a desired range? Would you recommend Oraclize to receive a "random" number? – 2stefan Jun 19 '19 at 19:30
  • Scaling - divide the original number by a factor to ensure the result is below a maximum. It's hard to recommend confidently without knowing the use-case. That's why I added the caution item to the hash technique idea which is simpler, as long as it isn't too simple for your case. – Rob Hitchens Jun 19 '19 at 20:20
  • okay. I'm working on a token for the first time. Everything is clear and simple but just this randomness factor which I'd like to scale to a range between 0 to 1 (0% to 100%) is driving me crazy – 2stefan Jun 19 '19 at 20:31
  • In the example, change the SCALE to 100 and drop the parts about offset because you don't need it. Since you mentioned percent, you might run into further challenges with integer math. 0-100 is the right way to start, or even 0-1000 for an extra digit of precision. – Rob Hitchens Jun 19 '19 at 20:43
  • 1
    Multiply x * 100 then divide by 80 to get 80% of x. Have a look at this for more hints: ethereum.stackexchange.com/questions/15090/… – Rob Hitchens Jun 19 '19 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.