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:
- Store future block number in the last accepted bet.
- 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.
blockHashesToBeUsed[msg.sender] = block.number + 2;does exactly that. – Markus - soliditydeveloper.com Jun 01 '20 at 23:30block.number + 2is 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 usingblock.number + 1but cannot remember what exactly right now) – Markus - soliditydeveloper.com Jun 03 '20 at 01:36playGame()the first time at block 100. It would then store block 102 insideblockHashesToBeUsed[msg.sender]. Now let's assume he callsplayGame()the second time at block 400 (> 102 + 256). This would result inblockhash(blockHashesToBeUsed[msg.sender]) = blockhash(102) = 0x0=>randomNumber = 0. Later on we check ifif (randomNumber != 0)and a player automatically losses if it's 0. – Markus - soliditydeveloper.com Jun 03 '20 at 23:41number % 2 == 0means 'is the number even (=> true) or odd (=> false)?'. – Markus - soliditydeveloper.com Jun 05 '20 at 03:33