A tutorial that teaches how to use Supra dVRF to serve random numbers using an onchain randomness generation mechanism directly within your smart contracts on the Base testnet.
curl -L https://foundry.paradigm.xyz | bash
foundryup
, to install the latest (nightly) build of FoundryRNGContract
. The smart contract’s constructor takes in a single address
and assigns it to a member variable named supraAddr
. This address corresponds to the contract address of the Supra Router Contract that will be used to generate random numbers. The contract address of the Supra Router Contract on Base Sepolia testnet is 0x99a021029EBC90020B193e111Ae2726264a111A2
.
The contract also assigns the contract deployer (msg.sender
) to a member variable named supraClientAddress
. This should be the client wallet address that is registered and whitelisted to use Supra VRF (see: Prerequisites).
src/ExampleContract.sol
, and delete the src/Counter.sol
contract that was generated with the project. (you can also delete the test/Counter.t.sol
and script/Counter.s.sol
files).
The following sections will guide you step-by-step on how to update your contract to generate random numbers using the Supra Router contract.
ISupraRouter
interface defines a generateRequest
function. This function is used to create a request for random numbers. The generateRequest
function is defined twice, because one of the definitions allows for an optional _clientSeed
(defaults to 0
) for additional unpredictability.
ISupraRouter
interface in a separate interface file and inherit the interface in your contract.ISupraRouter
, you are ready to add the logic to your smart contract for requesting random numbers.
For Supra dVRF, adding logic for requesting random numbers requires two functions:
rng
that requests random numbers using the Supra Router Contract. Add this function to your smart contract:
rng
function above requests 5
random numbers (defined by rngCount
), and waits 1
confirmation (defined by numConfirmations
) before considering the result to be final. It makes this request by calling the generateRequest
function of the Supra Router contract, while providing a callback function with the signature requestCallback(uint256,uint256[])
.
generateRequest
method of the Supra Router contract expects a signature for a callback function. This callback function must be of the form: uint256 nonce, uint256[] calldata rngList
, and must include validation code, such that only the Supra Router contract can call the function.
To do this, add the following callback function (requestCallback
) to your smart contract:
requestCallback
is executed by the Supra Router. The code above stores the resulting random numbers list in a map named rngForNonce
using the _nonce
argument. Because of this, you will need to add the following mapping to your contract:
nonce
, you add a third function:
cast wallet import
command to import the private key of the wallet into Foundry’s securely encrypted keystore:
deployer
account in your Foundry project, run:
.env
file in the home directory of your project, and add the RPC URL for the Base Sepolia testnet, as well as the Supra Router contract address for Base Sepolia testnet:
.env
file has been created, run the following command to load the environment variables in the current command line session:
forge create
command. The command requires you to specify the smart contract you want to deploy, an RPC URL of the network you want to deploy to, and the account you want to deploy with.
To deploy the RNGContract
smart contract to the Base Sepolia test network, run the following command:
cast
command-line tool that can be used to interact with the smart contract that was deployed and call the getLatestPrice()
function to fetch the latest price of ETH.
To call the getLatestPrice()
function of the smart contract, run:
nonce
value.
You can use this nonce
value to call the viewRngForNonce(uint256)
function to get the resulting list of randomly generated numbers: