1

I am reading the following article from a website: bad randomness

In the context of Blockhash the author says: For instance, a good protocol (formulating a random trial as a “bet”) is the following:

• accept a bet, with payment, register the block number of the bet transaction

• in a later transaction, compute the blockhash of the earlier-registered block number, and use it to determine the success of the bet.

Somebody please guide me what is meant by registered block number.

Zulfi.

1 Answer 1

1

The phrasing is a bit strange. You basically have to store a future blockhash number to be used, e.g., just the current blocknumber + 2. This blockhash is completely unknown at the time of the transaction, can only be influenced to some degree by Ethereum miners and thus provides a good-enough source of randomness for some protocols.

The approach would basically be:

  1. Store future block number in the last accepted bet.
  2. Inside the determine winner function evaluate the blockhash from the block number and compute the winner. Also handle the case if no one called this function for more than 256 blocks after the stored block number (see your other question: Blockhash Minus-256 Problem).

This is a simple example with a single function to gamble with ETH:

mapping (address => uint256) gameWeiValues;
mapping (address => uint256) blockHashesToBeUsed;

function playGame() public {
    if (!blockHashesToBeUsed[msg.sender]) {
        // first run, determine block hash to be used                          
        blockHashesToBeUsed[msg.sender] = block.number + 2; // use 2 or more
        gameWeiValues[msg.sender] = msg.value;
        return;
    }

    uint256 randomNumber = uint256(blockhash(blockHashesToBeUsed[msg.sender]));

    blockHashesToBeUsed[msg.sender] = 0;
    gameWeiValues[msg.sender] = 0;

    // randomNumber = 0 means expired blockhash, player looses
    if (randomNumber != 0 || randomNumber % 2 == 0) {
        uint256 winningAmount = gameWeiValues[msg.sender] * 2;
        msg.sender.transfer(winningAmount);    
    }
}

See also https://soliditydeveloper.com/2019-06-23-randomness-blockchain.

8
  • It means there is no concept of registering the block number. How can we store the future block number in the last accepted bet?
    – zak100
    Jun 1, 2020 at 23:04
  • 1
    @zak100 See my example, the line blockHashesToBeUsed[msg.sender] = block.number + 2; does exactly that. Jun 1, 2020 at 23:30
  • 1
    @zak100 block.number + 2 is a block number in the future, i.e., a block that is not yet mined and thus has an unknown block hash. (I think there was some issue with using block.number + 1 but cannot remember what exactly right now) Jun 3, 2020 at 1:36
  • 1
    @zak100 Let's assume somebody calls playGame() the first time at block 100. It would then store block 102 inside blockHashesToBeUsed[msg.sender]. Now let's assume he calls playGame() the second time at block 400 (> 102 + 256). This would result in blockhash(blockHashesToBeUsed[msg.sender]) = blockhash(102) = 0x0 => randomNumber = 0. Later on we check if if (randomNumber != 0) and a player automatically losses if it's 0. Jun 3, 2020 at 23:41
  • 1
    @zak100 Just an example which will be 50% of the times 0 and 50% of the times 1 ensuring a fair game between player and bank. It's the modulo operator which gives the remainder after division. In other words number % 2 == 0 means 'is the number even (=> true) or odd (=> false)?'. Jun 5, 2020 at 3:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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