# Randomness
Random numbers are widely used in Vite. One good case is the process to reach consensus, where a random number is chosen in each round in the purpose of determining which SBP is responsible for producing the next snapshot block, thus avoid being predicted in advance. Another scenario is in gambling games the results are generated depending on unpredictable random numbers to avoid manipulation.
When we design the random number, it should meet the following criteria:
- Must NOT be manipulable
- Must NOT be predictable
# Random Numbers on Vite
The design comes from the common dicing game in real world. Basically, a simple dicing game will go through the following 3 steps:
- Dealer shakes the dice box
- Player guesses the dice number and makes bet
- Dealer uncovers dice box and shows result
In this game, dealer can have two ways to cheat:
- Changes the result after player bets
- Reveals the result to another player in conspiracy
In real world, we can take the following precautions to reduce the probability of cheating, but none of them has 100% guarantees.
- Perform careful dicing equipments inspection
- Supervise the dicing process
- Rely on dealer's reputation
Luckily, in the blockchain world, a more secure and efficient way can be used to prevent a dealer from manipulating results - the random numbers.
This is equivalent to the following steps in the dicing example:
- Add multiple dealers. The dicing results from each dealer will be submitted to calculation of the final result. As long as one dealer is honest, the final result is safe. A dealer must conspire with all rest dealers in order to cheat.
- When the dicing result is generated, the result hash is calculated and shown in public for verification purpose before the player makes bet. The dicing result, when it is finally published, should match the hash. This effectively prevents the result from being tampered with.
Figure 1 shows how above idea is implemented in Vite
Each random number goes through three steps in the lifecycle:
- is published when is generated
- is published
- is safely used
In the figure, block to are six consecutive snapshot blocks produced by 3 SBPs (we assume the network has only 3 SBPs).
In each round of producing a snapshot block, an SBP should publish both:
- The hash of random number in the current round.
- The random number that was generated by this SBP in the last round.
For example, SBP1 published (the hash of random number in ) and (the random number generated in ) in . The network will test if , meaning the hash of must be equal to , otherwise is invalid.
At this time, we can calculate a random seed based on the random numbers published by the SBPs in previous rounds. When is produced, the random seed at this block is $$Seed_{N+5} = Sum(random_{N+2}, random_{N+1}, random_{N})$$ This result is unpredictable, and not a single SBP is able to manipulate the result.
In actual implementation, in order to save storage, is in uint64
, and is limited to 32-byte length.
In addition, for security reason such as preventing from brute-force attack, the hash function is defined as following:
See VEP-12: The Implementation of Random Numbers in Vite (opens new window) for more details.
# Using Random Seed in Contract
On Vite, contract execution is split into a pair of request and response. If random numbers are used in the contract, in order to obtain a random seed, the contract must wait at least until a given number x of snapshot blocks that contain published random numbers are produced. x is called Random Degree.
When deploying a contract that uses the global function random64()
or nextrandom()
, you need specify a positive Random Degree and Response Latency, otherwise the deployment will fail.
See here for more details about Random Degree and Response Latency.