I would like someone to tell me if I am neglecting serious security concerns here. I Am trying to create a Solidity slot machine where hash puzzles (leading zeros) are used to get various jackpots. However, I can't just use a nonce as someone could test nonces offchain and submit the winning one first try. So I've been looking into PRNGs. And I found future blockhashes to be a solid idea as it's very unlikely a miner will be the creator of each and every block in a sequence. The code bellow is a quick simple example of logic for a lottery contract where users submit guesses that must "vest" a number of blocks before they can be checked for a win.
contract Lottery{
uint128 difficulty;
uint128 immutable public BLOCK_VEST_PERIOD;
mapping(address => guess) entry;
struct guess{
bytes32 guess;
uint256 vestEnd;
}
constructor(uint128 _vestPeriod, uint128 _difficulty){
BLOCK_VEST_PERIOD = _vestPeriod;
difficulty = _difficulty;
}
function submitEntry(uint128 _x)external{
entry[msg.sender] = guess(
keccak256(abi.encodePacked(_x)), //guess is stored as the hash of the number entry
block.number + BLOCK_VEST_PERIOD
);
}
/// @dev returns true if entry is a winner
function claimEntry()external returns(bool){
require(block.number - entry[msg.sender].vestEnd < 256, "cannot claimEntry if more than 255 blocks have passed");
require(block.number >= entry[msg.sender].vestEnd, "must wait a few more blocks for vesting to end. For security reasons");
bytes32 hash = entry[msg.sender].guess;
for(uint128 i = 0; i < BLOCK_VEST_PERIOD; i++){
hash = keccak256(abi.encodePacked(
hash,
blockhash(i)
));
}
return hashPuzzle(hash);
}
function hashPuzzle(bytes32 _entry) public returns(bool){
/// @dev will return true if hash's leading 0s >= difficulty
}
}
As far as I can tell the only way to cheat this system would be to have control of every block or at least the last block as a miner could discard it if unfavorable to get a second chance. However, this seems to be a negligible advantage in practice, especially if a hash puzzle is sufficiently difficult. Please let me know if I am wrong about this.