For a game I have implemented Chainlink VRF and a basic RNG for small games where the fee of Chainlink wouldn't make sense.

For the 3rd parameter to abi.encodePacked (some seed data? docs suck so not exactly sure), I pass all the public keys of players who have entered the game.

function basicRNG(address[] memory players) public view returns (uint256) {
    return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));

Since this is so much simpler than VRF I wonder are there drawbacks?:

  • Could the random number generation somehow be manipulated? I would imagine the only way would be if the attacker was the only one who entered the game, because how could they control for an unknown public key affecting the random number?

Also bonus: any idea how gas-intensive passing a large array would be? Such as a 1000 player (1000 public key) game?

1 Answer 1


Some issues with your code for RNG:

  1. block.timestamp can be manipulated by the miner so it should not be used as a source of randomness. Since block.difficulty and the players array are fixed values at the point of execution, the miner just needs to choose an appropriate block.timestamp that would yield the desired outcome.

  2. Passing a large array of players just to calculate randomness with keccak256 is gas-inefficient (if you're calling it within a transaction). Just because you're passing more data to the hash function doesn't make it "more random". Instead, try to find a better source of random number.

Best of luck :)


Your Answer

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

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