Accessing a Random Seed with a Smart Contract
The RandomAura contract allows smart contracts to access a random number generated on-chain by the protocol.

Public getters:

  • currentSeed: access the network's random seed.
  • collectRoundLength: length in blocks for each collection round (commit + reveal phases)
  • isCommitPhase: returns true if current block is in commit phase
  • nextCommitPhaseStartBlock : retrieve block number of first block in next commit phase.
  • nextRevealPhaseStartBlock : retrieve block number of first block in next reveal phase.
The public getter currentSeed is used to access the network's random seed. Its value is only updated when the revealNumber function is called. This should occur at least once per collection round. The length in blocks of each collection round can be retrieved with the collectRoundLength public getter.
There are two phases in each round, a commit phase and a reveal phase. Since the revealing validator always knows the next random number before sending it, a DApp should prohibit business logic actions that depend on a random value during the reveal phase.
For example, a gambling application that relies on a random value should only allow bets to be placed during the commit phase. This type of application must prevent users from placing new bets during the entire reveal phase.
To determine the current phase, use the isCommitPhase public getter: it returns true if the current block is in the commit phase and false if the block is in the reveal phase.
To retrieve the number of the first block of the next commit phase, use the nextCommitPhaseStartBlock public getter. To do the same for the reveal phase, use the nextRevealPhaseStartBlock public getter.
Random numbers are updated during the reveal phase when validators produce block for the first time. For example, there can be 17 validators, but the reveal phase length is 38 blocks. So, during the reveal phase, the current seed will only be updated 17 times.
The commit & reveal phases have lengths of 38 blocks each. The total collection round (commit phase + reveal phase) has 76 blocks (38+38).

Example code to retrieve a random seed

1
pragma solidity 0.5.16;
2
3
4
interface IPOSDAORandom {
5
function collectRoundLength() external view returns(uint256);
6
function currentSeed() external view returns(uint256);
7
}
8
9
contract Example {
10
IPOSDAORandom private _posdaoRandomContract; // address of RandomAuRa contract
11
uint256 private _seed;
12
uint256 private _seedLastBlock;
13
uint256 private _updateInterval;
14
15
constructor(IPOSDAORandom _randomContract) public {
16
require(_randomContract != IPOSDAORandom(0));
17
_posdaoRandomContract = _randomContract;
18
_seed = _randomContract.currentSeed();
19
_seedLastBlock = block.number;
20
_updateInterval = _randomContract.collectRoundLength();
21
require(_updateInterval != 0);
22
}
23
24
function useSeed() public {
25
if (_wasSeedUpdated()) {
26
// using updated _seed ...
27
} else {
28
// using _seed ...
29
}
30
}
31
32
function _wasSeedUpdated() private returns(bool) {
33
if (block.number - _seedLastBlock <= _updateInterval) {
34
return false;
35
}
36
37
_updateInterval = _posdaoRandomContract.collectRoundLength();
38
39
uint256 remoteSeed = _posdaoRandomContract.currentSeed();
40
if (remoteSeed != _seed) {
41
_seed = remoteSeed;
42
_seedLastBlock = block.number;
43
return true;
44
}
45
return false;
46
}
47
}
Copied!
Last modified 5mo ago
Export as PDF
Copy link