Incorporate Randomness
On-chain randomness techniques and tools detailed.
Last updated
On-chain randomness techniques and tools detailed.
Last updated
Randomness is used in computer programs for many applications. For example, gaming applications, NFT creation, and selecting block authors all require a degree of randomness.
True randomness is hard to come by in deterministic computers. This is particularly true in the context of a blockchain, when all the nodes in the network must agree on the state of the chain. FRAME provides runtime engineers with a source of , using the .
This guide explains how to make use of FRAME's Randomness trait by using the random
method and a nonce as a subject. The guide also illustrates how to add entropy to the randomness value by assigning the RandomCollectiveFlip
pallet to the configuration trait of a pallet that exposes a "random" type.
Randomness
In the pallet you want to use, import the trait from frame_support
:
Include it in your pallet's configuration trait:
Note that the Randomness
trait specifies a generic return of type Output
and BlockNumber
. Use and from frame_system
in your pallet to satisfy that trait requirement.
As stated in , at best, this trait can give you randomness which was hard to predict a long time ago but that has become easy to predict recently. Keep this in mind when you evaluate your use of it.
Use a nonce to serve as a subject for the frame_support::traits::Randomness::random(subject: &[u8])
method.
There are two steps to including a nonce in your pallet:
Create a Nonce
storage item. The storage item can be type u32
or u64
.
Create a private nonce function. This function increments the nonce each time it's used.
The increment_nonce()
private function can be implemented in such a way that it both returns and updates the nonce. For example:
To learn more about the wrapping and encoding methods, see and in the Rust documentation.
Use Randomness in a dispatchable.
Using the nonce, you can call the random()
method that Randomness
exposes. The code snippet below is a mock example that assumes relevant events and storage items have been implemented:
Update your pallet's runtime implementation.
Because you have added a type to your pallet's configuration trait, Config
opens up the opportunity to further enhance the randomness derived by the Randomness
trait. This is accomplished by using the .
Using this pallet alongside the Randomness
trait will significantly improve the entropy being processed by random()
.
In runtime/src/lib.rs
, assuming pallet_random_collective_flip
is instantiated in construct_runtime
as RandomCollectiveFlip
, specify your exposed type in the following way: