After reading a lot of Info about this topic in this forum I am asking whether I can just use the formular winningNumber = uint256(blockhash(block.number-1)) % 100; e.g. 10 or 20 blocks after the betting period is finished. The "future" blockhash can not be known by anyone during the betting period right? e.g. implementing in solidity could be similar to this? require (block.number > (BettingEndBlock+20);

  • You still have the problem that block hashes are controlled by the miner. – Ismael Feb 19 at 16:27
  • There is not only one valid solution for the mining puzzle (for different nonces you could find another hashblock that fulfill the condition). usually, miners give directly the first valid answer (blockhash&nonce) they found to win the reward before others do... However, they can calculate the winning number and if they want to benefit from your lottery then they could risk it and look after another valid hash that makes them win. – Majd TL Feb 19 at 17:09

The important thing is to separate the commitment and the reveal so that no one can "guess" the "solution" from "this" block.

It would be sufficient, I think, to work with block.number + 1, so 100 blocks into the future don't add significant difficulty. Miners will always have a slight opportunity to craft blocks a certain way but I think it is negligible.


function claimPrize(bytes32 solution) public {
  bytes32 check = keccak256(abi.encodePacked(block.hash));
  require(solution == check, "Incorrect");
  // award prize

The problem is it is trivial to compute the "solution" in the context of the current block and then collect the prize.

Commit / Reveal:

function commit(bytes32 committment) public {
  commitments[msg.sender] = commitment; // over-simplified

function claimPrize() public {
  require(block.number >= deadline, "lottery still open");
  bytes32 solution = // ... block hash at deadline
  require(committments[msg.sender] == solution, "You didn't win");
  // award prize

In case it isn't clear, future block hash isn't knowable. The important thing is to ensure that the contest is based on a future block hash, not the present one (or the past).

Hope it helps.

| improve this answer | |
  • 1
    Thanks for the fast reply! the line "require(committments[msg.sender] = solution, "You didn't win");" was with a double "==" for comparison right? I will use your solution. thanks! – Tabaluga Feb 19 at 16:45
  • Thanks for the catch. Fixed it. :-) – Rob Hitchens Feb 19 at 18:38

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.