VRFConsumerBase
VRF v1
Last updated
VRF v1
Last updated
RNG cannot be done on-chain the blockchain is deterministic -> all nodes must come to the same consensus.
Off-chain RNG, but verifiable on-chain.
Smart contracts send requests for randomness
Requests are sent to a VRF Coordinator, which is another contract on-chain
The VRF Coordinator hands this request to an off-chain chainlink oracle for RNG.
After RNG, VRF Coordinator verifies the randomness of the result on-chain.
To consume randomness we first need to import and inherit from VRFConsumerBase
and define two required functions:
requestRandomness
: Make a request to the VRFCoordinator.
fulfillRandomness
: Called by VRFCoordinator when it receives a valid VRF proof.
Your contract should own enough LINK to pay the specified fee.
Note, the below values have to be configured correctly for VRF requests to work. You can find the respective values for your network in the VRF Contracts page.
LINK Token
- LINK token address on the corresponding network (Ethereum, Polygon, BSC, etc)
VRF Coordinator
- address of the Chainlink VRF Coordinator
Key Hash
- public key against which randomness is generated
Fee
- fee required to fulfill a VRF request
MyContract inherits VRFConsumerBase, and therefore its constructor as well.
_vrfCoordinator -> address of the VRF coordinator contract on the chain we are deploying to.
_link -> address of the Link token contract on the chain.
VRF Coordinator is a smart contract that receives requests, hands them off-chain, and subsequently verifies randomness of the generated number on-chain.
The random number generation is done off-chain via chainlink's oracle network.
In MyContract, getRandomNumber() calls on requestRandomness(keyHash, fee). This has been imported from VRFConsumerbase.sol
pass the keyhash of oracle node
pass the fee for request
The return requestRandomness(keyHash, fee)
will emit a log to the chainlink oracle we have specified with keyHash.
The oracle will look for this request, generate a random number. This is then returned on-chain by VRF coordinator.
seed is deprecated and no longer used. It is kept for backward-compatibility. See VRFConsumerBase.sol for notes.
In your implementation of getRandomNumber() or whichever function that calls on requestRandomness, make sure your contract holds the necessary LINK to successfully call requestRandomness. Else gas estimation error will occur.
Callback function used by VRF Coordinator to return the RNG after on-chain verification.
VRF will call this, by passing the requestID and randomness. We will catch the RNG and store it into randomResult
.
Techincally, VRFConsumerBase calls rawFulfillRandomness()
on verification:
This ensures that only VRF coordinator can respond and call fulfillRandomness
, to prevent spoofed responses.
Also fulfillRandomness is internal, therefore can only be called by rawFulfillRandomness,
and not other external functions.
VRF Coordinator looks for the function signature of fulfillRandomness on our contract and calls it. Which is why we must inherit this function from VRFConsumerBase and override it to suit our needs.
** Function signature is the hash of the function name.
requestRandomness()
will call transferAndCall()
through the LINK interface
transferAndCall() originates from the LINK token contract, and is interacted with through an interface that was imported: LinkTokenInterface.sol
in VRFConsumerBase.sol import "./interfaces/LinkTokenInterface.sol"; (state) LinkTokenInterface immutable internal LINK (constructor) LINK = LinkTokenInterface(_link);
transferAndCall sends our link tokens as fee and will call on the coordinator we specified.
Smart contracts send requests for randomness
Requests sent to VRF Coordinator contract, via requestRandomness(keyHash, fee, userprovidedSeed)
inherited from VRFConsumerBase.sol
VRF Coordinator hands this request to an off-chain chainlink oracle for RNG.
After RNG, VRF Coordinator verifies the randomness of the result on-chain.