We were using self.env.random()
in our contract to generate a random number. The calling user's AccountId
was used to give additional entropy to the random generation.
fn get_random_number(&self, min: u64, max: u64, user_account: AccountId) -> u64 {
let random_seed = self.env().random(user_account.as_ref());
let mut seed_converted: [u8; 32] = Default::default();
seed_converted.copy_from_slice(random_seed.0.as_ref());
let mut rng = ChaChaRng::from_seed(seed_converted);
((rng.next_u64() / u64::MAX) * (max - min) + min) as u64
}
The random number was used to select an index in a Vec<AccountId>
when the caller performed a read operation on the contract. This function allowed us to create basic load balancer functionality, in which the AccountIds in the vector are selected at random. Subsequent operations involving the selected AccountId
are performed off-chain. There is no transaction involved.
Now self.env.random()
has been removed from ink, how should we generate a source of randomness in the contract? The block hash would probably provide a random enough source but it is not available. block_timestamp
is too predictable.