Random Number Generation
Ranodm number generation (RNG), also commonly known as verifiable random functions (VRF) within blockchain; is a common tool used by developers of financial, gaming, social, and creative applications. Blockchains are known for traditionally being unable to generate provably random values due to the lack of shared rng values (i.e getting a random number at some point in time).
SKALE has solved this problem of random number generation nativley available within a blockchain thanks to the use of BLS threshold encyption. Every SKALE Chain includes a built-in random number generation feature that allows for a unique value to be derived from the chains threshold signature every single block using the previous blocks supermajority signature.
SKALE chain consensus is asynchronous and leaderless with each and every block signed by a minimum of 11 out of 16 nodes in the SKALE Chain. The signatures are combined in a way that prevents any single node from influencing the final outcome, ensuring the randomness cannot be tampered with or manipulated by any individual entity.
Achieving Randomness
Section titled “Achieving Randomness”The following steps are used to generate a unique random number:
- Signatures for the current block are retrieved
- The BLAKE3 hash of the signatures is created
- The resulting RNG value in hex format is presented
The SKALE Chain makes this value available through a Solidity precompiled contract.
Accessing Random Values
Section titled “Accessing Random Values”To generate random values on SKALE, you can use the code snippet below. Prefer to use a pre-built contract? Checkout the SKALE RNG Library below.
-
Code to retrieve the random bytes
The code bellow showcases how to use the pre-compiled random number generation function. It uses the function
getBlockRandom
to call the precompiled contract at the address0x18
.// SDPX-License-Identifier: MITpragma solidity ^0.8.13;contract GenerateRandomNumbers {function getRandom() public view returns (bytes32 addr) {assembly {let freemem := mload(0x40)let start_addr := add(freemem, 0)if iszero(staticcall(gas(), 0x18, 0, 0, start_addr, 32)) {invalid()}addr := mload(freemem)}}} -
Returned random bytes
Running the
getRandom()
function several times returns something similar to the following example. Each different result corresponds to a new block:Terminal window 0:bytes32: addr 0xb01da4532b80108eee3d00d48d6c617869eabfa39acbb58b7fd44e83693315010:bytes32: addr 0x48e4af915a9cf211474c11fec16dd40164a1d6d82dec93a646b4b776261a9fe50:bytes32: addr 0x7d95dd4d341e6bf27ce37e1dc531319daa1dfd75efe4a5f1b1de1f30624251550:bytes32: addr 0x80494d5289618a28ca5ed57803404a4c3b379699d81ae1badf408fb8341c8ef70:bytes32: addr 0xfd66a3c359c1c73f285f881105bb8ef5185cc04d5c8c7360c4386f0673ecc98b0:bytes32: addr 0xb95f1c2be3b13371115b8e6431461a24e960f0bb9881420993528ce68b019f75 -
Converting random bytes into uint256
The random bytes returned by the
getRandom()
function can be handled in different ways depending on the use case. One of the most common cases is generating a simple random uint256.To achieve the random uint256 its only required to cast the random bytes into a uint256:
function getRandomNumber() public view returns (uint256) {return uint256(getRandom());}
SKALE RNG Library
Section titled “SKALE RNG Library”The SKALE RNG library built by Dirt Road Development and TheGreatAxios takes the above and wraps it with a number of easy to use helpers.
-
Import the following npm package:
Terminal window npm i @dirtroad/skale-rng -
Import to your contract the RNG contract from the package:
import "@dirtroad/skale-rng/contracts/RNG.sol"; -
Utilize the function(s) from the RNG contract that suits you better
-
Example:
// SPDX-License-Identifer: MITpragma solidity ^0.8.19;import "@dirtroad/skale-rng/contracts/RNG.sol";contract GenerateRandomNumbers is RNG {function generateRandomNumber() external returns(uint256){return getRandomNumber();}function generateRandomNumberInRange(uint256 minRange, uint256 maxRange) external returns(uint256) {return getNextRandomRange(minRange, maxRange);}}
Q: How do you access random numbers on SKALE?
Section titled “Q: How do you access random numbers on SKALE?”RNG is available through a precompiled smart contract on each SKALE Chain.
You can use a function call in Solidity to access the bytes32
random value.
This can then be converted into a number by casting to a uint256
Q: Does it cost money to use SKALE RNG?
Section titled “Q: Does it cost money to use SKALE RNG?”No, random number generation on SKALE is 100% free since there are zero gas fees on SKALE and accessing random numbers is just a read in Solidity.
Q: Do I have to wait to use the random number?
Section titled “Q: Do I have to wait to use the random number?”No, unlike using VRF or other randomness technologies on most networks; you do not have to wait multiple blocks to use the random value generated on SKALE. Additionally, there are no callbacks on SKALE. Callbacks are a popular pattern in the Chainlink infrastructure which you do not have to deal with on SKALE since the values are available immediatley from the chain and don’t have to be generated from a 3rd party network.