Search
You are viewing the VRF v2 guide.
If you are using v1, see the VRF v1 guide.
Security Considerations
Be sure to review your contracts with the security considerations in mind.
This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2. For more advanced examples with programmatic subscription configuration, see the Programmatic Subscription page. To explore more applications of VRF, refer to our blog.
Subscription Manager
Read the Subcription Manager UI page to learn how to use all the features of the VRF v2 user interface. To learn how to troubleshoot your VRF requests, read the pending and failed requests sections.
Go to vrf.chain.link to open the Subscription Manager.
Topics
This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
If you are new to developing smart contracts on Ethereum, see the Getting Started guide to learn the basics.
For this example, create a new subscription on the Goerli testnet.
Open MetaMask and set it to use the Goerli testnet. The Subscription Manager detects your network based on the active network in MetaMask.
Check MetaMask to make sure you have testnet ETH and LINK on Goerli. You can get testnet ETH and LINK at one of the available Goerli faucets.
Open the Subscription Manager at vrf.chain.link.
Click Create Subscription and follow the instructions to create a new subscription account. MetaMask opens and asks you to confirm payment to create the account on-chain. After you approve the transaction, the network confirms the creation of your subscription account on-chain.
After the subscription is created, click Add funds and follow the instructions to fund your subscription. For this example, a balance of 2 LINK is sufficient. MetaMask opens to confirm the LINK transfer to your subscription. After you approve the transaction, the network confirms the transfer of your LINK token to your subscription account.
After you add funds, click Add consumer. A page opens with your account details and subscription ID.
Record your subscription ID, which you need for your consumer contract. You will add the consumer to your subscription later.
You can always find your subscription IDs, balances, and consumers at vrf.chain.link.
Now that you have a funded subscription account and your subscription ID, create and deploy a VRF v2 compatible contract.
For this example, use the VRFv2Consumer.sol sample contract. This contract imports the following dependencies:
The contract also includes pre-configured values for the necessary request parameters such as vrfCoordinator
address, link
token contract address, and gas lane keyHash
. You can change these parameters if you want to experiment on different testnets, but for this example you only need to specify subscriptionId
when you deploy the contract.
Build and deploy the contract on Goerli.
Open the VRFv2Consumer.sol
contract in Remix.
On the Compile tab in Remix, compile the VRFv2Consumer.sol
contract.
Configure your deployment. On the Deploy tab in Remix, select the Injected Provider Environment, select the VRFv2Consumer
contract from the contract list, and specify your subscriptionId
so the constructor can set it.
Click the Deploy button to deploy your contract on-chain. MetaMask opens and asks you to confirm the transaction.
After you deploy your contract, copy the address from the Deployed Contracts list in Remix. Before you can request randomness from VRF v2, you must add this address as an approved consumer on your subscription account.
Open the Subscription Manager at vrf.chain.link and click the ID of your new subscription under the My Subscriptions list. The subscription details page opens.
Under the Consumers section, click Add consumer.
Enter the address of your consumer contract that you just deployed and click Add consumer. MetaMask opens and asks you to confirm the transaction.
Your example contract is deployed and approved to use your subscription balance to pay for VRF v2 requests. Next, request random values from Chainlink VRF.
The deployed contract requests random values from Chainlink VRF, receives those values, and stores them in the s_randomWords
array. Run the requestRandomWords()
function on your contract to start the request.
Return to Remix and view your deployed contract functions in the Deployed Contracts list.
Click the requestRandomWords()
function to send the request for random values to Chainlink VRF. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, Chainlink VRF processes your request. Chainlink VRF fulfills the request and returns the random values to your contract in a callback to the fulfillRandomWords()
function.
Depending on current testnet conditions, it might take a few minutes for the callback to return the requested random values to your contract. You can see a list of pending requests for your subscription ID at vrf.chain.link.
After the oracle returns the random values to your contract, the s_randomWords
variable stores an array with all of the requested random values. Specify the index of the array that you want to display and click s_randomWords
to print the value. Because this example requests two random values, check the value at index 0
and then check the value at index 1
.
You deployed a simple contract that can request and receive random values from Chainlink VRF. To see more advanced examples where the contract can complete the entire process including subscription setup and management, see the Programmatic Subscription page.
Note on Requesting Randomness
Do not re-request randomness even if you do not receive an answer right away. Doing so would give the VRF service provider the option to withhold a VRF fulfillment, if it doesn't like the outcome, and wait for the re-request in the hopes that it gets a better outcome. This is similar to the considerations with block confirmation time. For more information, see the VRF Security Considerations page.
In this example, your MetaMask wallet is the subscription owner and you created a consumer contract to use that subscription. The consumer contract uses static configuration parameters.
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract VRFv2Consumer is VRFConsumerBaseV2 {
VRFCoordinatorV2Interface COORDINATOR;
// Your subscription ID.
uint64 s_subscriptionId;
// Goerli coordinator. For other networks,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address vrfCoordinator = 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
bytes32 keyHash = 0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Storing each word costs about 20,000 gas,
// so 100,000 is a safe default for this example contract. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 numWords = 2;
uint256[] public s_randomWords;
uint256 public s_requestId;
address s_owner;
constructor(uint64 subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
s_owner = msg.sender;
s_subscriptionId = subscriptionId;
}
// Assumes the subscription is funded sufficiently.
function requestRandomWords() external onlyOwner {
// Will revert if subscription is not set and funded.
s_requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
}
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
s_randomWords = randomWords;
}
modifier onlyOwner() {
require(msg.sender == s_owner);
_;
}
}
The parameters define how your requests will be processed. You can find the values for your network in the VRF Supported Networks page.
uint64 s_subscriptionId
: The subscription ID that this contract uses for funding requests.
address vrfCoordinator
: The address of the Chainlink VRF Coordinator contract.
address link
: The LINK token address for your selected network.
bytes32 keyHash
: The gas lane key hash value, which is the maximum gas price you are willing to pay for a request in wei. It functions as an ID of the off-chain VRF job that runs in response to requests.
uint32 callbackGasLimit
: The limit for how much gas to use for the callback request to your contract's fulfillRandomWords()
function. It must be less than the maxGasLimit
limit on the coordinator contract. In this example, the fulfillRandomWords()
function stores two random values, which cost about 20,000 gas each, so a limit of 100,000 gas is sufficient. Adjust this value for larger requests depending on how your fulfillRandomWords()
function processes and stores the received random values. If your callbackGasLimit
is not sufficient, the callback will fail and your subscription is still charged for the work done to generate your requested random values.
uint16 requestConfirmations
: How many confirmations the Chainlink node should wait before responding. The longer the node waits, the more secure the random value is. It must be greater than the minimumRequestBlockConfirmations
limit on the coordinator contract.
uint32 numWords
: How many random values to request. If you can use several random values in a single callback, you can reduce the amount of gas that you spend per random value. The total cost of the callback request depends on how your fulfillRandomWords()
function processes and stores the received random values, so adjust your callbackGasLimit
accordingly.
The contract includes the following functions:
requestRandomWords()
: Takes your specified parameters and submits the request to the VRF coordinator contract.
fulfillRandomWords()
: Receives random values and stores them with your contract.
Security Considerations
Be sure to review your contracts to make sure they follow the best practices on the security considerations page.
After you are done with this contract and the subscription, you can retrieve the remaining testnet LINK to use with other examples.
Open the Subscription Manager at vrf.chain.link and click the ID of your new subscription under the My Subscriptions list. The subscription details page opens.
Under your subscription details, click Cancel subscription. A field opens asking which wallet address you want to send the remaining funds to.
Enter your wallet address and click Cancel subscription. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, Chainlink VRF closes your subscription account and sends the remaining LINK to your wallet.
You must import the VRFCoordinatorV2
Vyper interface. You can find it here.
You can find a VRFConsumerV2
example here. Read the apeworx-starter-kit README to learn how to run the example.