# https://docs.chain.link/vrf llms-full.txt
## Chainlink VRF Overview
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Chainlink VRF](https://docs.chain.link/vrf\#overview)
**Chainlink VRF (Verifiable Random Function)** is a provably fair and verifiable random number generator (RNG) that enables smart contracts to access random values without compromising security or usability. For each request, Chainlink VRF generates one or more random values and cryptographic proof of how those values were determined. The proof is published and verified onchain before any consuming applications can use it. This process ensures that results cannot be tampered with or manipulated by any single entity including oracle operators, miners, users, or smart contract developers.
Use Chainlink VRF to build reliable smart contracts for any applications that rely on unpredictable outcomes:
- Building blockchain games and NFTs.
- Random assignment of duties and resources. For example, randomly assigning judges to cases.
- Choosing a representative sample for consensus mechanisms.
VRF v2.5 includes [all the original benefits of v2](https://blog.chain.link/vrf-v2-mainnet-launch/) and the following additional benefits:
- Easier upgrades to future versions.
- The option to pay for requests in either LINK or native tokens.
Learn how to [migrate to VRF v2.5](https://docs.chain.link/vrf/v2-5/migration-from-v2).
For help with your specific use case, [contact us](https://chain.link/contact) to connect with one of our Solutions Architects. You can also ask questions about Chainlink VRF on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=chainlink).
## [Two methods to request randomness](https://docs.chain.link/vrf\#two-methods-to-request-randomness)
Similarly to VRF v2, VRF v2.5 will offer two methods for requesting randomness:
- [Subscription](https://docs.chain.link/vrf/v2-5/overview/subscription): Create a subscription account and fund its balance with either native tokens or LINK. You can then connect multiple consuming contracts to the subscription account. When the consuming contracts request randomness, the transaction costs are calculated after the randomness requests are fulfilled and the subscription balance is deducted accordingly. This method allows you to fund requests for multiple consumer contracts from a single subscription.
- [Direct funding](https://docs.chain.link/vrf/v2-5/overview/direct-funding): Consuming contracts directly pay with either native tokens or LINK when they request random values. You must directly fund your consumer contracts and ensure that there are enough funds to pay for randomness requests.
## [Choosing the correct method](https://docs.chain.link/vrf\#choosing-the-correct-method)
Depending on your use case, one method might be more suitable than another. Consider the following characteristics when you choose a method:
| [Subscription method](https://docs.chain.link/vrf/v2-5/overview/subscription) | [Direct funding method](https://docs.chain.link/vrf/v2-5/overview/direct-funding) |
| --- | --- |
| Currently available on VRF v2.5 for all supported networks. | Currently available on VRF v2.5 for all supported networks. |
| Suitable for regular requests | Suitable for infrequent one-off requests |
| Supports multiple VRF consuming contracts connected to one subscription account | Each VRF consuming contract directly pays for its requests |
| VRF costs are calculated after requests are fulfilled and then deducted from the subscription balance. Learn [how VRF costs are calculated for the subscription method](https://docs.chain.link/vrf/v2-5/overview/subscription). | VRF costs are estimated and charged at request time, which may make it easier to transfer the cost of VRF to the end user. Learn [how VRF costs are calculated for the direct funding method](https://docs.chain.link/vrf/v2-5/overview/direct-funding). |
| Reduced gas overhead and more control over the maximum gas price for requests | Higher gas overhead than the subscription method |
| More random values returned per single request. See the maximum random values per request for the [V2.5 subscription supported networks](https://docs.chain.link/vrf/v2-5/supported-networks). | Fewer random values returned per single request than the subscription method, due to higher overhead. See the maximum random values per request and gas overhead for the [V2 direct funding supported networks](https://docs.chain.link/vrf/v2-5/supported-networks). |
| You don't have to estimate costs precisely for each request. Ensure that the subscription account has enough funds. | You must estimate transaction costs carefully for each request to ensure the consuming contract has enough funds to pay for the request. |
| Requires a subscription account | No subscription account required |
| VRF costs are billed to your subscription account | No refunds for overpayment after requests are completed |
## [Supported networks](https://docs.chain.link/vrf\#supported-networks)
The contract addresses and gas price limits are different depending on which method you use to get randomness. You can find the configuration, addresses, and limits for each method on the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
To learn when VRF v2.5 becomes available on more networks, follow us on [Twitter](https://twitter.com/chainlink) or sign up for our [mailing list](https://docs.chain.link/resources/developer-communications?parent=vrf).
## What's next
- [\> Subscription Method](https://docs.chain.link/vrf/v2-5/overview/subscription)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Security
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Security Considerations \[v1\]](https://docs.chain.link/vrf/v1/security\#overview)
Gaining access to high quality randomness onchain requires a solution like Chainlink's VRF, but it also requires you to understand some of the ways that randomness generation can be manipulated by miners/validators. Here are some of the top security considerations you should review in your project.
- [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v1/security#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
- [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v1/security#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
- [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v1/security#do-not-allow-re-requesting-or-cancellation-of-randomness)
- [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v1/security#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
- [`fulfillRandomness` must not revert](https://docs.chain.link/vrf/v1/security#fulfillrandomness-must-not-revert)
- [Use `VRFConsumerBase` in your contract, to interact with the VRF service](https://docs.chain.link/vrf/v1/security#use-vrfconsumerbase-in-your-contract-to-interact-with-the-vrf-service)
## [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v1/security\#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
If your contract could have multiple VRF requests in flight simultaneously, you must ensure that the order in which the VRF fulfillments arrive cannot be used to manipulate your contract's user-significant behavior.
Blockchain miners/validators can control the order in which your requests appear onchain, and hence the order in which your contract responds to them.
For example, if you made randomness requests `A`, `B`, `C` in short succession, there is no guarantee that the associated randomness fulfillments will also be in order `A`, `B`, `C`. The randomness fulfillments might just as well arrive at your contract in order `C`, `A`, `B` or any other order.
We recommend using the `requestID` to match randomness requests with their corresponding fulfillments.
## [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v1/security\#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
In principle, miners and validators of your underlying blockchain could rewrite the chain's history to put a randomness request from your contract into a different block, which would result in a different VRF output. Note that this does not enable a miner to determine the random value in advance. It only enables them to get a fresh random value that may or not be to their advantage. By way of analogy, they can only re-roll the dice, not predetermine or predict which side it will land on.
You must choose an appropriate confirmation time for the randomness requests you make (i.e. how many blocks the VRF service waits before writing a fulfillment to the chain) to make such rewrite attacks unprofitable in the context of your application and its value-at-risk.
On proof-of-stake blockchains (e.g. BSC, Polygon), what block confirmation time is considered secure depends on the specifics of their consensus mechanism and whether you're willing to trust any underlying assumptions of (partial) honesty of validators.
For further details, take a look at the consensus documentation for the chain you want to use:
- [Ethereum Consensus Mechanisms](https://ethereum.org/en/developers/docs/consensus-mechanisms/)
- [BNB Chain Consensus Docs](https://docs.binance.org/smart-chain/guides/concepts/consensus.html)
- [Polygon Consensus Docs](https://docs.polygon.technology/pos/architecture/bor/?h=consensus)
Understanding the blockchains you build your application on is very important. You should take time to understand [chain reorganization](https://blog.ethereum.org/2015/08/08/chain-reorganisation-depth-expectations/) which will also result in a different VRF output, which could be exploited.
## [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v1/security\#do-not-allow-re-requesting-or-cancellation-of-randomness)
Any re-request or cancellation of randomness is an incorrect use of VRF. dApps that implement the ability to cancel or re-request randomness for specific commitments must consider the additional attack vectors created by this capability. For example, you must prevent the ability for any party to discard unfavorable randomness.
## [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v1/security\#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
Consider the example of a contract that mints a random NFT in response to a users' actions.
The contract should:
1. record whatever actions of the user may affect the generated NFT
2. **stop accepting further user actions that may affect the generated NFT** and issue a randomness request
3. on randomness fulfillment, mint the NFT
Generally speaking, whenever an outcome in your contract depends on some user-supplied inputs and randomness, the contract should not accept any additional user-supplied inputs once the randomness request has been issued.
Otherwise, the cryptoeconomic security properties may be violated by an attacker that can rewrite the chain.
## [`fulfillRandomness` must not revert](https://docs.chain.link/vrf/v1/security\#fulfillrandomness-must-not-revert)
If your fulfillRandomness implementation reverts, the VRF service will not attempt to call it a second time. Make sure your contract logic does not revert. Consider simply storing the randomness and taking more complex follow-on actions in separate contract calls made by you or your users.
## [Use `VRFConsumerBase` in your contract, to interact with the VRF service](https://docs.chain.link/vrf/v1/security\#use-vrfconsumerbase-in-your-contract-to-interact-with-the-vrf-service)
`VRFConsumerBase` tracks important state which needs to be synchronized with the `VRFCoordinator` state. Some users fold `VRFConsumerBase` into their own contracts, but this means taking on significant extra complexity, so we advise against doing so.
Along the same lines, don't override `rawFulfillRandomness`.
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF v2 Subscription
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Subscription Method](https://docs.chain.link/vrf/v2/subscription\#overview)
This section explains how to generate random numbers using the subscription method.
Play
## [Subscriptions](https://docs.chain.link/vrf/v2/subscription\#subscriptions)
VRF v2 requests receive funding from subscription accounts. The [Subscription Manager](https://docs.chain.link/vrf/v2/subscription/ui) lets you create an account and pre-pay for VRF v2, so you don't provide funding each time your application requests randomness. This reduces the total gas cost to use VRF v2. It also provides a simple way to fund your use of Chainlink products from a single location, so you don't have to manage multiple wallets across several different systems and applications.
Subscriptions have the following core concepts:
- **Subscription id:** 64-bit unsigned integer representing the unique identifier of the subscription.
- **Subscription accounts:** An account that holds LINK tokens and makes them available to fund requests to Chainlink VRF v2 coordinators.
- **Subscription owner:** The wallet address that creates and manages a subscription account. Any account can add LINK to the subscription balance, but only the owner can add approved consuming contracts or withdraw funds.
- **Consumers:** Consuming contracts that are approved to use funding from your subscription account.
- **Subscription balance:** The amount of LINK maintained on your subscription account. Requests from consuming contracts will continue to be funded until the balance runs out, so be sure to maintain sufficient funds in your subscription balance to pay for the requests and keep your applications running.
For Chainlink VRF v2 to fulfill your requests, you must maintain a sufficient amount of LINK in your subscription balance. Gas cost calculation includes the following variables:
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
- **Verification gas:** The amount of gas used to verify randomness onchain.
The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
## [Request and receive data](https://docs.chain.link/vrf/v2/subscription\#request-and-receive-data)
Requests to Chainlink VRF v2 follow the request and receive data cycle. This end-to-end diagram shows each step in the lifecycle of a VRF subscription request, and registering a smart contract with a VRF subscription account:

Two types of accounts exist in the Ethereum ecosystem, and both are used in VRF:
- EOA (Externally Owned Account): An externally owned account that has a private key and can control a smart contract. Transactions can only be initiated by EOAs.
- Smart contract: A contract that does not have a private key and executes what it has been designed for as a decentralized application.
The Chainlink VRF v2 solution uses both offchain and onchain components:
- [VRF v2 Coordinator (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
- VRF service (offchain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
### [Set up your contract and request](https://docs.chain.link/vrf/v2/subscription\#set-up-your-contract-and-request)
Set up your consuming contract:
1. Your contract must inherit [VRFConsumerBaseV2](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol).
2. Your contract must implement the `fulfillRandomWords` function, which is the _callback VRF function_. Here, you add logic to handle the random values after they are returned to your contract.
3. Submit your VRF request by calling `requestRandomWords` of the [VRF Coordinator](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol). Include the following parameters in your request:
- `keyHash`: Identifier that maps to a job and a private key on the VRF service and that represents a specified gas lane. If your request is urgent, specify a gas lane with a higher gas price limit. The configuration for your network can be found [here](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations).
- `s_subscriptionId`: The subscription ID that the consuming contract is registered to. LINK funds are deducted from this subscription.
- `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations).
- `callbackGasLimit`: The maximum amount of gas a user is willing to pay for completing the callback VRF function. Note that you cannot put a value larger than maxGasLimit of the VRF Coordinator contract (read [coordinator contract limits](https://docs.chain.link/vrf/v2/subscription#limits) for more details).
- `numWords`: The number of random numbers to request. The maximum random values that can be requested for your network can be found [here](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations).
### [How VRF processes your request](https://docs.chain.link/vrf/v2/subscription\#how-vrf-processes-your-request)
After you submit your request, it is processed using the [Request & Receive Data](https://docs.chain.link/vrf/v2/subscription#request-and-receive-data) cycle. The VRF coordinator processes the request and determines the final charge to your subscription using the following steps:
1. The VRF coordinator emits an event.
2. The VRF service picks up the event and waits for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof ( `requestConfirmations`).
3. The VRF coordinator verifies the proof onchain, then it calls back the consuming contract `fulfillRandomWords` function.
## [Limits](https://docs.chain.link/vrf/v2/subscription\#limits)
Chainlink VRF v2 has some [subscription limits](https://docs.chain.link/vrf/v2/subscription#subscription-limits) and [coordinator contract limits](https://docs.chain.link/vrf/v2/subscription#coordinator-contract-limits).
### [Subscription limits](https://docs.chain.link/vrf/v2/subscription\#subscription-limits)
Subscriptions are required to maintain a minimum balance, and they can support a limited number of consuming contracts.
#### [Minimum subscription balance](https://docs.chain.link/vrf/v2/subscription\#minimum-subscription-balance)
Each subscription must maintain a minimum balance to fund requests from consuming contracts. This minimum balance requirement serves as a buffer against gas volatility by ensuring that all your requests have more than enough funding to go through. If your balance is below the minimum, your requests remain pending for up to 24 hours before they expire. After you add sufficient LINK to a subscription, pending requests automatically process as long as they have not expired.
In the Subscription Manager, the minimum subscription balance is displayed as the **Max Cost**, and it indicates the amount of LINK you need to add for a pending request to process. After the request is processed, only the amount actually consumed by the request is deducted from your balance. For example, if your minimum balance is 10 LINK, but your subscription balance is 5 LINK, you need to add at least 5 more LINK for your request to process. This does not mean that your request will ultimately cost 10 LINK. If the request ultimately costs 3 LINK after it has processed, then 3 LINK is deducted from your subscription balance.
The minimum subscription balance must be sufficient for each new consuming contract that you add to a subscription. For example, the minimum balance for a subscription that supports 20 consuming contracts needs to cover all the requests for all 20 contracts, while a subscription with one consuming contract only needs to cover that one contract.
For one request, the required size of the minimum balance depends on the gas lane and the size of the request. For example, a consuming contract that requests one random value will require a smaller minimum balance than a consuming contract that requests 50 random values. In general, you can estimate the required minimum LINK balance using the following formula where max verification gas is always 200,000 gwei.

```plaintext
(((Gas lane maximum * (Max verification gas + Callback gas limit)) / (1,000,000,000 Gwei/ETH)) / (ETH/LINK price)) + LINK premium = Minimum LINK
```
Here is the same formula, broken out into steps:

```plaintext
Gas lane maximum * (Max verification gas + Callback gas limit) = Total estimated gas (Gwei)
Total estimated gas (Gwei) / 1,000,000,000 Gwei/ETH = Total estimated gas (ETH)
Total estimated gas (ETH) / (ETH/LINK price) = Total estimated gas (LINK)
Total estimated gas (LINK) + LINK premium = Minimum subscription balance (LINK)
```
#### [Maximum consuming contracts](https://docs.chain.link/vrf/v2/subscription\#maximum-consuming-contracts)
Each subscription supports up to 100 consuming contracts. If you need more than 100 consuming contracts, create multiple subscriptions.
### [Coordinator contract limits](https://docs.chain.link/vrf/v2/subscription\#coordinator-contract-limits)
You can see the configuration for each network on the [Supported networks](https://docs.chain.link/vrf/v2/subscription/supported-networks) page. You can also view the full configuration for each coordinator contract directly in Etherscan. As an example, view the [Ethereum Mainnet VRF v2 coordinator contract](https://etherscan.io/token/0x271682DEB8C4E0901D1a1550aD2e64D568E69909#readContract) configuration.
- Each coordinator has a `MAX_NUM_WORDS` parameter that limits the maximum number of random values you can receive in each request.
- Each coordinator has a `maxGasLimit` parameter, which is the maximum allowed `callbackGasLimit` value for your requests. You must specify a sufficient `callbackGasLimit` to fund the callback request to your consuming contract. This depends on the number of random values you request and how you process them in your `fulfillRandomWords()` function. If your `callbackGasLimit` is not sufficient, the callback fails but your subscription is still charged for the work done to generate your requested random values.
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Security
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Security Considerations](https://docs.chain.link/vrf/v2/security\#overview)
Gaining access to high quality randomness onchain requires a solution like Chainlink's VRF, but it also requires you to understand some of the ways that miners or validators can potentially manipulate randomness generation. Here are some of the top security considerations you should review in your project.
- [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v2/security#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
- [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v2/security#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
- [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v2/security#do-not-allow-re-requesting-or-cancellation-of-randomness)
- [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v2/security#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
- [The `fulfillRandomWords` function must not revert](https://docs.chain.link/vrf/v2/security#fulfillrandomwords-must-not-revert)
- [Use `VRFConsumerBaseV2` in your contract to interact with the VRF service](https://docs.chain.link/vrf/v2/security#use-vrfconsumerbasev2-in-your-contract-to-interact-with-the-vrf-service)
## [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v2/security\#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
If your contract could have multiple VRF requests in flight simultaneously, you must ensure that the order in which the VRF fulfillments arrive cannot be used to manipulate your contract's user-significant behavior.
Blockchain miners/validators can control the order in which your requests appear onchain, and hence the order in which your contract responds to them.
For example, if you made randomness requests `A`, `B`, `C` in short succession, there is no guarantee that the associated randomness fulfillments will also be in order `A`, `B`, `C`. The randomness fulfillments might just as well arrive at your contract in order `C`, `A`, `B` or any other order.
We recommend using the `requestID` to match randomness requests with their corresponding fulfillments.
## [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v2/security\#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
In principle, miners/validators of your underlying blockchain could rewrite the chain's history to put a randomness request from your contract into a different block, which would result in a different VRF output. Note that this does not enable a miner to determine the random value in advance. It only enables them to get a fresh random value that might or might not be to their advantage. By way of analogy, they can only re-roll the dice, not predetermine or predict which side it will land on.
You must choose an appropriate confirmation time for the randomness requests you make. Confirmation time is how many blocks the VRF service waits before writing a fulfillment to the chain to make potential rewrite attacks unprofitable in the context of your application and its value-at-risk.
## [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v2/security\#do-not-allow-re-requesting-or-cancellation-of-randomness)
Any re-request or cancellation of randomness is an incorrect use of VRFv2. dApps that implement the ability to cancel or re-request randomness for specific commitments must consider the additional attack vectors created by this capability. For example, you must prevent the ability for any party to discard unfavorable randomness.
## [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v2/security\#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
Consider the example of a contract that mints a random NFT in response to a user's actions.
The contract should:
1. Record whatever actions of the user may affect the generated NFT.
2. **Stop accepting further user actions that might affect the generated NFT** and issue a randomness request.
3. On randomness fulfillment, mint the NFT.
Generally speaking, whenever an outcome in your contract depends on some user-supplied inputs and randomness, the contract should not accept any additional user-supplied inputs after it submits the randomness request.
Otherwise, the cryptoeconomic security properties may be violated by an attacker that can rewrite the chain.
## [`fulfillRandomWords` must not revert](https://docs.chain.link/vrf/v2/security\#fulfillrandomwords-must-not-revert)
If your `fulfillRandomWords()` implementation reverts, the VRF service will not attempt to call it a second time. Make sure your contract logic does not revert. Consider simply storing the randomness and taking more complex follow-on actions in separate contract calls made by you, your users, or an [Automation Node](https://docs.chain.link/chainlink-automation).
## [Use `VRFConsumerBaseV2` in your contract, to interact with the VRF service](https://docs.chain.link/vrf/v2/security\#use-vrfconsumerbasev2-in-your-contract-to-interact-with-the-vrf-service)
If you implement the [subscription method](https://docs.chain.link/vrf/v2/subscription), use `VRFConsumerBaseV2`. It includes a check to ensure the randomness is fulfilled by `VRFCoordinatorV2`. For this reason, it is a best practice to inherit from `VRFConsumerBaseV2`. Similarly, don't override `rawFulfillRandomness`.
## [Use `VRFv2WrapperConsumer.sol` in your contract, to interact with the VRF service](https://docs.chain.link/vrf/v2/security\#use-vrfv2wrapperconsumersol-in-your-contract-to-interact-with-the-vrf-service)
If you implement the [direct funding method](https://docs.chain.link/vrf/v2/direct-funding), use `VRFv2WrapperConsumer`. It includes a check to ensure the randomness is fulfilled by the `VRFV2Wrapper`. For this reason, it is a best practice to inherit from `VRFv2WrapperConsumer`. Similarly, don't override `rawFulfillRandomWords`.
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Overview
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Introduction to Chainlink VRF \[v1\]](https://docs.chain.link/vrf/v1/introduction\#overview)
## [Generate Random Numbers in your Smart Contracts](https://docs.chain.link/vrf/v1/introduction\#generate-random-numbers-in-your-smart-contracts)
Chainlink VRF (Verifiable Random Function) is a provably-fair and verifiable source of randomness designed for smart contracts. Smart contract developers can use Chainlink VRF as a tamper-proof random number generator (RNG) to build reliable smart contracts for any applications which rely on unpredictable outcomes:
- Blockchain games and NFTs
- Random assignment of duties and resources (e.g. randomly assigning judges to cases)
- Choosing a representative sample for consensus mechanisms
Learn how to write smart contracts that consume random numbers: [Get a Random Number](https://docs.chain.link/vrf/v1/examples/get-a-random-number).
## [onchain Verification of Randomness](https://docs.chain.link/vrf/v1/introduction\#onchain-verification-of-randomness)
Chainlink VRF enables smart contracts to access randomness without compromising on security or usability. With every new request for randomness, Chainlink VRF generates a random number and cryptographic proof of how that number was determined. The proof is published and verified onchain before it can be used by any consuming applications. This process ensures that the results cannot be tampered with nor manipulated by anyone, including oracle operators, miners, users and even smart contract developers.
Read more about Chainlink VRF in [our announcement post](https://blog.chain.link/verifiable-random-functions-vrf-random-number-generation-rng-feature/).
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v1/examples/get-a-random-number)
- [\> API Reference](https://docs.chain.link/vrf/v1/api-reference)
- [\> Supported Networks](https://docs.chain.link/vrf/v1/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Release Notes
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Chainlink VRF Release Notes](https://docs.chain.link/vrf/release-notes\#overview)
## [2025-05-07 - VRF 2.5 on Ronin](https://docs.chain.link/vrf/release-notes\#2025-05-07-vrf-2-5-on-ronin)
Chainlink VRF 2.5 is available on Ronin Mainnet and Ronin Saigon Testnet. Visit the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks#ronin) page for more information.
## [2025-04-01 - VRF 2.5 on Soneium Mainnet](https://docs.chain.link/vrf/release-notes\#2025-04-01-vrf-2-5-on-soneium-mainnet)
Chainlink VRF 2.5 is available on Soneium Mainnet. Visit the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks#soneium-mainnet) page for more information.
## [2024-11-26 - VRF 2.5 on Optimism mainnet](https://docs.chain.link/vrf/release-notes\#2024-11-26-vrf-2-5-on-optimism-mainnet)
Chainlink VRF 2.5 is available on Optimism mainnet. Visit the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks#op-mainnet) page for more information.
## [2024-10-22 - VRF 2.5 on Soneium Minato](https://docs.chain.link/vrf/release-notes\#2024-10-22-vrf-2-5-on-soneium-minato)
Chainlink VRF 2.5 is available on Soneium Minato testnet. Visit the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks#soneium-minato-testnet) page for more information.
## [2024-08-15 - VRF V2.5 on BASE](https://docs.chain.link/vrf/release-notes\#2024-08-15-vrf-v2-5-on-base)
VRF V2.5 is available on [BASE mainnet](https://docs.chain.link/vrf/v2-5/supported-networks#base-mainnet) and [BASE Sepolia testnet](https://docs.chain.link/vrf/v2-5/supported-networks#base-sepolia-testnet). See the [VRF V2.5 Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page to get configuration details for both subscription and direct funding.
## [2024-07-15 - VRF V2 and V1 Deprecation Announcement](https://docs.chain.link/vrf/release-notes\#2024-07-15-vrf-v2-and-v1-deprecation-announcement)
VRF V2 and V1 will be deprecated on November 29, 2024. Please migrate to VRF V2.5 before then. See the migration guides for instructions:
- [Migrating from VRF v2](https://docs.chain.link/vrf/v2-5/migration-from-v2)
- [Migrating from VRF v1](https://docs.chain.link/vrf/v2-5/migration-from-v1)
## [2024-05-24 - Updated VRF V2.5 contracts](https://docs.chain.link/vrf/release-notes\#2024-05-24-updated-vrf-v2-5-contracts)
The [`@chainlink/contracts`](https://www.npmjs.com/package/@chainlink/contracts/v/1.1.1) package version 1.1.1 is now available. It includes the updated wrapper and interface contracts for VRF 2.5 direct funding, which had not been included in the `@chainlink/contracts` package version 1.1.0. The `DirectFundingConsumer.sol` example contract has been updated to reflect this.
The [`@chainlink/contracts`](https://www.npmjs.com/package/@chainlink/contracts/v/1.1.1) also includes an updated function signature for `fulfillRandomWords` in the `VRFConsumerBaseV2Plus` contract, which applies only to subscription users. This function signature has **not** changed in the `VRFV2PlusWrapperConsumerBase`, so this does not affect direct funding users.
When using package version 1.1.1 and later, update your `fulfillRandomWords` function signature to match the `VRFConsumerBaseV2Plus` contract, which has changed to: `function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)`
In the `@chainlink/contracts` package version 1.1.0 and earlier, the `randomWords` parameter has a `memory` storage location.
## [2024-04-29 - VRF v2.5](https://docs.chain.link/vrf/release-notes\#2024-04-29-vrf-v2-5)
VRF V2.5 is available on Ethereum, BNB Chain, Polygon, Avalanche and Arbitrum mainnets and testnets.The new version of Chainlink VRF implements the following changes:
- Support for native gas token billing
- Easy 1-click migration to future new versions
- New [billing model](https://docs.chain.link/vrf/v2-5/billing), where the premium is a percentage of the gas costs of the VRF callback instead of a flat fee
- Gas optimizations
Learn how to [migrate to VRF V2.5](https://docs.chain.link/vrf/v2-5/migration-from-v2).
## [2024-04-13 - Polygon testnet support changed](https://docs.chain.link/vrf/release-notes\#2024-04-13-polygon-testnet-support-changed)
The Mumbai network has stopped producing blocks, so example code will not function on this network. Check again soon for updates about future testnet support on Polygon.
## [2024-03-29 - Fantom support changed](https://docs.chain.link/vrf/release-notes\#2024-03-29-fantom-support-changed)
Creating new Fantom subscriptions in the [VRF Subscription Manager](https://vrf.chain.link/) is no longer supported. Existing Fantom subscriptions are still supported.
## [2023-11-17 - Arbitrum testnet support changed](https://docs.chain.link/vrf/release-notes\#2023-11-17-arbitrum-testnet-support-changed)
Arbitrum Goerli support ends as of November 18, 2023. Support for Arbitrum Sepolia is available for both [subscription](https://docs.chain.link/vrf/v2/subscription/supported-networks#arbitrum-sepolia-testnet) and [direct funding](https://docs.chain.link/vrf/v2/direct-funding/supported-networks#arbitrum-sepolia-testnet).
## [2023-10-02 - VRF Quickstarts and Resources](https://docs.chain.link/vrf/release-notes\#2023-10-02-vrf-quickstarts-and-resources)
The [Developer Hub](https://dev.chain.link/) has been released. It helps you find resources related to web3 use cases like NFTs and gaming. The Developer Hub includes a comprehensive [VRF Resources](https://dev.chain.link/products/vrf) page that shows a collection of Quickstarts, guides, tutorials, videos, blog posts, courses, documentation, and case studies related to VRF. A new set of Quickstarts has been released. See [all the Quickstarts that involve VRF](https://dev.chain.link/resources/quickstarts?product=VRF).
## [2023-10-02 - Sepolia gas lane increase](https://docs.chain.link/vrf/release-notes\#2023-10-02-sepolia-gas-lane-increase)
For VRF V2 subscription, the [Sepolia gas lane](https://docs.chain.link/vrf/v2/subscription/supported-networks#sepolia-testnet) has increased from 30 gwei to 150 gwei. The key hash has otherwise remained the same.
## [2023-07-26 - VRF Cost Calculator](https://docs.chain.link/vrf/release-notes\#2023-07-26-vrf-cost-calculator)
A VRF cost calculator has been added to the [Estimating Costs](https://docs.chain.link/vrf/v2/estimating-costs) page. Use this calculator to estimate costs for both subscription and direct funding.
## [2023-06-14 - Arbitrum support and docs expanded](https://docs.chain.link/vrf/release-notes\#2023-06-14-arbitrum-support-and-docs-expanded)
Arbitrum mainnet and Arbitrum Goerli are supported on VRF V2 direct funding. Detailed cost explanations for Arbitrum and a cost estimation code example are available on the [Estimating Costs](https://docs.chain.link/vrf/v2/estimating-costs) page.
## [2023-05-19 - VRF support added for Arbitrum](https://docs.chain.link/vrf/release-notes\#2023-05-19-vrf-support-added-for-arbitrum)
Arbitrum mainnet and Arbitrum Goerli are supported on VRF V2 subscription.
## [2023-04-20 - Supported network removed](https://docs.chain.link/vrf/release-notes\#2023-04-20-supported-network-removed)
Klaytn and Klaytn Baobob are no longer supported networks on VRF.
See the currently supported networks for [subscription](https://docs.chain.link/vrf/v2/subscription/supported-networks) and [direct funding](https://docs.chain.link/vrf/v2/direct-funding/supported-networks).
## [2023-04-19 - VRF Subscription Manager updated](https://docs.chain.link/vrf/release-notes\#2023-04-19-vrf-subscription-manager-updated)
The [VRF Subscription Manager](https://vrf.chain.link/) has a new [Actions menu](https://docs.chain.link/vrf/v2/subscription/ui#actions-menu) that displays actions you can take on a VRF subscription, including funding, cancellation, and adding an email address.
## [2023-04-12 - VRF Estimating costs page added](https://docs.chain.link/vrf/release-notes\#2023-04-12-vrf-estimating-costs-page-added)
Billing and cost information for VRF V2 subscription and direct funding has been consolidated into one [Estimating Costs](https://docs.chain.link/vrf/v2/estimating-costs) page. Static cost breakdown examples are available for both funding methods.
## [2023-04-05 - VRF V2 mock contracts added](https://docs.chain.link/vrf/release-notes\#2023-04-05-vrf-v2-mock-contracts-added)
Mock contracts for local testing are available for VRF V2 subscription and direct funding:
- [Test VRF V2 subscription locally](https://docs.chain.link/vrf/v2/subscription/examples/test-locally)
- [Test VRF V2 direct funding locally](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally)
## [2022-02-16 - VRF V2 is Generally Available](https://docs.chain.link/vrf/release-notes\#2022-02-16-vrf-v2-is-generally-available)
VRF V2 is Generally Available with new sample contracts for V2.
## [2021-12-14 - VRF V2 launched](https://docs.chain.link/vrf/release-notes\#2021-12-14-vrf-v2-launched)
VRF V2 is available along with guides to help you migrate from V1 to V2:
- [Subscription: Migrating from V1 to V2](https://docs.chain.link/vrf/v2/subscription/migration-from-v1)
- [Direct funding: Migrating from V1 to V2](https://docs.chain.link/vrf/v2/direct-funding/migration-from-v1)
## [2020-10-22 - VRF V1 is available](https://docs.chain.link/vrf/release-notes\#2020-10-22-vrf-v1-is-available)
VRF V1 is [available on Ethereum mainnet](https://blog.chain.link/chainlink-vrf-now-live-on-ethereum-mainnet/).
## What's next
- [\> Migrate to VRF V2.5](https://docs.chain.link/vrf/v2-5/migration-from-v2)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Guide
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Getting Started with Chainlink VRF](https://docs.chain.link/vrf/v2/getting-started\#overview)
Play
VRF v2 - Developer Walkthrough
In this guide, you will learn about generating randomness on blockchains. This includes learning how to implement a Request and Receive cycle with Chainlink oracles and how to consume random numbers with Chainlink VRF in smart contracts.
## [How is randomness generated on blockchains? What is Chainlink VRF?](https://docs.chain.link/vrf/v2/getting-started\#how-is-randomness-generated-on-blockchains-what-is-chainlink-vrf)
Randomness is very difficult to generate on blockchains. This is because every node on the blockchain must come to the same conclusion and form a consensus. Even though random numbers are versatile and useful in a variety of blockchain applications, they cannot be generated natively in smart contracts. The solution to this issue is [**Chainlink VRF**](https://docs.chain.link/vrf), also known as Chainlink Verifiable Random Function.
## [What is the Request and Receive cycle?](https://docs.chain.link/vrf/v2/getting-started\#what-is-the-request-and-receive-cycle)
The [Data Feeds Getting Started](https://docs.chain.link/data-feeds/getting-started) guide explains how to consume Chainlink Data Feeds, which consist of reference data posted onchain by oracles. This data is stored in a contract and can be referenced by consumers until the oracle updates the data again.
Randomness, on the other hand, cannot be reference data. If the result of randomness is stored onchain, any actor could retrieve the value and predict the outcome. Instead, randomness must be requested from an oracle, which generates a number and a cryptographic proof. Then, the oracle returns that result to the contract that requested it. This sequence is known as the **[Request and Receive cycle](https://docs.chain.link/architecture-overview/architecture-request-model)**.
## [What is the payment process for generating a random number?](https://docs.chain.link/vrf/v2/getting-started\#what-is-the-payment-process-for-generating-a-random-number)
VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link/) lets you create an account and pre-pay for VRF requests, so that funding of all your application requests are managed in a single location.
To learn more about VRF requests funding, see [Subscriptions limits](https://docs.chain.link/vrf/v2/subscription#subscription-limits).
## [How can I use Chainlink VRF?](https://docs.chain.link/vrf/v2/getting-started\#how-can-i-use-chainlink-vrf)
To see a basic implementation of Chainlink VRF, see [Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number). In this section, you will create an application that uses Chainlink VRF to generate randomness. The contract used in this application has a [_Game of Thrones_](https://en.wikipedia.org/wiki/Game_of_Thrones) theme.
After the contract requests randomness from Chainlink VRF, the result of the randomness will transform into a number between 1 and 20, mimicking the rolling of a 20 sided die. Each number represents a _Game of Thrones_ house. If the dice land on the value 1, the user is assigned house Targaryan, 2 for Lannister, and so on. A full list of houses can be found [here](https://gameofthrones.fandom.com/wiki/Great_House).
When rolling the dice, it uses an `address` variable to track which address is assigned to each house.
The contract has the following functions:
- `rollDice`: This submits a randomness request to Chainlink VRF
- `fulfillRandomWords`: The function that the Oracle uses to send the result back
- `house`: To see the assigned house of an address
**Note**: to jump straight to the entire implementation, you can [open the VRFD20.sol contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFD20.sol) in remix.
### [Create and fund a subscription](https://docs.chain.link/vrf/v2/getting-started\#create-and-fund-a-subscription)
Chainlink VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link/) lets you create an account and pre-pay your use of Chainlink VRF requests.
For this example, create a new subscription on the Sepolia testnet as explained [here](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number/#create-and-fund-a-subscription).
### [Importing `VRFConsumerBaseV2` and `VRFCoordinatorV2Interface`](https://docs.chain.link/vrf/v2/getting-started\#importing-vrfconsumerbasev2-and-vrfcoordinatorv2interface)
Chainlink maintains a [library of contracts](https://github.com/smartcontractkit/chainlink/tree/contracts-v1.3.0/contracts) that make consuming data from oracles easier. For Chainlink VRF, you will use:
- [`VRFConsumerBaseV2`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol) that must be imported and extended from the contract that you create.
- [`VRFCoordinatorV2Interface`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol) that must be imported to communicate with the VRF coordinator.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
}
```
### [Contract variables](https://docs.chain.link/vrf/v2/getting-started\#contract-variables)
This example is adapted for [Sepolia testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks/#sepolia-testnet) but you can change the configuration and make it run for any [supported network](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations).

```solidity
uint64 s_subscriptionId;
address s_owner;
VRFCoordinatorV2Interface COORDINATOR;
address vrfCoordinator = 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625;
bytes32 s_keyHash = 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
uint32 callbackGasLimit = 40000;
uint16 requestConfirmations = 3;
uint32 numWords = 1;
```
- `uint64 s_subscriptionId`: The subscription ID that this contract uses for funding requests. Initialized in the `constructor`.
- `address s_owner`: The address of the owner of the contract that you will deploy. This is initialized in the `constructor`, and it will be the address you use when deploying the contract.
- `VRFCoordinatorV2Interface COORDINATOR`: The address of the Chainlink VRF Coordinator contract that this contract will use. Initialized in the `constructor`.
- `address vrfCoordinator`: The address of the Chainlink VRF Coordinator contract.
- `bytes32 s_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 offchain 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` on the coordinator contract. 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. In this example, each transaction requests one random value.
To keep track of addresses that roll the dice, the contract uses mappings. [Mappings](https://medium.com/upstate-interactive/mappings-in-solidity-explained-in-under-two-minutes-ecba88aff96e) are unique key-value pair data structures similar to hash tables in Java.

```solidity
mapping(uint256 => address) private s_rollers;
mapping(address => uint256) private s_results;
```
- `s_rollers` stores a mapping between the `requestID` (returned when a request is made), and the address of the roller. This is so the contract can keep track of who to assign the result to when it comes back.
- `s_results` stores the roller and the result of the dice roll.
### [Initializing the contract](https://docs.chain.link/vrf/v2/getting-started\#initializing-the-contract)
The coordinator and subscription id must be initialized in the `constructor` of the contract. To use `VRFConsumerBaseV2` properly, you must also pass the VRF coordinator address into its constructor.
The address that creates the smart contract is the owner of the contract. the modifier `onlyOwner()` checks that only the owner is allowed to do some tasks.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
// variables
// ...
// constructor
constructor(uint64 subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
s_owner = msg.sender;
s_subscriptionId = subscriptionId;
}
//...
modifier onlyOwner() {
require(msg.sender == s_owner);
_;
}
}
```
### [`rollDice` function](https://docs.chain.link/vrf/v2/getting-started\#rolldice-function)
The `rollDice` function will complete the following tasks:
1. Check if the roller has already rolled since each roller can only ever be assigned to a single house.
2. Request randomness by calling the VRF coordinator.
3. Store the `requestId` and roller address.
4. Emit an event to signal that the dice is rolling.
You must add a `ROLL_IN_PROGRESS` constant to signify that the dice has been rolled but the result is not yet returned. Also add a `DiceRolled` event to the contract.
Only the owner of the contract can execute the `rollDice` function.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
// variables
uint256 private constant ROLL_IN_PROGRESS = 42;
// ...
// events
event DiceRolled(uint256 indexed requestId, address indexed roller);
// ...
// ...
// { constructor }
// ...
// rollDice function
function rollDice(address roller) public onlyOwner returns (uint256 requestId) {
require(s_results[roller] == 0, "Already rolled");
// Will revert if subscription is not set and funded.
requestId = COORDINATOR.requestRandomWords(
s_keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
s_rollers[requestId] = roller;
s_results[roller] = ROLL_IN_PROGRESS;
emit DiceRolled(requestId, roller);
}
}
```
### [`fulfillRandomWords` function](https://docs.chain.link/vrf/v2/getting-started\#fulfillrandomwords-function)
`fulfillRandomWords` is a special function defined within the `VRFConsumerBaseV2` contract that our contract extends from. The coordinator sends the result of our generated `randomWords` back to `fulfillRandomWords`. You will implement some functionality here to deal with the result:
1. Change the result to a number between 1 and 20 inclusively. Note that `randomWords` is an array that could contain several random values. In this example, request 1 random value.
2. Assign the transformed value to the address in the `s_results` mapping variable.
3. Emit a `DiceLanded` event.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
// ...
// { variables }
// ...
// events
// ...
event DiceLanded(uint256 indexed requestId, uint256 indexed result);
// ...
// { constructor }
// ...
// ...
// { rollDice function }
// ...
// fulfillRandomWords function
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
// transform the result to a number between 1 and 20 inclusively
uint256 d20Value = (randomWords[0] % 20) + 1;
// assign the transformed value to the address in the s_results mapping variable
s_results[s_rollers[requestId]] = d20Value;
// emitting event to signal that dice landed
emit DiceLanded(requestId, d20Value);
}
}
```
### [`house` function](https://docs.chain.link/vrf/v2/getting-started\#house-function)
Finally, the `house` function returns the house of an address.
To have a list of the house's names, create the `getHouseName` function that is called in the `house` function.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
contract VRFD20 is VRFConsumerBaseV2 {
// ...
// { variables }
// ...
// ...
// { events }
// ...
// ...
// { constructor }
// ...
// ...
// { rollDice function }
// ...
// ...
// { fulfillRandomWords function }
// ...
// house function
function house(address player) public view returns (string memory) {
// dice has not yet been rolled to this address
require(s_results[player] != 0, "Dice not rolled");
// not waiting for the result of a thrown dice
require(s_results[player] != ROLL_IN_PROGRESS, "Roll in progress");
// returns the house name from the name list function
return getHouseName(s_results[player]);
}
// getHouseName function
function getHouseName(uint256 id) private pure returns (string memory) {
// array storing the list of house's names
string[20] memory houseNames = [\
"Targaryen",\
"Lannister",\
"Stark",\
"Tyrell",\
"Baratheon",\
"Martell",\
"Tully",\
"Bolton",\
"Greyjoy",\
"Arryn",\
"Frey",\
"Mormont",\
"Tarley",\
"Dayne",\
"Umber",\
"Valeryon",\
"Manderly",\
"Clegane",\
"Glover",\
"Karstark"\
];
// returns the house name given an index
return houseNames[id - 1];
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFD20.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
You have now completed all necessary functions to generate randomness and assign the user a _Game of Thrones_ house. We've added a few helper functions in there to make using the contract easier and more flexible. You can deploy and interact with the complete contract in Remix.
## [How do I deploy to testnet?](https://docs.chain.link/vrf/v2/getting-started\#how-do-i-deploy-to-testnet)
You will deploy this contract on the Sepolia test network. You must have some Sepolia testnet ETH in your MetaMask account to pay for the gas. Testnet ETH is also available from several [public faucets](https://faucetlink.to/sepolia).
This deployment is slightly different than the example in the [Deploy Your First Contract](https://docs.chain.link/quickstarts/deploy-your-first-contract) guide. In this case, you pass in parameters to the constructor upon deployment.
Once compiled, you'll see a dropdown menu that looks like this in the deploy pane:

Select the `VRFD20` contract or the name that you gave to your contract.
Click the caret arrow on the right hand side of **Deploy** to expand the parameter fields, and paste your subscription ID.

Then click the `Deploy` button and use your MetaMask account to confirm the transaction.
At this point, your contract should be successfully deployed. However, it can't request anything because it is not yet approved to use the LINK balance in your subscription. If you click `rollDice`, the transaction will revert.
## [How do I add my contract to my subscription account?](https://docs.chain.link/vrf/v2/getting-started\#how-do-i-add-my-contract-to-my-subscription-account)
After you deploy your contract, you must add it as an approved consumer contract so it can use the subscription balance when requesting for randomness. Go to the [Subscription Manager](https://vrf.chain.link/) and add your deployed contract address to the list of consumers. Find your contract address in Remix under **Deployed Contracts** on the bottom left.

## [How do I test `rollDice`?](https://docs.chain.link/vrf/v2/getting-started\#how-do-i-test-rolldice)
After you open the deployed contract tab in the bottom left, the function buttons are available. Find `rollDice` and click the caret to expand the parameter fields. Enter an Ethereum address to specify a "dice roller", and click 'rollDice'.
It takes a few minutes for the transaction to confirm and the response to be sent back. You can get your house by clicking the `house` function button with the address passed in `rollDice`. After the response is sent back, you'll be assigned a _Game of Thrones_ house!
## [Further Reading](https://docs.chain.link/vrf/v2/getting-started\#further-reading)
To read more about generating random numbers in Solidity, read our blog posts:
- [35+ Blockchain RNG Use Cases Enabled by Chainlink VRF](https://blog.chain.link/blockchain-rng-use-cases-enabled-by-chainlink-vrf/)
- [How to Build Dynamic NFTs on Polygon](https://blog.chain.link/how-to-build-dynamic-nfts-on-polygon/)
- [Chainlink VRF v2 Now Live on Ethereum Mainnet](https://blog.chain.link/vrf-v2-mainnet-launch/)
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number)
- [\> Programmatic Subscription](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription)
- [\> Security Considerations](https://docs.chain.link/vrf/v2/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2/best-practices)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Best Practices
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF V2 Best Practices](https://docs.chain.link/vrf/v2/best-practices\#overview)
These are example best practices for using Chainlink VRF. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Getting a random number within a range](https://docs.chain.link/vrf/v2/best-practices\#getting-a-random-number-within-a-range)
If you need to generate a random number within a given range, use [modulo](https://docs.soliditylang.org/en/v0.8.7/types.html#modulo) to define the limits of your range. Below you can see how to get a random number in a range from 1 to 50.

```solidity
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
// Assuming only one random word was requested.
s_randomRange = (randomWords[0] % 50) + 1;
}
```
## [Getting multiple random values](https://docs.chain.link/vrf/v2/best-practices\#getting-multiple-random-values)
If you want to get multiple random values from a single VRF request, you can request this directly with the `numWords` argument:
- If you are using the VRF v2 subscription method, see the [Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number) guide for an example where one request returns multiple random values.
- If you are using the VRF v2 direct funding method, see the [Get a Random Number](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number) guide for an example where one request returns multiple random values.
## [Processing simultaneous VRF requests](https://docs.chain.link/vrf/v2/best-practices\#processing-simultaneous-vrf-requests)
If you want to have multiple VRF requests processing simultaneously, create a mapping between `requestId` and the response. You might also create a mapping between the `requestId` and the address of the requester to track which address made each request.

```solidity
mapping(uint256 => uint256[]) public s_requestIdToRandomWords;
mapping(uint256 => address) public s_requestIdToAddress;
uint256 public s_requestId;
function requestRandomWords() external onlyOwner returns (uint256) {
uint256 requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
s_requestIdToAddress[requestId] = msg.sender;
// Store the latest requestId for this example.
s_requestId = requestId;
// Return the requestId to the requester.
return requestId;
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
// You can return the value to the requester,
// but this example simply stores it.
s_requestIdToRandomWords[requestId] = randomWords;
}
```
You could also map the `requestId` to an index to keep track of the order in which a request was made.

```solidity
mapping(uint256 => uint256) s_requestIdToRequestIndex;
mapping(uint256 => uint256[]) public s_requestIndexToRandomWords;
uint256 public requestCounter;
function requestRandomWords() external onlyOwner {
uint256 requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
s_requestIdToRequestIndex[requestId] = requestCounter;
requestCounter += 1;
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
uint256 requestNumber = s_requestIdToRequestIndex[requestId];
s_requestIndexToRandomWords[requestNumber] = randomWords;
}
```
## [Processing VRF responses through different execution paths](https://docs.chain.link/vrf/v2/best-practices\#processing-vrf-responses-through-different-execution-paths)
If you want to process VRF responses depending on predetermined conditions, you can create an `enum`. When requesting for randomness, map each `requestId` to an enum. This way, you can handle different execution paths in `fulfillRandomWords`. See the following example:

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
// It shows how to setup multiple execution paths for handling a response.
pragma solidity ^0.8.7;
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/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 VRFv2MultiplePaths is VRFConsumerBaseV2 {
VRFCoordinatorV2Interface COORDINATOR;
// Your subscription ID.
uint64 s_subscriptionId;
// Sepolia coordinator. For other networks,
// see https://docs.chain.link/docs/vrf/v2/supported-networks/#configurations
address vrfCoordinator = 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625;
// 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/v2/supported-networks/#configurations
bytes32 keyHash =
0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 1 random value in one request.
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 numWords = 1;
enum Variable {
A,
B,
C
}
uint256 public variableA;
uint256 public variableB;
uint256 public variableC;
mapping(uint256 => Variable) public requests;
// events
event FulfilledA(uint256 requestId, uint256 value);
event FulfilledB(uint256 requestId, uint256 value);
event FulfilledC(uint256 requestId, uint256 value);
constructor(uint64 subscriptionId) VRFConsumerBaseV2(vrfCoordinator) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
s_subscriptionId = subscriptionId;
}
function updateVariable(uint256 input) public {
uint256 requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
if (input % 2 == 0) {
requests[requestId] = Variable.A;
} else if (input % 3 == 0) {
requests[requestId] = Variable.B;
} else {
requests[requestId] = Variable.C;
}
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
Variable variable = requests[requestId];
if (variable == Variable.A) {
fulfillA(requestId, randomWords[0]);
} else if (variable == Variable.B) {
fulfillB(requestId, randomWords[0]);
} else if (variable == Variable.C) {
fulfillC(requestId, randomWords[0]);
}
}
function fulfillA(uint256 requestId, uint256 randomWord) private {
// execution path A
variableA = randomWord;
emit FulfilledA(requestId, randomWord);
}
function fulfillB(uint256 requestId, uint256 randomWord) private {
// execution path B
variableB = randomWord;
emit FulfilledB(requestId, randomWord);
}
function fulfillC(uint256 requestId, uint256 randomWord) private {
// execution path C
variableC = randomWord;
emit FulfilledC(requestId, randomWord);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2MultiplePaths.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Direct Funding Method
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
On this page
# [Direct Funding Method](https://docs.chain.link/vrf/v2/direct-funding\#overview)
This guide explains how to generate random numbers using the _direct funding_ method. This method doesn't require a subscription and is optimal for one-off requests for randomness. This method also works best for applications where your end-users must pay the fees for VRF because the cost of the request is determined at request time.
## [VRF direct funding](https://docs.chain.link/vrf/v2/direct-funding\#vrf-direct-funding)
Unlike the [subscription method](https://docs.chain.link/vrf/v2/subscription), the direct funding method does not require you to create subscriptions and pre-fund them. Instead, you must directly fund consuming contracts with LINK tokens before they request randomness. Because the consuming contract directly pays the LINK for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Learn [how to estimate costs](https://docs.chain.link/vrf/v2/estimating-costs).
## [Request and receive data](https://docs.chain.link/vrf/v2/direct-funding\#request-and-receive-data)
Requests to Chainlink VRF v2 follow the request and receive data cycle. This end-to-end diagram shows each step in the lifecycle of a VRF direct funding request:

Two types of accounts exist in the Ethereum ecosystem, and both are used in VRF:
- EOA (Externally Owned Account): An externally owned account that has a private key and can control a smart contract. Transactions can be initiated only by EOAs.
- Smart contract: A smart contract that does not have a private key and executes what it has been designed for as a decentralized application.
The Chainlink VRF v2 solution uses both offchain and onchain components:
- [VRF v2 Wrapper (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2Wrapper.sol): A wrapper for the VRF Coordinator that provides an interface for consuming contracts.
- [VRF v2 Coordinator (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
- VRF service (offchain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
### [Set up your contract and request](https://docs.chain.link/vrf/v2/direct-funding\#set-up-your-contract-and-request)
Set up your consuming contract:
1. Your contract must inherit [VRFV2WrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol).
2. Your contract must implement the `fulfillRandomWords` function, which is the _callback VRF function_. Here, you add logic to handle the random values after they are returned to your contract.
3. Submit your VRF request by calling the `requestRandomness` function in the [VRFV2WrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol) contract. Include the following parameters in your request:
- `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations).
- `callbackGasLimit`: The maximum amount of gas to pay for completing the callback VRF function.
- `numWords`: The number of random numbers to request. You can find the maximum number of random values per request for your network in the [Supported networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations) page.
### [How VRF processes your request](https://docs.chain.link/vrf/v2/direct-funding\#how-vrf-processes-your-request)
After you submit your request, it is processed using the [Request & Receive Data](https://docs.chain.link/vrf/v2/direct-funding#request-and-receive-data) cycle:
1. The consuming contract calls the [VRFV2Wrapper](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2Wrapper.sol) `calculateRequestPrice` function to estimate the total transaction cost to fulfill randomness. Learn [how to estimate transaction costs](https://docs.chain.link/vrf/v2/estimating-costs).
2. The consuming contract calls the [LinkToken](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol) `transferAndCall` function to pay the wrapper with the calculated request price. This method sends LINK tokens and executes the [VRFV2Wrapper](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2Wrapper.sol) `onTokenTransfer` logic.
3. The VRFV2Wrapper's `onTokenTransfer` logic triggers the [VRF Coordinator](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol) `requestRandomWords` function to request randomness.
4. The VRF coordinator emits an event.
5. The VRF service picks up the event and waits for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof ( `requestConfirmations`).
6. The VRF coordinator verifies the proof onchain, then it calls back the wrapper contract's `fulfillRandomWords` function.
7. Finally, the VRF Wrapper calls back your consuming contract.
## [Limits](https://docs.chain.link/vrf/v2/direct-funding\#limits)
You can see the configuration for each network on the [Supported networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks) page. You can also view the full configuration for each VRF v2 Wrapper contract directly in Etherscan. As an example, view the [Ethereum Mainnet VRF v2 Wrapper contract](https://etherscan.io/address/0x5A861794B927983406fCE1D062e00b9368d97Df6#readContract) configuration by calling `getConfig` function.
- Each wrapper has a `maxNumWords` parameter that limits the maximum number of random values you can receive in each request.
- The maximum allowed `callbackGasLimit` value for your requests is defined in the [Coordinator contract supported networks](https://docs.chain.link/vrf/v2/subscription/supported-networks) page. Because the VRF v2 Wrapper adds an overhead, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`. Learn more about [estimating costs](https://docs.chain.link/vrf/v2/estimating-costs).
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Best Practices
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Best Practices \[v1\]](https://docs.chain.link/vrf/v1/best-practices\#overview)
Below are the best practices for using Chainlink VRF.
## [Getting a random number within a range](https://docs.chain.link/vrf/v1/best-practices\#getting-a-random-number-within-a-range)
If you need to generate a random number within a given range, you use [modulo](https://docs.soliditylang.org/en/v0.8.17/types.html#modulo) to define the limits of your range. Below you can see how to get a random number between 1 and 50.

```solidity
uint256 public randomResult;
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
randomResult = (randomness % 50) + 1;
}
```
## [Getting multiple random numbers](https://docs.chain.link/vrf/v1/best-practices\#getting-multiple-random-numbers)
If you want to get multiple random numbers from a single VRF response, you should create an array where the `randomValue` is your original returned VRF number and `n` is the desired number of random numbers.

```solidity
function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) {
expandedValues = new uint256[](n);
for (uint256 i = 0; i < n; i++) {
expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i)));
}
return expandedValues;
}
```
## [Having multiple VRF requests in flight](https://docs.chain.link/vrf/v1/best-practices\#having-multiple-vrf-requests-in-flight)
If you want to have multiple VRF requests in flight, you might want to create a mapping between the `requestId` and the address of the requester.

```solidity
mapping(bytes32 => address) public requestIdToAddress;
function getRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
bytes32 requestId = requestRandomness(keyHash, fee);
requestIdToAddress[requestId] = msg.sender;
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
address requestAddress = requestIdToAddress[requestId];
}
```
If you want to keep order when a request was made, you might want to use a mapping of `requestId` to the index/order of this request.

```solidity
mapping(bytes32 => uint256) public requestIdToRequestNumberIndex;
uint256 public requestCounter;
function getRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
bytes32 requestId = requestRandomness(keyHash, fee);
requestIdToRequestNumberIndex[requestId] = requestCounter;
requestCounter += 1;
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
uint256 requestNumber = requestIdToRequestNumberIndex[requestId];
}
```
If you want to keep generated random numbers of several VRF requests, you might want to use a mapping of `requestId` to the returned random number.

```solidity
mapping(bytes32 => uint256) public requestIdToRandomNumber;
function getRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
return requestRandomness(keyHash, fee);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
requestIdToRandomNumber[requestId] = randomness;
}
```
Feel free to use whatever data structure you prefer.
## Get the latest Chainlink content straight to your inbox.
Email Address
[iframe](https://td.doubleclick.net/td/rul/346357746?random=1747983811862&cv=11&fst=1747983811862&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=1>m=45be55l1v891173849z8847174275za200zb847174275&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103116026~103130495~103130497~103200004~103233427~103252644~103252646~103301114~103301116~104481633~104481635&ptag_exp=101509157~103116026~103130498~103130500~103200004~103233427~103252644~103252646~103301114~103301116~104481633~104481635&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fvrf%2Fv1%2Fbest-practices&_ng=1&label=1k9kCM_Z-oYYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=VRF%20Best%20Practices%20%5Bv1%5D%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1488936584.1747983811&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.113%7CGoogle%2520Chrome%3B136.0.7103.113%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&ec_mode=a&fledge=1&capi=1&_tu=Cg&em=tv.1&ct_cookie_present=0)[iframe](https://td.doubleclick.net/td/rul/346357746?random=1747983811887&cv=11&fst=1747983811887&fmt=3&bg=ffffff&guid=ON&async=1&gcl_ctr=2>m=45be55l1v891173849z8847174275za200zb847174275&gcd=13l3l3l3l1l1&dma=0&tag_exp=101509157~103116026~103130495~103130497~103200004~103233427~103252644~103252646~103301114~103301116~104481633~104481635&ptag_exp=101509157~103116026~103130498~103130500~103200004~103233427~103252644~103252646~103301114~103301116~104481633~104481635&u_w=1280&u_h=1024&url=https%3A%2F%2Fdocs.chain.link%2Fvrf%2Fv1%2Fbest-practices&_ng=1&label=_duuCKn_k4cYEPL_k6UB&hn=www.googleadservices.com&frm=0&tiba=VRF%20Best%20Practices%20%5Bv1%5D%20%7C%20Chainlink%20Documentation&value=0&bttype=purchase&npa=0&pscdl=noapi&auid=1488936584.1747983811&uaa=x86&uab=64&uafvl=Chromium%3B136.0.7103.113%7CGoogle%2520Chrome%3B136.0.7103.113%7CNot.A%252FBrand%3B99.0.0.0&uamb=0&uam=&uap=Linux%20x86_64&uapv=6.6.72&uaw=0&ec_mode=a&fledge=1&capi=1&_tu=Cg&em=tv.1&ct_cookie_present=0)
## Chainlink VRF Cost Estimation
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Billing](https://docs.chain.link/vrf/v2/estimating-costs\#overview)
This guide explains how to estimate VRF V2 costs for both the subscription and direct funding methods.
## [VRF v2 cost calculator](https://docs.chain.link/vrf/v2/estimating-costs\#vrf-v2-cost-calculator)
Choose the method you prefer to use the VRF cost calculator:
Subscription
Direct funding

Arbitrum
Avalanche
BNB Chain
Ethereum
Fantom
Polygon
## [Understanding transaction costs](https://docs.chain.link/vrf/v2/estimating-costs\#understanding-transaction-costs)
SubscriptionDirect funding
For Chainlink VRF v2 to fulfill your requests, you must maintain a sufficient amount of LINK in your subscription balance. Gas cost calculation includes the following variables:
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
- **Verification gas:** The amount of gas used to verify randomness onchain.
The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
For Chainlink VRF v2 to fulfill your requests, you must have a sufficient amount of LINK in your consuming contract. Gas cost calculation includes the following variables:
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values. The callback gas depends on your callback function and the number of random values in your request. Set the **callback gas limit** to specify the maximum amount of gas you are willing to spend on the callback request.
- **Verification gas:** The amount of gas used to verify randomness onchain.
- **Wrapper overhead gas:** The amount of gas used by the VRF Wrapper contract. See the [Request and Receive Data](https://docs.chain.link/vrf/v2/direct-funding#request-and-receive-data) section for details about the VRF v2 Wrapper contract design.
Because the consuming contract directly pays the LINK for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.
- If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
- If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
Make sure that your consuming contracts are funded with enough LINK tokens to cover the transaction costs. If the consuming contract doesn't have enough LINK tokens, your request will revert.
### [Estimate gas costs](https://docs.chain.link/vrf/v2/estimating-costs\#estimate-gas-costs)
SubscriptionDirect funding
You need to pre-fund your subscription enough to meet the [minimum subscription balance](https://docs.chain.link/vrf/v2/subscription#minimum-subscription-balance)
in order to have a buffer against gas volatility.
After the request is complete, the final gas cost is recorded based on how much gas is used for the verification and callback.
The actual cost of the request is deducted from your subscription balance.
The total gas cost in wei for your request uses the following formula:

```plaintext
(Gas price * (Verification gas + Callback gas)) = total gas cost
```
The total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is
unavailable, the VRF coordinator uses the `fallbackWeiPerUnitLink` value for the conversion instead. The
`fallbackWeiPerUnitLink` value is defined in the
[coordinator contract](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations) for your selected network.
The final gas cost to fulfill randomness is estimated based on how much gas is expected for the verification and callback. The total gas cost in wei uses the following formula:

```plaintext
(Gas price * (Verification gas
+ Callback gas limit
+ Wrapper gas overhead)) = total gas cost
```
The total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is unavailable, the VRF Wrapper uses the `fallbackWeiPerUnitLink` value for the conversion instead. The `fallbackWeiPerUnitLink` value is defined in the [VRF v2 Wrapper contract](https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations) for your selected network.
The maximum allowed `callbackGasLimit` value for your requests is defined in the [Coordinator contract supported networks](https://docs.chain.link/vrf/v2/subscription/supported-networks) page. Because the VRF v2 Wrapper adds a gas overhead, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`.
### [Add LINK premium](https://docs.chain.link/vrf/v2/estimating-costs\#add-link-premium)
SubscriptionDirect funding
The LINK premium is added to the total gas cost. The premium is defined in the [coordinator contract](https://docs.chain.link/vrf/v2/subscription/supported-networks/#configurations) with the `fulfillmentFlatFeeLinkPPMTier1` parameter in millionths of LINK.

```plaintext
(total gas cost + LINK premium) = total request cost
```
The total request cost is charged to your subscription balance.
A LINK premium is then added to the total gas cost. The premium is divided in two parts:
- Wrapper premium: The premium percentage. You can find the percentage for your network in the [Supported networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations) page.
- Coordinator premium: A flat fee. This premium is defined in the `fulfillmentFlatFeeLinkPPMTier1` parameter in millionths of LINK. You can find the flat fee of the coordinator for your network in the [Supported networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks/#configurations) page.

```plaintext
(Coordinator premium
+ (total gas cost * (1 + Wrapper premium percentage)) = total request cost
```
### [Ethereum example](https://docs.chain.link/vrf/v2/estimating-costs\#ethereum-example)
SubscriptionDirect funding
This is an example calculation of a VRF request on the Ethereum network. The values for other supported networks
are available on the [Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks) page.
#### [Estimate minimum subscription balance](https://docs.chain.link/vrf/v2/estimating-costs\#estimate-minimum-subscription-balance)
You need to have the [minimum subscription balance](https://docs.chain.link/vrf/v2/subscription#minimum-subscription-balance) for your requests
to be processed. This provides a buffer in case gas prices go higher when processing the request. The actual cost of the
request is usually lower than the minimum subscription balance.
| Parameter | Value |
| --- | --- |
| Gas lane | 500 gwei |
| Callback gas limit | 100000 |
| Max verification gas | 200000 |
| LINK premium | 0.25 LINK |
1. Calculate the total gas cost, using the maximum possible gas price for the selected gas lane, the estimated
maximum verification gas, and the full callback gas limit:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 500 gwei x (200000 + 100000) | 150000000 gwei (0.15 ETH) |
2. Convert the gas cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.004 ETH per 1 LINK.
| ETH to LINK cost conversion | Total gas cost (LINK) |
| --- | --- |
| 0.15 ETH / 0.004 ETH/LINK | 37.5 LINK |
3. Add the LINK premium to get the total maximum cost of a request:
| Adding LINK premium | Maximum request cost (LINK) |
| --- | --- |
| Total gas cost (LINK) + LINK premium | |
| 37.5 LINK + 0.25 LINK | 37.75 LINK |
This example request requires a minimum subscription balance of 37.75 LINK. Check the **Max Cost** in the
Subscription Manager to view the minimum subscription balance for all your contracts. When your request is
processed, the actual cost of the request is deducted from your subscription balance.
#### [Estimate VRF request cost](https://docs.chain.link/vrf/v2/estimating-costs\#estimate-vrf-request-cost)
This example reflects an estimate of how much a VRF request costs. Check [Etherscan](https://etherscan.io/gastracker)
for current gas prices.
| Parameter | Value |
| --- | --- |
| Actual gas price | 50 gwei |
| Callback gas used | 95000 |
| Verification gas used | 115000 |
| LINK premium | 0.25 LINK |
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 50 gwei x (115000 + 95000) | 10500000 gwei (0.0105 ETH) |
2. Convert the gas cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.004 ETH per 1 LINK.
| ETH to LINK cost conversion | Total gas cost (LINK) |
| --- | --- |
| 0.0105 ETH / 0.004 ETH/LINK | 2.625 LINK |
3. Add the LINK premium to get the total cost of a request:
| Adding LINK premium | Total request cost (LINK) |
| --- | --- |
| Total gas cost (LINK) + LINK premium | |
| 2.625 LINK + 0.25 LINK | 2.875 LINK |
This example request would cost 2.875 LINK, which is deducted from your subscription balance.
This is an example calculation of a VRF request on the Ethereum network. The values for other supported networks
are available on the [Supported Networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks) page.
| Parameter | Value |
| --- | --- |
| Gas price | 50 gwei |
| Callback gas limit | 100000 |
| Coordinator gas overhead (Verification gas) | 90000 |
| Wrapper gas overhead | 40000 |
| Coordinator premium | 0.25 LINK |
| Wrapper premium percentage | 0 |
#### [Steps](https://docs.chain.link/vrf/v2/estimating-costs\#steps)
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas limit + Wrapper gas overhead) | |
| 50 gwei x (90000 + 100000 + 40000) | 11500000 gwei (0.0115 ETH) |
2. Convert the gas cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.004 ETH per 1 LINK.
| ETH to LINK cost conversion | Total gas cost (LINK) |
| --- | --- |
| 0.0115 ETH / 0.004 ETH/LINK | 2.875 LINK |
3. Add the LINK premium to get the total cost of a request:
| Adding LINK premium | Total request cost (LINK) |
| --- | --- |
| Coordinator premium + (Total gas cost x (1 + Wrapper premium percentage)) | |
| 0.25 LINK + (2.875 x (1 + 0)) | 3.125 LINK |
This example request would cost 3.125 LINK.
### [Arbitrum](https://docs.chain.link/vrf/v2/estimating-costs\#arbitrum)
The total transaction costs for using Arbitrum involve both L2 gas costs and L1 costs. Arbitrum transactions are [posted in batches to L1 Ethereum](https://developer.arbitrum.io/inside-arbitrum-nitro/#how-the-sequencer-publishes-the-sequence), which incurs an L1 cost. For an individual transaction, the total cost includes part of the L1 cost incurred to post the batch that included the transaction.
To learn how to estimate gas costs for Arbitrum, refer to the [Arbitrum gas estimation tutorial](https://developer.arbitrum.io/devs-how-tos/how-to-estimate-gas) and the full [Arbitrum gas estimation script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation) using their SDK. There is also a [**version of Arbitrum's gas estimation script extended to include VRF calculations**](https://docs.chain.link/vrf/v2/estimating-costs#arbitrum-and-vrf-gas-estimation-code).
#### [Estimating Arbitrum gas costs with VRF](https://docs.chain.link/vrf/v2/estimating-costs\#estimating-arbitrum-gas-costs-with-vrf)
SubscriptionDirect funding
VRF gas costs are calculated based on the amount of verification gas and callback gas used, multiplied by the gas price:

```plaintext
(Gas price * (Verification gas + Callback gas)) = total gas cost
```
For VRF Arbitrum transactions, add a buffer to estimate the additional L1 cost:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ L1 calldata gas buffer))) = total estimated gas cost
```
To calculate the L1 callback gas buffer:
- `calldataSizeBytes`: A static size for the transaction's calldata in bytes. Total: 720 bytes.
- The amount Arbitrum adds to account for the static part of the transaction, fixed at 140 bytes.
- The size of an ABI-encoded VRF V2 fulfillment, fixed at 580 bytes ( `fulfillmentTxSizeBytes`).
- `L1PricePerByte`: The estimated cost of posting 1 byte of data on L1, which varies with L1 network gas prices.
- `L2GasPrice`: The L2 gas price, which varies with L2 network gas prices.

```plaintext
L1 calldata gas buffer = (calldataSizeBytes * L1PricePerByte) / L2GasPrice
= (720 * L1PricePerByte) / L2GasPrice
```
This conversion allows us to estimate the L1 callback gas cost and incorporate it into the overall L2 gas estimate. You can add this estimated L1 callback gas buffer directly to the verification and callback gas:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost
```
VRF gas costs are calculated based on the amount of verification gas, callback gas and wrapper gas overhead, multiplied by the gas price:

```plaintext
(Gas price * (Verification gas + Callback gas + Wrapper gas overhead)) = total gas cost
```
For VRF Arbitrum transactions, add a buffer to estimate the additional L1 cost:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ Wrapper gas overhead
+ L1 calldata gas buffer))) = total estimated gas cost
```
To calculate the L1 callback gas buffer:
- `calldataSizeBytes`: A static size for the transaction's calldata in bytes. Total: 720 bytes.
- The amount Arbitrum adds to account for the static part of the transaction, fixed at 140 bytes.
- The size of an ABI-encoded VRF V2 fulfillment, fixed at 580 bytes ( `fulfillmentTxSizeBytes`).
- `L1PricePerByte`: The estimated cost of posting 1 byte of data on L1, which varies with L1 network gas prices.
- `L2GasPrice`: The L2 gas price, which varies with L2 network gas prices.

```plaintext
L1 calldata gas buffer = (calldataSizeBytes * L1PricePerByte) / L2GasPrice
= (720 * L1PricePerByte) / L2GasPrice
```
This conversion allows us to estimate the L1 callback gas cost and incorporate it into the overall L2 gas estimate. You can add this estimated L1 callback gas buffer directly to the verification, callback, and wrapper gas:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ Wrapper gas overhead
+ ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost
```
#### [Arbitrum and VRF gas estimation code](https://docs.chain.link/vrf/v2/estimating-costs\#arbitrum-and-vrf-gas-estimation-code)
This sample extends the [original Arbitrum gas estimation script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation) to estimate gas costs for VRF subscription and direct funding requests on Arbitrum.
The following snippet shows only the VRF variables and calculations that were added to the Arbitrum gas estimation script. To learn more about how Arbitrum gas is calculated, refer to the [Arbitrum gas estimation tutorial](https://developer.arbitrum.io/devs-how-tos/how-to-estimate-gas). To run this code, use the [**full Arbitrum gas estimation script that includes VRF calculations**](https://github.com/smartcontractkit/smart-contract-examples/tree/main/vrf-arbitrum-gas-estimation).

```typescript
// VRF variables and calculations
// ---------------------------------
// Full script: https://github.com/smartcontractkit/smart-contract-examples/tree/main/vrf-arbitrum-gas-estimation
// ---------------------------------
// Estimated upper bound of verification gas for VRF subscription.
// To see an estimate with an average amount of verification gas,
// adjust this to 115000.
const maxVerificationGas = 200000
// The L1 Calldata size includes:
// Arbitrum's static 140 bytes for transaction metadata
// VRF V2's static 580 bytes, the size of a fulfillment's calldata abi-encoded in bytes
// (from s_fulfillmentTxSizeBytes in VRFV2Wrapper.sol)
const VRFCallDataSizeBytes = 140 + 580
// For direct funding only. Coordinator gas is verification gas
const wrapperGasOverhead = 40000
const coordinatorGasOverhead = 90000
// VRF user settings
const callbackGasLimit = 175000
// Estimate VRF L1 buffer
const VRFL1CostEstimate = L1P.mul(VRFCallDataSizeBytes)
const VRFL1Buffer = VRFL1CostEstimate.div(P)
// VRF Subscription gas estimate
// L2 gas price (P) * (maxVerificationGas + callbackGasLimit + VRFL1Buffer)
const VRFL2SubscriptionGasSubtotal = BigNumber.from(maxVerificationGas + callbackGasLimit)
const VRFSubscriptionGasTotal = VRFL2SubscriptionGasSubtotal.add(VRFL1Buffer)
const VRFSubscriptionGasEstimate = P.mul(VRFSubscriptionGasTotal)
// VRF Direct funding gas estimate
// L2 gas price (P) * (coordinatorGasOverhead + callbackGasLimit + wrapperGasOverhead + VRFL1Buffer)
const VRFL2DirectFundingGasSubtotal = BigNumber.from(coordinatorGasOverhead + wrapperGasOverhead + callbackGasLimit)
const VRFDirectFundingGasTotal = VRFL2DirectFundingGasSubtotal.add(VRFL1Buffer)
const VRFDirectFundingGasEstimate = P.mul(VRFDirectFundingGasTotal)
```
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Networks
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Chainlink VRF Supported Networks \[v1\]](https://docs.chain.link/vrf/v1/supported-networks\#overview)
Chainlink VRF allows you to integrate provably-fair and verifiably random data in your smart contract.
For implementation details, read [Introduction to Chainlink VRF](https://docs.chain.link/vrf/v1/introduction).
## [Polygon Mainnet](https://docs.chain.link/vrf/v1/supported-networks\#polygon-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | `0xb0897686c545045aFc77CF20eC7A532E3120E0F1` |
| VRF Coordinator | `0x3d2341ADb2D31f1c5530cDC622016af293177AE0` |
| Key Hash | `0xf86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da` |
| Fee | 0.0001 LINK |
## [BNB Chain Mainnet](https://docs.chain.link/vrf/v1/supported-networks\#bnb-chain-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | `0x404460C6A5EdE2D891e8297795264fDe62ADBB75` |
| VRF Coordinator | `0x747973a5A2a4Ae1D3a8fDF5479f1514F65Db9C31` |
| Key Hash | `0xc251acd21ec4fb7f31bb8868288bfdbaeb4fbfec2df3735ddbd4f7dc8d60103c` |
| Fee | 0.2 LINK - initial fees on BNB Chain are meant to cover the highest gas cost prices. |
## [BNB Chain Testnet](https://docs.chain.link/vrf/v1/supported-networks\#bnb-chain-testnet)
| Item | Value |
| --- | --- |
| LINK | `0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06` |
| VRF Coordinator | `0xa555fC018435bef5A13C6c6870a9d4C11DEC329C ` |
| Key Hash | `0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186 ` |
| Fee | 0.1 LINK |
## [Ethereum Mainnet](https://docs.chain.link/vrf/v1/supported-networks\#ethereum-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | `0x514910771AF9Ca656af840dff83E8264EcF986CA` |
| VRF Coordinator | `0xf0d54349aDdcf704F77AE15b96510dEA15cb7952` |
| Key Hash | `0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445` |
| Fee | 2 LINK - initial fees on Ethereum are meant to cover the highest gas cost prices. |
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Billing Guide
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Billing](https://docs.chain.link/vrf/v2-5/billing\#overview)
This guide explains how to estimate VRF 2.5 costs for both the subscription and direct funding methods.
## [Understanding transaction costs](https://docs.chain.link/vrf/v2-5/billing\#understanding-transaction-costs)
SubscriptionDirect funding
For Chainlink VRF v2.5 to fulfill your requests, you must maintain enough funds in your subscription balance. Gas cost calculation includes the following variables:
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
- **Verification gas:** The amount of gas used to verify randomness onchain.
The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
For Chainlink VRF v2.5 to fulfill your requests, you must maintain enough funds in your consuming contract.
Gas cost calculation includes the following variables:
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values. The callback gas depends on your callback function and the number of random values in your request. Set the **callback gas limit** to specify the maximum amount of gas you are willing to spend on the callback request.
- **Number of random values requested:** The number of random values ( `numWords`) per request to VRF.
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Coordinator overhead gas:** The amount of gas used to verify randomness onchain. This consists of two components:
- **Coordinator overhead gas (Native or LINK):** The coordinator overhead gas has different values depending on whether you're using LINK or native tokens.
- **Coordinator overhead gas per word:** The amount of additional gas the coordinator uses per random value ("word") that you request.
- **Wrapper overhead gas:** The amount of gas used by the VRF Wrapper contract.
Because the consuming contract directly pays for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Test your callback function to learn how to correctly estimate the callback gas limit.
- If the gas limit is underestimated, the callback fails and the consuming contract is still charged for the work done to generate the requested random values.
- If the gas limit is overestimated, the callback function will be executed but your contract is not refunded for the excess gas amount that you paid.
Make sure that your consuming contracts have enough funds in either LINK or native tokens to cover the transaction costs. If the consuming contract doesn't have enough funds, your request will revert.
### [Estimate gas costs](https://docs.chain.link/vrf/v2-5/billing\#estimate-gas-costs)
SubscriptionDirect funding
You need to pre-fund your subscription enough to meet the [minimum subscription balance](https://docs.chain.link/vrf/v2/subscription#minimum-subscription-balance)
in order to have a buffer against gas volatility.
After the request is complete, the final gas cost is recorded based on how much gas is used for the verification and callback.
The actual cost of the request is deducted from your subscription balance.
The total gas cost in wei for your request uses the following formula:

```plaintext
(Gas price * (Verification gas + Callback gas)) = total gas cost
```
If you're paying for VRF in LINK, the total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is
unavailable, the VRF coordinator uses the `fallbackWeiPerUnitLink` value for the conversion instead. The
`fallbackWeiPerUnitLink` value is defined in the
[coordinator contract](https://docs.chain.link/vrf/v2-5/supported-networks) for your selected network.
The final gas cost to fulfill randomness is estimated based on how much gas is expected for the verification and callback. The total gas cost in wei uses the following formula:

```plaintext
(Gas price * (Coordinator gas overhead
+ Callback gas limit
+ Wrapper gas overhead)) = total gas cost
```
The total gas cost is converted to LINK using the ETH/LINK data feed. In the unlikely event that the data feed is unavailable, the VRF Wrapper uses the `fallbackWeiPerUnitLink` value for the conversion instead. The `fallbackWeiPerUnitLink` value is defined in the [VRF v2.5 Wrapper contract](https://docs.chain.link/vrf/v2-5/supported-networks) for your selected network.
The maximum allowed `callbackGasLimit` value for your requests is defined in the [Coordinator contract supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page. Because the VRF v2.5 Wrapper adds gas overheads, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`.
### [Apply premium](https://docs.chain.link/vrf/v2-5/billing\#apply-premium)
SubscriptionDirect funding
The premium is charged as a percentage of the overall gas cost. The premium is defined in the [coordinator contract](https://docs.chain.link/vrf/v2-5/supported-networks). Premium percentages are listed there as whole integers. For example, a 20% premium is listed as `20`.

```plaintext
(total gas cost) * ((100 + Premium percentage) / 100) = total request cost
```
The total request cost is charged to your subscription balance. Since you have the option to pay for VRF requests either in LINK or the native token for the network you're using, your subscription can have both a LINK balance and a native token balance. The premium is higher when you pay with native tokens than when you pay with LINK. For example, the premium percentage for using Ethereum is 24 if you pay with Ethereum, and 20 if you pay with LINK.
The premium is divided in two parts:
- Wrapper premium: This premium is charged as a percentage of the overall gas cost. Premium percentages are listed there as whole integers. For example, a 20% premium is listed as `20`. You can find the percentage for your network in the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- Coordinator premium: A flat fee. This premium is defined in the `fulfillmentFlatFeeLinkPPMTier1` parameter in millionths of LINK. You can find the flat fee of the coordinator for your network in the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.

```plaintext
(Coordinator premium
+ (total gas cost) * ((100 + Premium percentage) / 100)) = total request cost
```
The total request cost is charged to your consuming contract. The premium is higher when you pay with native tokens than when you pay with LINK. For example, the premium percentage for using Ethereum is 24 if you pay with Ethereum, and 20 if you pay with LINK.
### [Subscription cost examples](https://docs.chain.link/vrf/v2-5/billing\#subscription-cost-examples)
These are example calculations of a VRF subscription request on Ethereum, shown in both ETH and LINK. The values for other supported networks
are available on the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
The examples show how to estimate the following:
- The [minimum subscription balance](https://docs.chain.link/vrf/v2-5/overview/subscription#minimum-subscription-balance), which is a higher amount you need to reserve before your request is processed. This provides a buffer in case gas prices go higher when processing the request. The VRF Subscription Manager displays your minimum subscription balance as **Max Cost**.
- The actual cost of the request after it is processed, which is lower than the minimum subscription balance.
#### [Estimate minimum subscription balance](https://docs.chain.link/vrf/v2-5/billing\#estimate-minimum-subscription-balance)
These example calculations show an estimated minimum subscription balance for using VRF on Ethereum, shown in both ETH and LINK. The premium is higher when you pay with native tokens than when you pay with LINK.
Paying in LINKPaying in ETH
| Parameter | Value |
| --- | --- |
| Gas lane | 500 gwei |
| Callback gas limit | 100000 |
| Max verification gas | 200000 |
| Premium percentage | 20 |
1. Calculate the total gas cost, using the maximum possible gas price for the selected gas lane, the estimated maximum verification gas, and the full callback gas limit:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 500 gwei x (200000 + 100000) | 150000000 gwei (0.15 ETH) |
2. Apply the premium percentage to get the total maximum cost of a request:
| Applying premium percentage | Maximum request cost (ETH) |
| --- | --- |
| Total gas cost (ETH) \* ((100 + premium percentage)/100) | |
| 0.15 ETH \* ((100 + 20)/100) | 0.18 ETH |
3. Convert the total cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.005 ETH per 1 LINK.
| ETH to LINK cost conversion | Maximum request cost (LINK) |
| --- | --- |
| 0.18 ETH / 0.005 ETH/LINK | 36 LINK |
For this example request to go through, you need to reserve a minimum subscription balance of 36 LINK, but that does not mean the actual request will cost 36 LINK. Check the **Max Cost** in the
Subscription Manager to view the minimum subscription balance for all your contracts. When your request is processed, the actual cost of the request is calculated and deducted from your subscription balance. See [the next section](https://docs.chain.link/vrf/v2-5/billing#estimate-vrf-request-cost) for an example of how to calculate the actual request cost.
| Parameter | Value |
| --- | --- |
| Gas lane | 500 gwei |
| Callback gas limit | 100000 |
| Max verification gas | 200000 |
| Premium percentage | 24 |
1. Calculate the total gas cost, using the maximum possible gas price for the selected gas lane, the estimated maximum verification gas, and the full callback gas limit:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 500 gwei x (200000 + 100000) | 150000000 gwei (0.15 ETH) |
2. Apply the premium percentage to get the total maximum cost of a request:
| Applying premium percentage | Maximum request cost (ETH) |
| --- | --- |
| Total gas cost (ETH) \* ((100 + premium percentage)/100) | |
| 0.15 ETH \* ((100 + 24)/100) | 0.186 ETH |
For this example request to go through, you need to reserve a minimum subscription balance of 0.186 ETH, but that does not mean the actual request will cost 0.186 ETH. Check the **Max Cost** in the Subscription Manager to view the minimum subscription balance for all your contracts. When your request is processed, the actual cost of the request is deducted from your subscription balance. See [the next section](https://docs.chain.link/vrf/v2-5/billing#estimate-vrf-request-cost) for an example of how to calculate the actual request cost.
#### [Estimate VRF request cost](https://docs.chain.link/vrf/v2-5/billing\#estimate-vrf-request-cost)
These example calculations show a cost breakdown of a VRF subscription request on the Ethereum network. Check [Etherscan](https://etherscan.io/gastracker)
for current gas prices.
Paying in LINKPaying in ETH
| Parameter | Value |
| --- | --- |
| Actual gas price | 50 gwei |
| Callback gas used | 95000 |
| Verification gas used | 115000 |
| Premium percentage | 20 |
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 50 gwei x (115000 + 95000) | 10500000 gwei (0.0105 ETH) |
2. Apply the premium percentage to get the total cost of a request:
| Applying premium percentage | Total request cost (ETH) |
| --- | --- |
| Total gas cost (ETH) \* ((100 + premium percentage)/100) | |
| 0.0105 ETH \* ((100 + 20)/100) | 0.0126 ETH |
3. Convert the total cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.005 ETH per 1 LINK.
| ETH to LINK cost conversion | Total gas cost (LINK) |
| --- | --- |
| 0.0126 ETH / 0.005 ETH/LINK | 2.52 LINK |
This example request would cost 2.52 LINK, which is deducted from your subscription balance.
| Parameter | Value |
| --- | --- |
| Actual gas price | 50 gwei |
| Callback gas used | 95000 |
| Verification gas used | 115000 |
| Premium percentage | 24 |
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price x (Verification gas + Callback gas) | |
| 50 gwei x (115000 + 95000) | 10500000 gwei (0.0105 ETH) |
2. Apply the premium percentage to get the total maximum cost of a request:
| Applying premium percentage | Maximum request cost (ETH) |
| --- | --- |
| Total gas cost (ETH) \* ((100 + premium percentage)/100) | |
| 0.0105 ETH \* ((100 + 24)/100) | 0.01302 ETH |
This example request would cost 0.01302 ETH, which is deducted from your subscription balance.
### [Direct funding cost examples](https://docs.chain.link/vrf/v2-5/billing\#direct-funding-cost-examples)
These are example calculations of a VRF direct funding request on Ethereum, shown in both ETH and LINK. The values for other supported networks
are available on the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
Paying in LINKPaying in ETH
| Parameter | Value |
| --- | --- |
| Gas price | 50 gwei |
| Callback gas limit | 100000 |
| Coordinator gas overhead (LINK) | 112000 |
| Wrapper gas overhead | 13400 |
| Coordinator gas overhead per word | 435 |
| Number of random values (words) | 2 |
| Wrapper premium percentage | 20 |
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price \_ (Coordinator overhead gas + Callback gas limit + Wrapper gas overhead + (Coordinator overhead gas per word \_ Number of words)) | |
| 50 gwei x (112000 + 100000 + 13400 + (435 \* 2)) | 11313500 gwei (0.0113135 ETH) |
2. Convert the gas cost to LINK using the [LINK/ETH feed](https://data.chain.link/ethereum/mainnet/crypto-eth/link-eth).
For this example, assume the feed returns a conversion value of Ξ0.004 ETH per 1 LINK.
| ETH to LINK cost conversion | Total gas cost (LINK) |
| --- | --- |
| 0.0113135 ETH / 0.004 ETH/LINK | 2.828375 LINK |
3. Apply the premium percentage to get the total cost of a request:
| Applying premium percentage | Request cost (LINK) |
| --- | --- |
| Total gas cost (LINK) \* ((100 + premium percentage)/100) | |
| (2.828375 LINK \* (100 + 20))/100) | 3.39405 LINK |
This example request would cost 3.39405 LINK.
| Parameter | Value |
| --- | --- |
| Gas price | 50 gwei |
| Callback gas limit | 100000 |
| Coordinator gas overhead (Native) | 90000 |
| Wrapper gas overhead | 13400 |
| Coordinator gas overhead per word | 435 |
| Number of random values (words) | 2 |
| Wrapper premium percentage | 24 |
1. Calculate the total gas cost:
| Gas cost calculation | Total gas cost |
| --- | --- |
| Gas price \_ (Coordinator overhead gas + Callback gas limit + Wrapper gas overhead + (Coordinator overhead gas per word \_ Number of words)) | |
| 50 gwei x (90000 + 100000 + 13400 + (435 \* 2)) | 10213500 gwei (0.0102135 ETH) |
2. Apply the premium percentage to get the total cost of a request:
| Applying premium percentage | Request cost (ETH) |
| --- | --- |
| Total gas cost (ETH) \* ((100 + premium percentage)/100) | |
| (0.0102135 ETH \* (100 + 24))/100) | 0.01266474 ETH |
This example request would cost 0.01266474 ETH.
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Security
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Security Considerations](https://docs.chain.link/vrf/v2-5/security\#overview)
Gaining access to high quality randomness onchain requires a solution like Chainlink's VRF, but it also requires you to understand some of the ways that miners or validators can potentially manipulate randomness generation. Here are some of the top security considerations you should review in your project.
- [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v2-5/security#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
- [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v2-5/security#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
- [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v2-5/security#do-not-allow-re-requesting-or-cancellation-of-randomness)
- [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v2-5/security#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
- [The `fulfillRandomWords` function must not revert](https://docs.chain.link/vrf/v2-5/security#fulfillrandomwords-must-not-revert)
- [Use `VRFConsumerBaseV2Plus` in your contract to interact with the VRF service](https://docs.chain.link/vrf/v2-5/security#use-vrfconsumerbasev2plus-in-your-contract-to-interact-with-the-vrf-service)
## [Use `requestId` to match randomness requests with their fulfillment in order](https://docs.chain.link/vrf/v2-5/security\#use-requestid-to-match-randomness-requests-with-their-fulfillment-in-order)
If your contract could have multiple VRF requests in flight simultaneously, you must ensure that the order in which the VRF fulfillments arrive cannot be used to manipulate your contract's user-significant behavior.
Blockchain miners/validators can control the order in which your requests appear onchain, and hence the order in which your contract responds to them.
For example, if you made randomness requests `A`, `B`, `C` in short succession, there is no guarantee that the associated randomness fulfillments will also be in order `A`, `B`, `C`. The randomness fulfillments might just as well arrive at your contract in order `C`, `A`, `B` or any other order.
We recommend using the `requestID` to match randomness requests with their corresponding fulfillments.
## [Choose a safe block confirmation time, which will vary between blockchains](https://docs.chain.link/vrf/v2-5/security\#choose-a-safe-block-confirmation-time-which-will-vary-between-blockchains)
In principle, miners/validators of your underlying blockchain could rewrite the chain's history to put a randomness request from your contract into a different block, which would result in a different VRF output. Note that this does not enable a miner to determine the random value in advance. It only enables them to get a fresh random value that might or might not be to their advantage. By way of analogy, they can only re-roll the dice, not predetermine or predict which side it will land on.
You must choose an appropriate confirmation time for the randomness requests you make. Confirmation time is how many blocks the VRF service waits before writing a fulfillment to the chain to make potential rewrite attacks unprofitable in the context of your application and its value-at-risk.
## [Do not allow re-requesting or cancellation of randomness](https://docs.chain.link/vrf/v2-5/security\#do-not-allow-re-requesting-or-cancellation-of-randomness)
Any re-request or cancellation of randomness is an incorrect use of VRF v2.5. dApps that implement the ability to cancel or re-request randomness for specific commitments must consider the additional attack vectors created by this capability. For example, you must prevent the ability for any party to discard unfavorable randomness.
## [Don't accept bids/bets/inputs after you have made a randomness request](https://docs.chain.link/vrf/v2-5/security\#dont-accept-bidsbetsinputs-after-you-have-made-a-randomness-request)
Consider the example of a contract that mints a random NFT in response to a user's actions.
The contract should:
1. Record whatever actions of the user may affect the generated NFT.
2. **Stop accepting further user actions that might affect the generated NFT** and issue a randomness request.
3. On randomness fulfillment, mint the NFT.
Generally speaking, whenever an outcome in your contract depends on some user-supplied inputs and randomness, the contract should not accept any additional user-supplied inputs after it submits the randomness request.
Otherwise, the cryptoeconomic security properties may be violated by an attacker that can rewrite the chain.
## [`fulfillRandomWords` must not revert](https://docs.chain.link/vrf/v2-5/security\#fulfillrandomwords-must-not-revert)
If your `fulfillRandomWords()` implementation reverts, the VRF service will not attempt to call it a second time. Make sure your contract logic does not revert. Consider simply storing the randomness and taking more complex follow-on actions in separate contract calls made by you, your users, or an [Automation Node](https://docs.chain.link/chainlink-automation).
## [Use `VRFConsumerBaseV2Plus` in your contract, to interact with the VRF service](https://docs.chain.link/vrf/v2-5/security\#use-vrfconsumerbasev2plus-in-your-contract-to-interact-with-the-vrf-service)
If you implement the [subscription method](https://docs.chain.link/vrf/v2-5/overview/subscription), use `VRFConsumerBaseV2Plus`. It includes a check to ensure the randomness is fulfilled by `VRFCoordinatorV2_5`. For this reason, it is a best practice to inherit from `VRFConsumerBaseV2Plus`. Similarly, don't override `rawFulfillRandomness`.
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Best Practices
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [VRF Best Practices](https://docs.chain.link/vrf/v2-5/best-practices\#overview)
These are example best practices for using Chainlink VRF. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Getting a random number within a range](https://docs.chain.link/vrf/v2-5/best-practices\#getting-a-random-number-within-a-range)
If you need to generate a random number within a given range, use [modulo](https://docs.soliditylang.org/en/v0.8.7/types.html#modulo) to define the limits of your range. Below you can see how to get a random number in a range from 1 to 50.

```solidity
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
// Assuming only one random word was requested.
s_randomRange = (randomWords[0] % 50) + 1;
}
```
## [Getting multiple random values](https://docs.chain.link/vrf/v2-5/best-practices\#getting-multiple-random-values)
If you want to get multiple random values from a single VRF request, you can request this directly with the `numWords` argument:
- If you are using the VRF v2.5 subscription method, see the [full example code](https://docs.chain.link/vrf/v2-5/migration-from-v2#compare-example-code) for an example where one request returns multiple random values.
## [Processing simultaneous VRF requests](https://docs.chain.link/vrf/v2-5/best-practices\#processing-simultaneous-vrf-requests)
If you want to have multiple VRF requests processing simultaneously, create a mapping between `requestId` and the response. You might also create a mapping between the `requestId` and the address of the requester to track which address made each request.

```solidity
mapping(uint256 => uint256[]) public s_requestIdToRandomWords;
mapping(uint256 => address) public s_requestIdToAddress;
uint256 public s_requestId;
function requestRandomWords() external onlyOwner returns (uint256) {
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) // new parameter
})
);
s_requestIdToAddress[requestId] = msg.sender;
// Store the latest requestId for this example.
s_requestId = requestId;
// Return the requestId to the requester.
return requestId;
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
// You can return the value to the requester,
// but this example simply stores it.
s_requestIdToRandomWords[requestId] = randomWords;
}
```
You could also map the `requestId` to an index to keep track of the order in which a request was made.

```solidity
mapping(uint256 => uint256) s_requestIdToRequestIndex;
mapping(uint256 => uint256[]) public s_requestIndexToRandomWords;
uint256 public requestCounter;
function requestRandomWords() external onlyOwner {
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) // new parameter
})
);
s_requestIdToRequestIndex[requestId] = requestCounter;
requestCounter += 1;
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
uint256 requestNumber = s_requestIdToRequestIndex[requestId];
s_requestIndexToRandomWords[requestNumber] = randomWords;
}
```
## [Processing VRF responses through different execution paths](https://docs.chain.link/vrf/v2-5/best-practices\#processing-vrf-responses-through-different-execution-paths)
If you want to process VRF responses depending on predetermined conditions, you can create an `enum`. When requesting for randomness, map each `requestId` to an enum. This way, you can handle different execution paths in `fulfillRandomWords`. See the following example:

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
// It shows how to setup multiple execution paths for handling a response.
pragma solidity 0.8.19;
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import {IVRFCoordinatorV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/interfaces/IVRFCoordinatorV2Plus.sol";
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.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 VRFv2MultiplePaths is VRFConsumerBaseV2Plus {
// Your subscription ID.
uint256 s_subscriptionId;
// Sepolia coordinator. For other networks,
// see https://docs.chain.link/docs/vrf/v2-5/supported-networks
address vrfCoordinatorV2Plus = 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B;
// 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/v2-5/supported-networks
bytes32 keyHash =
0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 1 random value in one request.
// Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS.
uint32 numWords = 1;
enum Variable {
A,
B,
C
}
uint256 public variableA;
uint256 public variableB;
uint256 public variableC;
mapping(uint256 => Variable) public requests;
// events
event FulfilledA(uint256 requestId, uint256 value);
event FulfilledB(uint256 requestId, uint256 value);
event FulfilledC(uint256 requestId, uint256 value);
constructor(uint256 subscriptionId) VRFConsumerBaseV2Plus(vrfCoordinatorV2Plus) {
s_vrfCoordinator = IVRFCoordinatorV2Plus(vrfCoordinatorV2Plus);
s_subscriptionId = subscriptionId;
}
function updateVariable(uint256 input) public {
uint256 requestId = s_vrfCoordinator.requestRandomWords(VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
})
);
if (input % 2 == 0) {
requests[requestId] = Variable.A;
} else if (input % 3 == 0) {
requests[requestId] = Variable.B;
} else {
requests[requestId] = Variable.C;
}
}
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
) internal override {
Variable variable = requests[requestId];
if (variable == Variable.A) {
fulfillA(requestId, randomWords[0]);
} else if (variable == Variable.B) {
fulfillB(requestId, randomWords[0]);
} else if (variable == Variable.C) {
fulfillC(requestId, randomWords[0]);
}
}
function fulfillA(uint256 requestId, uint256 randomWord) private {
// execution path A
variableA = randomWord;
emit FulfilledA(requestId, randomWord);
}
function fulfillB(uint256 requestId, uint256 randomWord) private {
// execution path B
variableB = randomWord;
emit FulfilledB(requestId, randomWord);
}
function fulfillC(uint256 requestId, uint256 randomWord) private {
// execution path C
variableC = randomWord;
emit FulfilledC(requestId, randomWord);
}
}
```
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Supported Networks
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks\#overview)
Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract. For implementation details, read [Introduction to Chainlink VRF](https://docs.chain.link/vrf).
VRF v2.5 coordinators for subscription funding are available on several networks. To use Chainlink VRF on certain networks, you may need to conduct token transfers. You can transfer tokens by using [Chainlink CCIP](https://docs.chain.link/ccip/tutorials/evm/transfer-tokens-from-contract), [Transporter](https://www.transporter.io/) or third-party applications such as [XSwap](https://xswap.link/).
## [Coordinator parameters](https://docs.chain.link/vrf/v2-5/supported-networks\#coordinator-parameters)
These parameters are configured in the coordinator contract. You can view these values by running `getConfig` on the coordinator or by viewing the coordinator contracts in a blockchain explorer.
- `uint16 minimumRequestConfirmations`: The minimum number of confirmation blocks on VRF requests before oracles respond
- `uint32 maxGasLimit`: The maximum gas limit supported for a `fulfillRandomWords` callback.
- `uint32 stalenessSeconds`: How long the coordinator waits until we consider the ETH/LINK price used for converting gas costs to LINK is stale and use `fallbackWeiPerUnitLink`
- `uint32 gasAfterPaymentCalculation`: How much gas is used outside of the payment calculation. This covers the additional operations required to decrement the subscription balance and increment the balance for the oracle that handled the request.
## [Arbitrum](https://docs.chain.link/vrf/v2-5/supported-networks\#arbitrum)
### [Arbitrum Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#arbitrum-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4 "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4") |
| VRF Coordinator | [0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e](https://arbiscan.io/address/0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e "0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e") |
| 2 gwei Key Hash | `0x9e9e46732b32662b9adc6f3abdf6c5e926a666d174a4d6b8e39c4cca76a38897` |
| 30 gwei Key Hash | `0x8472ba59cf7134dfe321f4d61a430c4857e8b19cdd5230b09952a92671c24409` |
| 150 gwei Key Hash | `0xe9f223d7d83ec85c4f78042a4845af3a1c8df7757b4997b815ce4b8d07aca68c` |
| Premium percentage
(paying with ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4 "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4") |
| VRF Wrapper | [0x14632CD5c12eC5875D41350B55e825c54406BaaB](https://arbiscan.io/address/0x14632CD5c12eC5875D41350B55e825c54406BaaB "0x14632CD5c12eC5875D41350B55e825c54406BaaB") |
| VRF Coordinator | [0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e](https://arbiscan.io/address/0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e "0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e") |
| 2 gwei Key Hash | `0x9e9e46732b32662b9adc6f3abdf6c5e926a666d174a4d6b8e39c4cca76a38897` |
| 30 gwei Key Hash | `0x8472ba59cf7134dfe321f4d61a430c4857e8b19cdd5230b09952a92671c24409` |
| 150 gwei Key Hash | `0xe9f223d7d83ec85c4f78042a4845af3a1c8df7757b4997b815ce4b8d07aca68c` |
| Premium percentage
(paying with ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 104500 |
| Coordinator Gas Overhead (LINK) | 126500 |
| Coordinator Gas Overhead per Word | 435 |
### [Arbitrum Sepolia Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#arbitrum-sepolia-testnet)
Testnet ETH and LINK are available from [https://faucets.chain.link/arbitrum-sepolia](https://faucets.chain.link/arbitrum-sepolia)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E") |
| VRF Coordinator | [0x5CE8D5A2BC84beb22a398CCA51996F7930313D61](https://sepolia.arbiscan.io/address/0x5CE8D5A2BC84beb22a398CCA51996F7930313D61 "0x5CE8D5A2BC84beb22a398CCA51996F7930313D61") |
| 50 gwei Key Hash | `0x1770bdc7eec7771f7ba4ffd640f34260d7f095b79c92d34a5b2551d6f6cfd2be` |
| Premium percentage
(paying with Sepolia ETH) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E") |
| VRF Wrapper | [0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC](https://sepolia.arbiscan.io/address/0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC "0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC") |
| VRF Coordinator | [0x5CE8D5A2BC84beb22a398CCA51996F7930313D61](https://sepolia.arbiscan.io/address/0x5CE8D5A2BC84beb22a398CCA51996F7930313D61 "0x5CE8D5A2BC84beb22a398CCA51996F7930313D61") |
| 50 gwei Key Hash | `0x1770bdc7eec7771f7ba4ffd640f34260d7f095b79c92d34a5b2551d6f6cfd2be` |
| Premium percentage
(paying with Sepolia ETH) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 104500 |
| Coordinator Gas Overhead (LINK) | 126500 |
| Coordinator Gas Overhead per Word | 435 |
## [Avalanche](https://docs.chain.link/vrf/v2-5/supported-networks\#avalanche)
### [Avalanche Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#avalanche-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3 "0x5947BB275c521040051D82396192181b413227A3") |
| VRF Coordinator | [0xE40895D055bccd2053dD0638C9695E326152b1A4](https://snowtrace.io/address/0xE40895D055bccd2053dD0638C9695E326152b1A4 "0xE40895D055bccd2053dD0638C9695E326152b1A4") |
| 200 gwei Key Hash | `0xea7f56be19583eeb8255aa79f16d8bd8a64cedf68e42fefee1c9ac5372b1a102` |
| 500 gwei Key Hash | `0x84213dcadf1f89e4097eb654e3f284d7d5d5bda2bd4748d8b7fada5b3a6eaa0d` |
| 1000 gwei Key Hash | `0xe227ebd10a873dde8e58841197a07b410038e405f1180bd117be6f6557fa491c` |
| Premium percentage
(paying with AVAX) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3 "0x5947BB275c521040051D82396192181b413227A3") |
| VRF Wrapper | [0x62Fb87c10A917580cA99AB9a86E213Eb98aa820C](https://snowtrace.io/address/0x62Fb87c10A917580cA99AB9a86E213Eb98aa820C "0x62Fb87c10A917580cA99AB9a86E213Eb98aa820C") |
| VRF Coordinator | [0xE40895D055bccd2053dD0638C9695E326152b1A4](https://snowtrace.io/address/0xE40895D055bccd2053dD0638C9695E326152b1A4 "0xE40895D055bccd2053dD0638C9695E326152b1A4") |
| 200 gwei Key Hash | `0xea7f56be19583eeb8255aa79f16d8bd8a64cedf68e42fefee1c9ac5372b1a102` |
| 500 gwei Key Hash | `0x84213dcadf1f89e4097eb654e3f284d7d5d5bda2bd4748d8b7fada5b3a6eaa0d` |
| 1000 gwei Key Hash | `0xe227ebd10a873dde8e58841197a07b410038e405f1180bd117be6f6557fa491c` |
| Premium percentage
(paying with AVAX) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 107000 |
| Coordinator Gas Overhead (LINK) | 129000 |
| Coordinator Gas Overhead per Word | 435 |
### [Avalanche Fuji Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#avalanche-fuji-testnet)
Testnet LINK is available from [https://faucets.chain.link/fuji](https://faucets.chain.link/fuji)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846 "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846") |
| VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://testnet.snowtrace.io/address/0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE "0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE") |
| 300 gwei Key Hash | `0xc799bd1e3bd4d1a41cd4968997a4e03dfd2a3c7c04b695881138580163f42887` |
| Premium percentage
(paying with testnet AVAX) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846 "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846") |
| VRF Wrapper | [0x327B83F409E1D5f13985c6d0584420FA648f1F56](https://testnet.snowtrace.io/address/0x327B83F409E1D5f13985c6d0584420FA648f1F56 "0x327B83F409E1D5f13985c6d0584420FA648f1F56") |
| VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://testnet.snowtrace.io/address/0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE "0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE") |
| 300 gwei Key Hash | `0xc799bd1e3bd4d1a41cd4968997a4e03dfd2a3c7c04b695881138580163f42887` |
| Premium percentage
(paying with testnet AVAX) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 104500 |
| Coordinator Gas Overhead (LINK) | 126500 |
| Coordinator Gas Overhead per Word | 435 |
## [BASE](https://docs.chain.link/vrf/v2-5/supported-networks\#base)
### [BASE Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#base-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196](https://basescan.org/address/0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196 "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196") |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://basescan.org/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| 2 gwei Key Hash | `0x00b81b5a830cb0a4009fbd8904de511e28631e62ce5ad231373d3cdad373ccab` |
| 30 gwei Key Hash | `0xdc2f87677b01473c763cb0aee938ed3341512f6057324a584e5944e786144d70` |
| Premium percentage
(paying with BASE) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196](https://basescan.org/address/0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196 "0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196") |
| VRF Wrapper | [0xb0407dbe851f8318bd31404A49e658143C982F23](https://basescan.org/address/0xb0407dbe851f8318bd31404A49e658143C982F23 "0xb0407dbe851f8318bd31404A49e658143C982F23") |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://basescan.org/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| 2 gwei Key Hash | `0x00b81b5a830cb0a4009fbd8904de511e28631e62ce5ad231373d3cdad373ccab` |
| 30 gwei Key Hash | `0xdc2f87677b01473c763cb0aee938ed3341512f6057324a584e5944e786144d70` |
| Premium percentage
(paying with BASE) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
### [BASE Sepolia Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#base-sepolia-testnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia.basescan.org/address/0xE4aB69C077896252FAFBD49EFD26B5D171A32410 "0xE4aB69C077896252FAFBD49EFD26B5D171A32410") |
| VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://sepolia.basescan.org/address/0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE "0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE") |
| 30 gwei Key Hash | `0x9e1344a1247c8a1785d0a4681a27152bffdb43666ae5bf7d14d24a5efd44bf71` |
| Premium percentage
(paying with Sepolia BASE ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia.basescan.org/address/0xE4aB69C077896252FAFBD49EFD26B5D171A32410 "0xE4aB69C077896252FAFBD49EFD26B5D171A32410") |
| VRF Wrapper | [0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed](https://sepolia.basescan.org/address/0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed "0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed") |
| VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://sepolia.basescan.org/address/0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE "0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE") |
| 30 gwei Key Hash | `0x9e1344a1247c8a1785d0a4681a27152bffdb43666ae5bf7d14d24a5efd44bf71` |
| Premium percentage
(paying with Sepolia BASE ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
## [BNB Chain](https://docs.chain.link/vrf/v2-5/supported-networks\#bnb-chain)
### [BNB Chain Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#bnb-chain-mainnet)
The LINK provided by the [BNB Chain Bridge](https://www.bnbchain.world/en/bridge) is not ERC-677 compatible, so cannot
be used with Chainlink oracles. However, it can be [**converted to the official LINK token on BNB Chain using Chainlink's PegSwap service**](https://pegswap.chain.link/).
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75 "0x404460C6A5EdE2D891e8297795264fDe62ADBB75") |
| VRF Coordinator | [0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9](https://bscscan.com/address/0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9 "0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9") |
| 200 gwei Key Hash | `0x130dba50ad435d4ecc214aad0d5820474137bd68e7e77724144f27c3c377d3d4` |
| 500 gwei Key Hash | `0xeb0f72532fed5c94b4caf7b49caf454b35a729608a441101b9269efb7efe2c6c` |
| 1000 gwei Key Hash | `0xb94a4fdb12830e15846df59b27d7c5d92c9c24c10cf6ae49655681ba560848dd` |
| Premium percentage
(paying with BNB) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75 "0x404460C6A5EdE2D891e8297795264fDe62ADBB75") |
| VRF Wrapper | [0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94](https://bscscan.com/address/0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94 "0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94") |
| VRF Coordinator | [0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9](https://bscscan.com/address/0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9 "0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9") |
| 200 gwei Key Hash | `0x130dba50ad435d4ecc214aad0d5820474137bd68e7e77724144f27c3c377d3d4` |
| 500 gwei Key Hash | `0xeb0f72532fed5c94b4caf7b49caf454b35a729608a441101b9269efb7efe2c6c` |
| 1000 gwei Key Hash | `0xb94a4fdb12830e15846df59b27d7c5d92c9c24c10cf6ae49655681ba560848dd` |
| Premium percentage
(paying with testnet BNB) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
### [BNB Chain Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#bnb-chain-testnet)
SubscriptionDirect funding
Testnet LINK is available from [https://faucets.chain.link/bnb-chain-testnet](https://faucets.chain.link/bnb-chain-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06](https://testnet.bscscan.com/address/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06") |
| VRF Coordinator | [0xDA3b641D438362C440Ac5458c57e00a712b66700](https://testnet.bscscan.com/address/0xDA3b641D438362C440Ac5458c57e00a712b66700 "0xDA3b641D438362C440Ac5458c57e00a712b66700") |
| 50 gwei Key Hash | `0x8596b430971ac45bdf6088665b9ad8e8630c9d5049ab54b14dff711bee7c0e26` |
| Premium percentage
(paying with testnet BNB) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06](https://testnet.bscscan.com/address/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06") |
| VRF Wrapper | [0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94](https://testnet.bscscan.com/address/0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94 "0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94") |
| VRF Coordinator | [0xDA3b641D438362C440Ac5458c57e00a712b66700](https://testnet.bscscan.com/address/0xDA3b641D438362C440Ac5458c57e00a712b66700 "0xDA3b641D438362C440Ac5458c57e00a712b66700") |
| 50 gwei Key Hash | `0x8596b430971ac45bdf6088665b9ad8e8630c9d5049ab54b14dff711bee7c0e26` |
| Premium percentage
(paying with testnet BNB) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
## [Ethereum](https://docs.chain.link/vrf/v2-5/supported-networks\#ethereum)
### [Ethereum Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#ethereum-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA "0x514910771AF9Ca656af840dff83E8264EcF986CA") |
| VRF Coordinator | [0xD7f86b4b8Cae7D942340FF628F82735b7a20893a](https://etherscan.io/address/0xD7f86b4b8Cae7D942340FF628F82735b7a20893a "0xD7f86b4b8Cae7D942340FF628F82735b7a20893a") |
| 200 gwei Key Hash | `0x8077df514608a09f83e4e8d300645594e5d7234665448ba83f51a50f842bd3d9` |
| 500 gwei Key Hash | `0x3fd2fec10d06ee8f65e7f2e95f5c56511359ece3f33960ad8a866ae24a8ff10b` |
| 1000 gwei Key Hash | `0xc6bf2e7b88e5cfbb4946ff23af846494ae1f3c65270b79ee7876c9aa99d3d45f` |
| Premium percentage
(paying with ETH) | 24 |
| Premium percentage
(paying with LINK) | 20 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA "0x514910771AF9Ca656af840dff83E8264EcF986CA") |
| VRF Wrapper | [0x02aae1A04f9828517b3007f83f6181900CaD910c](https://etherscan.io/address/0x02aae1A04f9828517b3007f83f6181900CaD910c "0x02aae1A04f9828517b3007f83f6181900CaD910c") |
| VRF Coordinator | [0xD7f86b4b8Cae7D942340FF628F82735b7a20893a](https://etherscan.io/address/0xD7f86b4b8Cae7D942340FF628F82735b7a20893a "0xD7f86b4b8Cae7D942340FF628F82735b7a20893a") |
| 200 gwei Key Hash | `0x8077df514608a09f83e4e8d300645594e5d7234665448ba83f51a50f842bd3d9` |
| 500 gwei Key Hash | `0x3fd2fec10d06ee8f65e7f2e95f5c56511359ece3f33960ad8a866ae24a8ff10b` |
| 1000 gwei Key Hash | `0xc6bf2e7b88e5cfbb4946ff23af846494ae1f3c65270b79ee7876c9aa99d3d45f` |
| Premium percentage
(paying with ETH) | 24 |
| Premium percentage
(paying with LINK) | 20 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 90000 |
| Coordinator Gas Overhead (LINK) | 112000 |
| Coordinator Gas Overhead per Word | 435 |
### [Ethereum Sepolia Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#ethereum-sepolia-testnet)
Testnet LINK and ETH are available from [faucets.chain.link](https://faucets.chain.link/sepolia).
Testnet ETH is also available from several public [ETH faucets](https://faucetlink.to/sepolia).
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789 "0x779877A7B0D9E8603169DdbD7836e478b4624789") |
| VRF Coordinator | [0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B](https://sepolia.etherscan.io/address/0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B "0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B") |
| 500 gwei Key Hash | `0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae` |
| Premium percentage
(paying with Sepolia ETH) | 24 |
| Premium percentage
(paying with testnet LINK) | 20 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789 "0x779877A7B0D9E8603169DdbD7836e478b4624789") |
| VRF Wrapper | [0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1](https://sepolia.etherscan.io/address/0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1 "0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1") |
| VRF Coordinator | [0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B](https://sepolia.etherscan.io/address/0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B "0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B") |
| 500 gwei Key Hash | `0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae` |
| Premium percentage
(paying with Sepolia ETH) | 24 |
| Premium percentage
(paying with testnet LINK) | 20 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 90000 |
| Coordinator Gas Overhead (LINK) | 112000 |
| Coordinator Gas Overhead per Word | 435 |
## [OP](https://docs.chain.link/vrf/v2-5/supported-networks\#op)
### [OP Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#op-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6](https://optimistic.etherscan.io/address/0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6 "0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6") |
| VRF Coordinator | [0x5FE58960F730153eb5A84a47C51BD4E58302E1c8](https://optimistic.etherscan.io/address/0x5FE58960F730153eb5A84a47C51BD4E58302E1c8 "0x5FE58960F730153eb5A84a47C51BD4E58302E1c8") |
| 2 gwei Key Hash | `0xa16a2316f92fa0abfd0029eea74e947d0613728e934d9794cd78bc02e2f69de4` |
| 30 gwei Key Hash | `0x8e7a847ba0757d1c302a3f0fde7b868ef8cf4acc32e48505f1a1d53693a10a19` |
| Premium percentage
(paying with OP Mainnet) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6](https://optimistic.etherscan.io/address/0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6 "0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6") |
| VRF Wrapper | [0x6A39cE9604FAD060B32bc35BE2e0D3825B2b8D4B](https://optimistic.etherscan.io/address/0x6A39cE9604FAD060B32bc35BE2e0D3825B2b8D4B "0x6A39cE9604FAD060B32bc35BE2e0D3825B2b8D4B") |
| VRF Coordinator | [0x5FE58960F730153eb5A84a47C51BD4E58302E1c8](https://optimistic.etherscan.io/address/0x5FE58960F730153eb5A84a47C51BD4E58302E1c8 "0x5FE58960F730153eb5A84a47C51BD4E58302E1c8") |
| 2 gwei Key Hash | `0xa16a2316f92fa0abfd0029eea74e947d0613728e934d9794cd78bc02e2f69de4` |
| 30 gwei Key Hash | `0x8e7a847ba0757d1c302a3f0fde7b868ef8cf4acc32e48505f1a1d53693a10a19` |
| Premium percentage
(paying with OP Mainnet) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
### [OP Sepolia Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#op-sepolia-testnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia-optimism.etherscan.io/token/0xE4aB69C077896252FAFBD49EFD26B5D171A32410 "0xE4aB69C077896252FAFBD49EFD26B5D171A32410") |
| VRF Coordinator | [0x02667f44a6a44E4BDddCF80e724512Ad3426B17d](https://sepolia-optimism.etherscan.io/address/0x02667f44a6a44E4BDddCF80e724512Ad3426B17d "0x02667f44a6a44E4BDddCF80e724512Ad3426B17d") |
| 30 gwei Key Hash | `0xc3d5bc4d5600fa71f7a50b9ad841f14f24f9ca4236fd00bdb5fda56b052b28a4` |
| Premium percentage
(paying with OP Sepolia ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia-optimism.etherscan.io/token/0xE4aB69C077896252FAFBD49EFD26B5D171A32410 "0xE4aB69C077896252FAFBD49EFD26B5D171A32410") |
| VRF Wrapper | [0xA8A278BF534BCa72eFd6e6C9ac573E98c21A6171](https://sepolia-optimism.etherscan.io/address/0xA8A278BF534BCa72eFd6e6C9ac573E98c21A6171 "0xA8A278BF534BCa72eFd6e6C9ac573E98c21A6171") |
| VRF Coordinator | [0x02667f44a6a44E4BDddCF80e724512Ad3426B17d](https://sepolia-optimism.etherscan.io/address/0x02667f44a6a44E4BDddCF80e724512Ad3426B17d "0x02667f44a6a44E4BDddCF80e724512Ad3426B17d") |
| 30 gwei Key Hash | `0xc3d5bc4d5600fa71f7a50b9ad841f14f24f9ca4236fd00bdb5fda56b052b28a4` |
| Premium percentage
(paying with OP Sepolia ETH) | 60 |
| Premium percentage
(paying with testnet LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
## [Polygon](https://docs.chain.link/vrf/v2-5/supported-networks\#polygon)
### [Polygon Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#polygon-mainnet)
The LINK provided by the [Polygon Bridge](https://wallet.polygon.technology/polygon/bridge) is not ERC-677 compatible,
so cannot be used with Chainlink oracles. However, it can be [**converted to the official LINK token on Polygon using**\\
**Chainlink's PegSwap service**](https://pegswap.chain.link/)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1 "0xb0897686c545045aFc77CF20eC7A532E3120E0F1") |
| VRF Coordinator | [0xec0Ed46f36576541C75739E915ADbCb3DE24bD77](https://polygonscan.com/address/0xec0Ed46f36576541C75739E915ADbCb3DE24bD77 "0xec0Ed46f36576541C75739E915ADbCb3DE24bD77") |
| 200 gwei Key Hash | `0x0ffbbd0c1c18c0263dd778dadd1d64240d7bc338d95fec1cf0473928ca7eaf9e` |
| 500 gwei Key Hash | `0x719ed7d7664abc3001c18aac8130a2265e1e70b7e036ae20f3ca8b92b3154d86` |
| 1000 gwei Key Hash | `0x192234a5cda4cc07c0b66dfbcfbb785341cc790edc50032e842667dbb506cada` |
| Premium percentage
(paying with POL) | 84 |
| Premium percentage
(paying with LINK) | 70 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1 "0xb0897686c545045aFc77CF20eC7A532E3120E0F1") |
| VRF Wrapper | [0xc8F13422c49909F4Ec24BF65EDFBEbe410BB9D7c](https://polygonscan.com/address/0xc8F13422c49909F4Ec24BF65EDFBEbe410BB9D7c "0xc8F13422c49909F4Ec24BF65EDFBEbe410BB9D7c") |
| VRF Coordinator | [0xec0Ed46f36576541C75739E915ADbCb3DE24bD77](https://polygonscan.com/address/0xec0Ed46f36576541C75739E915ADbCb3DE24bD77 "0xec0Ed46f36576541C75739E915ADbCb3DE24bD77") |
| 200 gwei Key Hash | `0x0ffbbd0c1c18c0263dd778dadd1d64240d7bc338d95fec1cf0473928ca7eaf9e` |
| 500 gwei Key Hash | `0x719ed7d7664abc3001c18aac8130a2265e1e70b7e036ae20f3ca8b92b3154d86` |
| 1000 gwei Key Hash | `0x192234a5cda4cc07c0b66dfbcfbb785341cc790edc50032e842667dbb506cada` |
| Premium percentage
(paying with POL) | 84 |
| Premium percentage
(paying with LINK) | 70 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
### [Polygon Amoy Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#polygon-amoy-testnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904 "0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904") |
| VRF Coordinator | [0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2](https://amoy.polygonscan.com/address/0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2 "0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2") |
| 500 gwei Key Hash | `0x816bedba8a50b294e5cbd47842baf240c2385f2eaf719edbd4f250a137a8c899` |
| Premium percentage
(paying with testnet POL) | 84 |
| Premium percentage
(paying with testnet LINK) | 70 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904 "0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904") |
| VRF Wrapper | [0x6e6c366a1cd1F92ba87Fd6f96F743B0e6c967Bf0](https://amoy.polygonscan.com/address/0x6e6c366a1cd1F92ba87Fd6f96F743B0e6c967Bf0 "0x6e6c366a1cd1F92ba87Fd6f96F743B0e6c967Bf0") |
| VRF Coordinator | [0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2](https://amoy.polygonscan.com/address/0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2 "0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2") |
| 500 gwei Key Hash | `0x816bedba8a50b294e5cbd47842baf240c2385f2eaf719edbd4f250a137a8c899` |
| Premium percentage
(paying with testnet POL) | 84 |
| Premium percentage
(paying with testnet LINK) | 70 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
## [Ronin](https://docs.chain.link/vrf/v2-5/supported-networks\#ronin)
### [Ronin Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#ronin-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b](https://app.roninchain.com/address/0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b "0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b") |
| VRF Coordinator | [0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda](https://app.roninchain.com/address/0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda "0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda") |
| 50 gwei Key Hash | `0x1aefc70f3533a251306d6b85a6b336ba0ae2e384226274b236f42c3d5366dbbd` |
| 200 gwei Key Hash | `0x01753ec79fbf37f6332977d62f25c6d701b11bac255d7e79674fd2886622b0cc` |
| 1000 gwei Key Hash | `0xdb64d2a17ee501f6c6a8c090e058dfa39ea79d5fd121185bb903f5a69b8038a3` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b](https://app.roninchain.com/address/0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b "0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b") |
| VRF Wrapper | [0x3B7d0d0CeC08eBF8dad58aCCa4719791378b2329](https://app.roninchain.com/address/0x3B7d0d0CeC08eBF8dad58aCCa4719791378b2329 "0x3B7d0d0CeC08eBF8dad58aCCa4719791378b2329") |
| VRF Coordinator | [0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda](https://app.roninchain.com/address/0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda "0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda") |
| 50 gwei Key Hash | `0x1aefc70f3533a251306d6b85a6b336ba0ae2e384226274b236f42c3d5366dbbd` |
| 200 gwei Key Hash | `0x01753ec79fbf37f6332977d62f25c6d701b11bac255d7e79674fd2886622b0cc` |
| 1000 gwei Key Hash | `0xdb64d2a17ee501f6c6a8c090e058dfa39ea79d5fd121185bb903f5a69b8038a3` |
| Premium percentage
(paying with ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
### [Ronin Saigon Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#ronin-saigon-testnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15](https://saigon-app.roninchain.com/address/0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15 "0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15") |
| VRF Coordinator | [0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8](https://saigon-app.roninchain.com/address/0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8 "0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8") |
| 200 gwei Key Hash | `0x0a79a60cc054d8da06a5050a1d07f0fec08088ca64192cf67477f8cc3e549f71` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15](https://saigon-app.roninchain.com/address/0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15 "0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15") |
| VRF Wrapper | [0x4664273cf5Eb350c864c2F37F63b045a883F93C6](https://saigon-app.roninchain.com/address/0x4664273cf5Eb350c864c2F37F63b045a883F93C6 "0x4664273cf5Eb350c864c2F37F63b045a883F93C6") |
| VRF Coordinator | [0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8](https://saigon-app.roninchain.com/address/0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8 "0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8") |
| 200 gwei Key Hash | `0x0a79a60cc054d8da06a5050a1d07f0fec08088ca64192cf67477f8cc3e549f71` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 99500 |
| Coordinator Gas Overhead (LINK) | 121500 |
| Coordinator Gas Overhead per Word | 435 |
## [Soneium](https://docs.chain.link/vrf/v2-5/supported-networks\#soneium)
### [Soneium Mainnet](https://docs.chain.link/vrf/v2-5/supported-networks\#soneium-mainnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec](https://soneium.blockscout.com/address/0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec "0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec") |
| VRF Coordinator | [0xb89BB0aB64b219Ba7702f862020d879786a2BC49](https://soneium.blockscout.com/address/0xb89BB0aB64b219Ba7702f862020d879786a2BC49 "0xb89BB0aB64b219Ba7702f862020d879786a2BC49") |
| 2 gwei Key Hash | `0x508b86c17b9abbdef2b903bd4f1b03ae321d7c1431b9ccac97d5927b4619e050` |
| 30 gwei Key Hash | `0x7611210a5ac0abd39b581bd4ce1108aa0b9e63994daa32cc7302d98ed47747c1` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec](https://soneium.blockscout.com/address/0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec "0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec") |
| VRF Wrapper | [0x656155C8bD09d1741385C525010590522758345c](https://soneium.blockscout.com/address/0x656155C8bD09d1741385C525010590522758345c "0x656155C8bD09d1741385C525010590522758345c") |
| VRF Coordinator | [0xb89BB0aB64b219Ba7702f862020d879786a2BC49](https://soneium.blockscout.com/address/0xb89BB0aB64b219Ba7702f862020d879786a2BC49 "0xb89BB0aB64b219Ba7702f862020d879786a2BC49") |
| 2 gwei Key Hash | `0x508b86c17b9abbdef2b903bd4f1b03ae321d7c1431b9ccac97d5927b4619e050` |
| 30 gwei Key Hash | `0x7611210a5ac0abd39b581bd4ce1108aa0b9e63994daa32cc7302d98ed47747c1` |
| Premium percentage
(paying with ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
### [Soneium Minato Testnet](https://docs.chain.link/vrf/v2-5/supported-networks\#soneium-minato-testnet)
SubscriptionDirect funding
| Item | Value |
| --- | --- |
| LINK Token | [0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2](https://soneium-minato.blockscout.com/address/0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2 "0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2") |
| VRF Coordinator | [0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47](https://soneium-minato.blockscout.com/address/0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47 "0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47") |
| 30 gwei Key Hash | `0x0c970a50393bea0011d5cec18c15c80c6deb37888b9ff579f476b3e52f6d3922` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
| Item | Value |
| --- | --- |
| LINK Token | [0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2](https://soneium-minato.blockscout.com/address/0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2 "0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2") |
| VRF Wrapper | [0xB64019F234f2A4951261B111C6B43eb0d8f33b76](https://soneium-minato.blockscout.com/address/0xB64019F234f2A4951261B111C6B43eb0d8f33b76 "0xB64019F234f2A4951261B111C6B43eb0d8f33b76") |
| VRF Coordinator | [0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47](https://soneium-minato.blockscout.com/address/0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47 "0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47") |
| 30 gwei Key Hash | `0x0c970a50393bea0011d5cec18c15c80c6deb37888b9ff579f476b3e52f6d3922` |
| Premium percentage
(paying with testnet ETH) | 60 |
| Premium percentage
(paying with LINK) | 50 |
| Minimum Confirmations | 0 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 13400 |
| Coordinator Gas Overhead (Native) | 128500 |
| Coordinator Gas Overhead (LINK) | 150400 |
| Coordinator Gas Overhead per Word | 435 |
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Supported Networks
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Supported Networks - Subscription Method](https://docs.chain.link/vrf/v2/subscription/supported-networks\#overview)
Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract.
For implementation details, read [Introduction to Chainlink VRF](https://docs.chain.link/vrf).
## [Coordinator parameters](https://docs.chain.link/vrf/v2/subscription/supported-networks\#coordinator-parameters)
These parameters are configured in the coordinator contract. You can view these values by running `getConfig` on the coordinator or by viewing the coordinator contracts in a blockchain explorer.
- `uint16 minimumRequestConfirmations`: The minimum number of confirmation blocks on VRF requests before oracles respond
- `uint32 maxGasLimit`: The maximum gas limit supported for a `fulfillRandomWords` callback.
- `uint32 stalenessSeconds`: How long the coordinator waits until we consider the ETH/LINK price used for converting gas costs to LINK is stale and use `fallbackWeiPerUnitLink`
- `uint32 gasAfterPaymentCalculation`: How much gas is used outside of the payment calculation. This covers the additional operations required to decrement the subscription balance and increment the balance for the oracle that handled the request.
## [Fee parameters](https://docs.chain.link/vrf/v2/subscription/supported-networks\#fee-parameters)
Fee parameters are configured in the coordinator contract and specify the premium you pay per request in addition to the gas cost for the transaction. You can view them by running `getFeeConfig` on the coordinator. The `uint32 fulfillmentFlatFeeLinkPPMTier1` parameter defines the fees per request specified in millionths of LINK.
The details for calculating the total transaction cost can be found [here](https://docs.chain.link/vrf/v2/subscription/#request-and-receive-data).
## [Configurations](https://docs.chain.link/vrf/v2/subscription/supported-networks\#configurations)
VRF v2 coordinators for subscription funding are available on several networks. To see a list of coordinators for direct funding, see the [Direct Funding Configurations](https://docs.chain.link/vrf/v2/direct-funding/supported-networks) page.
To use Chainlink VRF on certain networks, you may need to conduct token transfers. You can transfer tokens by using [Chainlink CCIP](https://docs.chain.link/ccip/tutorials/evm/transfer-tokens-from-contract), [Transporter](https://www.transporter.io/) or third-party applications such as [XSwap](https://xswap.link/).
### [Ethereum mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#ethereum-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA "0x514910771AF9Ca656af840dff83E8264EcF986CA") |
| VRF Coordinator | [0x271682DEB8C4E0901D1a1550aD2e64D568E69909](https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909 "0x271682DEB8C4E0901D1a1550aD2e64D568E69909") |
| 200 gwei Key Hash | `0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef` |
| 500 gwei Key Hash | `0xff8dedfbfa60af186cf3c830acbc32c05aae823045ae5ea7da1e45fbfaba4f92` |
| 1000 gwei Key Hash | `0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805` |
| Premium | 0.25 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Sepolia testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#sepolia-testnet)
Testnet LINK and ETH are available from [faucets.chain.link](https://faucets.chain.link/sepolia).
Testnet ETH is also available from several public [ETH faucets](https://faucetlink.to/sepolia).
| Item | Value |
| --- | --- |
| LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789 "0x779877A7B0D9E8603169DdbD7836e478b4624789") |
| VRF Coordinator | [0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625](https://sepolia.etherscan.io/address/0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625 "0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625") |
| 750 gwei Key Hash | `0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c` |
| Premium | 0.25 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [BNB Chain mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#bnb-chain-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75 "0x404460C6A5EdE2D891e8297795264fDe62ADBB75") |
| VRF Coordinator | [0xc587d9053cd1118f25F645F9E08BB98c9712A4EE](https://bscscan.com/address/0xc587d9053cd1118f25F645F9E08BB98c9712A4EE "0xc587d9053cd1118f25F645F9E08BB98c9712A4EE") |
| 200 gwei Key Hash | `0x114f3da0a805b6a67d6e9cd2ec746f7028f1b7376365af575cfea3550dd1aa04` |
| 500 gwei Key Hash | `0xba6e730de88d94a5510ae6613898bfb0c3de5d16e609c5b7da808747125506f7` |
| 1000 gwei Key Hash | `0x17cd473250a9a479dc7f234c64332ed4bc8af9e8ded7556aa6e66d83da49f470` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [BNB Chain testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#bnb-chain-testnet)
Testnet LINK is available from [https://faucets.chain.link/bnb-chain-testnet](https://faucets.chain.link/bnb-chain-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06](https://testnet.bscscan.com/address/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06") |
| VRF Coordinator | [0x6A2AAd07396B36Fe02a22b33cf443582f682c82f](https://testnet.bscscan.com/address/0x6A2AAd07396B36Fe02a22b33cf443582f682c82f "0x6A2AAd07396B36Fe02a22b33cf443582f682c82f") |
| 50 gwei Key Hash | `0xd4bb89654db74673a187bd804519e65e3f71a52bc55f11da7601a13dcf505314` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Polygon mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#polygon-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1 "0xb0897686c545045aFc77CF20eC7A532E3120E0F1") |
| VRF Coordinator | [0xAE975071Be8F8eE67addBC1A82488F1C24858067](https://polygonscan.com/address/0xAE975071Be8F8eE67addBC1A82488F1C24858067 "0xAE975071Be8F8eE67addBC1A82488F1C24858067") |
| 200 gwei Key Hash | `0x6e099d640cde6de9d40ac749b4b594126b0169747122711109c9985d47751f93` |
| 500 gwei Key Hash | `0xcc294a196eeeb44da2888d17c0625cc88d70d9760a69d58d853ba6581a9ab0cd` |
| 1000 gwei Key Hash | `0xd729dc84e21ae57ffb6be0053bf2b0668aa2aaf300a2a7b2ddf7dc0bb6e875a8` |
| Premium | 0.0005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Polygon Amoy testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#polygon-amoy-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904 "0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904") |
| VRF Coordinator | [0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908](https://amoy.polygonscan.com/address/0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908 "0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908") |
| 500 gwei Key Hash | `0x3f631d5ec60a0ce16203bcd6aff7ffbc423e22e452786288e172d467354304c8` |
| Premium | 0.0005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Avalanche mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#avalanche-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3 "0x5947BB275c521040051D82396192181b413227A3") |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://snowtrace.io/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| 200 gwei Key Hash | `0x83250c5584ffa93feb6ee082981c5ebe484c865196750b39835ad4f13780435d` |
| 500 gwei Key Hash | `0x89630569c9567e43c4fe7b1633258df9f2531b62f2352fa721cf3162ee4ecb46` |
| 1000 gwei Key Hash | `0x06eb0e2ea7cca202fc7c8258397a36f33d88568d2522b37aaa3b14ff6ee1b696` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Avalanche Fuji testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#avalanche-fuji-testnet)
Testnet LINK is available from [https://faucets.chain.link/fuji](https://faucets.chain.link/fuji)
| Item | Value |
| --- | --- |
| LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846 "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846") |
| | |
| VRF Coordinator | [0x2eD832Ba664535e5886b75D64C46EB9a228C2610](https://testnet.snowtrace.io/address/0x2eD832Ba664535e5886b75D64C46EB9a228C2610 "0x2eD832Ba664535e5886b75D64C46EB9a228C2610") |
| 300 gwei Key Hash | `0x354d2f95da55398f44b7cff77da56283d9c6c829a4bdf1bbcaf2ad6a4d081f61` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Fantom mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#fantom-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x6F43FF82CCA38001B6699a8AC47A2d0E66939407](https://ftmscan.com/token/0x6F43FF82CCA38001B6699a8AC47A2d0E66939407 "0x6F43FF82CCA38001B6699a8AC47A2d0E66939407") |
| | |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://ftmscan.com/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| 4000 gwei Key Hash | `0xb4797e686f9a1548b9a2e8c68988d74788e0c4af5899020fb0c47784af76ddfa` |
| 10000 gwei Key Hash | `0x5881eea62f9876043df723cf89f0c2bb6f950da25e9dfe66995c24f919c8f8ab` |
| 20000 gwei Key Hash | `0x64ae04e5dba58bc08ba2d53eb33fe95bf71f5002789692fe78fb3778f16121c9` |
| Premium | 0.0005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Fantom testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#fantom-testnet)
Testnet LINK is available from [https://faucets.chain.link/fantom-testnet](https://faucets.chain.link/fantom-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F](https://testnet.ftmscan.com/address/0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F "0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F") |
| | |
| VRF Coordinator | [0xbd13f08b8352A3635218ab9418E340c60d6Eb418](https://testnet.ftmscan.com/address/0xbd13f08b8352A3635218ab9418E340c60d6Eb418 "0xbd13f08b8352A3635218ab9418E340c60d6Eb418") |
| 3000 gwei Key Hash | `0x121a143066e0f2f08b620784af77cccb35c6242460b4a8ee251b4b416abaebd4` |
| Premium | 0.0005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Arbitrum mainnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#arbitrum-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4 "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4") |
| | |
| VRF Coordinator | [0x41034678D6C633D8a95c75e1138A360a28bA15d1](https://arbiscan.io/address/0x41034678D6C633D8a95c75e1138A360a28bA15d1 "0x41034678D6C633D8a95c75e1138A360a28bA15d1") |
| 2 gwei Key Hash | `0x08ba8f62ff6c40a58877a106147661db43bc58dabfb814793847a839aa03367f` |
| 30 gwei Key Hash | `0x72d2b016bb5b62912afea355ebf33b91319f828738b111b723b78696b9847b63` |
| 150 gwei Key Hash | `0x68d24f9a037a649944964c2a1ebd0b2918f4a243d2a99701cc22b548cf2daff0` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
### [Arbitrum Sepolia testnet](https://docs.chain.link/vrf/v2/subscription/supported-networks\#arbitrum-sepolia-testnet)
Testnet LINK is available from [https://faucets.chain.link/arbitrum-sepolia](https://faucets.chain.link/arbitrum-sepolia)
| Item | Value |
| --- | --- |
| LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E") |
| | |
| VRF Coordinator | [0x50d47e4142598E3411aA864e08a44284e471AC6f](https://sepolia.arbiscan.io/address/0x50d47e4142598E3411aA864e08a44284e471AC6f "0x50d47e4142598E3411aA864e08a44284e471AC6f") |
| 50 gwei Key Hash | ` 0x027f94ff1465b3525f9fc03e9ff7d6d2c0953482246dd6ae07570c45d6631414` |
| Premium | 0.005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 500 |
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Guide
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
On this page
# [Getting Started with Chainlink VRF V2.5](https://docs.chain.link/vrf/v2-5/getting-started\#overview)
In this guide, you will learn about generating randomness on blockchains. This includes learning how to implement a Request and Receive cycle with Chainlink oracles and how to consume random numbers with Chainlink VRF in smart contracts.
## [How is randomness generated on blockchains? What is Chainlink VRF?](https://docs.chain.link/vrf/v2-5/getting-started\#how-is-randomness-generated-on-blockchains-what-is-chainlink-vrf)
Randomness is very difficult to generate on blockchains. This is because every node on the blockchain must come to the same conclusion and form a consensus. Even though random numbers are versatile and useful in a variety of blockchain applications, they cannot be generated natively in smart contracts. The solution to this issue is [**Chainlink VRF**](https://docs.chain.link/vrf), also known as Chainlink Verifiable Random Function.
## [What is the Request and Receive cycle?](https://docs.chain.link/vrf/v2-5/getting-started\#what-is-the-request-and-receive-cycle)
The [Data Feeds Getting Started](https://docs.chain.link/data-feeds/getting-started) guide explains how to consume Chainlink Data Feeds, which consist of reference data posted onchain by oracles. This data is stored in a contract and can be referenced by consumers until the oracle updates the data again.
Randomness, on the other hand, cannot be reference data. If the result of randomness is stored onchain, any actor could retrieve the value and predict the outcome. Instead, randomness must be requested from an oracle, which generates a number and a cryptographic proof. Then, the oracle returns that result to the contract that requested it. This sequence is known as the **[Request and Receive cycle](https://docs.chain.link/architecture-overview/architecture-request-model)**.
## [What is the payment process for generating a random number?](https://docs.chain.link/vrf/v2-5/getting-started\#what-is-the-payment-process-for-generating-a-random-number)
VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link/) lets you create an account and pre-pay for VRF requests, so that funding of all your application requests are managed in a single location.
To learn more about VRF requests funding, see [Subscription limits](https://docs.chain.link/vrf/v2-5/overview/subscription#subscription-limits).
## [How can I use Chainlink VRF?](https://docs.chain.link/vrf/v2-5/getting-started\#how-can-i-use-chainlink-vrf)
In this section, you will create an application that uses Chainlink VRF to generate randomness. The contract used in this application has a [_Game of Thrones_](https://en.wikipedia.org/wiki/Game_of_Thrones) theme.
After the contract requests randomness from Chainlink VRF, the result of the randomness will transform into a number between 1 and 20, mimicking the rolling of a 20 sided die. Each number represents a _Game of Thrones_ house. If the dice land on the value 1, the user is assigned house Targaryan, 2 for Lannister, and so on. A full list of houses can be found [here](https://gameofthrones.fandom.com/wiki/Great_House).
When rolling the dice, it uses an `address` variable to track which address is assigned to each house.
The contract has the following functions:
- `rollDice`: This submits a randomness request to Chainlink VRF
- `fulfillRandomWords`: The function that the Oracle uses to send the result back
- `house`: To see the assigned house of an address
**Note**: to jump straight to the entire implementation, you can [open the VRFD20.sol contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/VRFD20.sol) in Remix.
### [Create and fund a subscription](https://docs.chain.link/vrf/v2-5/getting-started\#create-and-fund-a-subscription)
Chainlink VRF requests receive funding from subscription accounts. The [Subscription Manager](https://vrf.chain.link/) lets you create an account and pre-pay your use of Chainlink VRF requests.
For this example, create a new subscription on the Sepolia testnet as explained [here](https://docs.chain.link/vrf/v2-5/subscription/create-manage).
Your subscription has two balances - one for LINK and one for the native token you're using (in this case, Sepolia ETH). You can choose to pay for VRF requests using either balance.
### [Importing contracts](https://docs.chain.link/vrf/v2-5/getting-started\#importing-contracts)
Chainlink maintains a [library of contracts](https://github.com/smartcontractkit/chainlink/tree/contracts-v1.3.0/contracts) that make consuming data from oracles easier. For Chainlink VRF, you will use:
- [`VRFConsumerBaseV2Plus`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol) that must be imported and extended from the contract that you create.
- [`VRFV2PlusClient`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol) to format your requests to VRF.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
contract VRFD20 is VRFConsumerBaseV2Plus {
}
```
### [Contract variables](https://docs.chain.link/vrf/v2-5/getting-started\#contract-variables)
This example is adapted for [Sepolia testnet](https://docs.chain.link/vrf/v2-5/supported-networks#ethereum-sepolia-testnet) but you can change the configuration and make it run for any [supported network](https://docs.chain.link/vrf/v2-5/supported-networks).

```solidity
uint256 s_subscriptionId;
address vrfCoordinator = 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B;
bytes32 s_keyHash = 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
uint32 callbackGasLimit = 40000;
uint16 requestConfirmations = 3;
uint32 numWords = 1;
```
- `uint256 s_subscriptionId`: The subscription ID that this contract uses for funding requests. Initialized in the `constructor`.
- `address vrfCoordinator`: The address of the Chainlink VRF Coordinator contract.
- `bytes32 s_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 offchain 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` on the coordinator contract. 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` value on the coordinator contract. For Sepolia, the `minimumRequestBlockConfirmations` value is 3. You can check this and the other configuration values on the coordinator contract by querying [the `s_config` value in the Sepolia Etherscan block explorer](https://sepolia.etherscan.io/address/0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B#readContract#F12).
- `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. In this example, each transaction requests one random value.
To keep track of addresses that roll the dice, the contract uses mappings. [Mappings](https://medium.com/upstate-interactive/mappings-in-solidity-explained-in-under-two-minutes-ecba88aff96e) are unique key-value pair data structures similar to hash tables in Java.

```solidity
mapping(uint256 => address) private s_rollers;
mapping(address => uint256) private s_results;
```
- `s_rollers` stores a mapping between the `requestID` (returned when a request is made), and the address of the roller. This is so the contract can keep track of who to assign the result to when it comes back.
- `s_results` stores the roller and the result of the dice roll.
### [Initializing the contract](https://docs.chain.link/vrf/v2-5/getting-started\#initializing-the-contract)
The subscription ID must be initialized in the `constructor` of the contract. To use `VRFConsumerBaseV2Plus` properly, you must also pass the VRF coordinator address into its constructor.
The address that creates the smart contract is the owner of the contract.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
contract VRFD20 is VRFConsumerBaseV2Plus {
// variables
// ...
// constructor
constructor(uint256 subscriptionId) VRFConsumerBaseV2Plus(vrfCoordinator) {
s_subscriptionId = subscriptionId;
}
...
}
```
### [`rollDice` function](https://docs.chain.link/vrf/v2-5/getting-started\#rolldice-function)
The `rollDice` function will complete the following tasks:
1. Check if the roller has already rolled since each roller can only ever be assigned to a single house.
2. Request randomness by calling the VRF coordinator.
3. Store the `requestId` and roller address.
4. Emit an event to signal that the dice is rolling.
You must add a `ROLL_IN_PROGRESS` constant to signify that the dice has been rolled but the result is not yet returned. Also add a `DiceRolled` event to the contract.
Only the owner of the contract can execute the `rollDice` function.
This `rollDice` function is configured so that you pay for VRF requests using LINK by default. If you want to pay for your VRF request with Sepolia ETH instead, set `nativePayment` to `true`.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
contract VRFD20 is VRFConsumerBaseV2Plus {
// variables
uint256 private constant ROLL_IN_PROGRESS = 42;
// ...
// events
event DiceRolled(uint256 indexed requestId, address indexed roller);
// ...
// ...
// { constructor }
// ...
// rollDice function
function rollDice(address roller) public onlyOwner returns (uint256 requestId) {
require(s_results[roller] == 0, "Already rolled");
// Will revert if subscription is not set and funded.
requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: s_keyHash,
subId: s_subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
// Set nativePayment to true to pay for VRF requests with Sepolia ETH instead of LINK
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}))
})
);
s_rollers[requestId] = roller;
s_results[roller] = ROLL_IN_PROGRESS;
emit DiceRolled(requestId, roller);
}
}
```
### [`fulfillRandomWords` function](https://docs.chain.link/vrf/v2-5/getting-started\#fulfillrandomwords-function)
`fulfillRandomWords` is a special function defined within the `VRFConsumerBaseV2Plus` contract that our contract extends from. The coordinator sends the result of our generated `randomWords` back to `fulfillRandomWords`. You will implement some functionality here to deal with the result:
1. Change the result to a number between 1 and 20 inclusively. Note that `randomWords` is an array that could contain several random values. In this example, request 1 random value.
2. Assign the transformed value to the address in the `s_results` mapping variable.
3. Emit a `DiceLanded` event.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
contract VRFD20 is VRFConsumerBaseV2Plus {
// ...
// { variables }
// ...
// events
// ...
event DiceLanded(uint256 indexed requestId, uint256 indexed result);
// ...
// { constructor }
// ...
// ...
// { rollDice function }
// ...
// fulfillRandomWords function
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
// transform the result to a number between 1 and 20 inclusively
uint256 d20Value = (randomWords[0] % 20) + 1;
// assign the transformed value to the address in the s_results mapping variable
s_results[s_rollers[requestId]] = d20Value;
// emitting event to signal that dice landed
emit DiceLanded(requestId, d20Value);
}
}
```
### [`house` function](https://docs.chain.link/vrf/v2-5/getting-started\#house-function)
Finally, the `house` function returns the house of an address.
To have a list of the house's names, create the `getHouseName` function that is called in the `house` function.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
contract VRFD20 is VRFConsumerBaseV2Plus {
// ...
// { variables }
// ...
// ...
// { events }
// ...
// ...
// { constructor }
// ...
// ...
// { rollDice function }
// ...
// ...
// { fulfillRandomWords function }
// ...
// house function
function house(address player) public view returns (string memory) {
// dice has not yet been rolled to this address
require(s_results[player] != 0, "Dice not rolled");
// not waiting for the result of a thrown dice
require(s_results[player] != ROLL_IN_PROGRESS, "Roll in progress");
// returns the house name from the name list function
return getHouseName(s_results[player]);
}
// getHouseName function
function getHouseName(uint256 id) private pure returns (string memory) {
// array storing the list of house's names
string[20] memory houseNames = [\
"Targaryen",\
"Lannister",\
"Stark",\
"Tyrell",\
"Baratheon",\
"Martell",\
"Tully",\
"Bolton",\
"Greyjoy",\
"Arryn",\
"Frey",\
"Mormont",\
"Tarley",\
"Dayne",\
"Umber",\
"Valeryon",\
"Manderly",\
"Clegane",\
"Glover",\
"Karstark"\
];
// returns the house name given an index
return houseNames[id - 1];
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/VRFD20.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
You have now completed all necessary functions to generate randomness and assign the user a _Game of Thrones_ house. We've added a few helper functions in there to make using the contract easier and more flexible. You can deploy and interact with the complete contract in Remix.
## [How do I deploy to testnet?](https://docs.chain.link/vrf/v2-5/getting-started\#how-do-i-deploy-to-testnet)
You will deploy this contract on the Sepolia test network. You must have some Sepolia testnet ETH in your MetaMask account to pay for the gas for each contract interaction with the Sepolia network.
You can choose to pay for your VRF requests in either Sepolia ETH or testnet LINK. The `rollDice` function is written to use LINK by default. If you want to change to using Sepolia, set `nativePayment` to `true` before deploying your contract.
You can request both testnet LINK and testnet ETH from [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia). Testnet ETH is also available from several [public faucets](https://faucetlink.to/sepolia).
This deployment is slightly different than the example in the [Deploy Your First Contract](https://docs.chain.link/quickstarts/deploy-your-first-contract) guide. In this case, you pass in parameters to the constructor upon deployment.
Once compiled, you'll see a dropdown menu that looks like this in the deploy pane:

Select the `VRFD20` contract or the name that you gave to your contract.
Click the caret arrow on the right hand side of **Deploy** to expand the parameter fields, and paste your subscription ID.

Then click the `Deploy` button and use your MetaMask account to confirm the transaction.
At this point, your contract should be successfully deployed. However, it can't request anything because it is not yet approved to use the LINK or Sepolia ETH balance in your subscription. If you click `rollDice`, the transaction will revert.
## [How do I add my contract to my subscription account?](https://docs.chain.link/vrf/v2-5/getting-started\#how-do-i-add-my-contract-to-my-subscription-account)
After you deploy your contract, you must add it as an approved consumer contract so it can use the subscription balance when requesting for randomness.
1. Find your contract address in Remix under **Deployed Contracts** on the bottom left, and copy the contract address:

2. Go to the [Subscription Manager](https://vrf.chain.link/), open the details page for your subscription, and add your deployed contract address to the list of consumers:

## [How do I test `rollDice`?](https://docs.chain.link/vrf/v2-5/getting-started\#how-do-i-test-rolldice)
After you open the deployed contract tab in the bottom left, the function buttons are available. Find `rollDice` and click the caret to expand the parameter fields. Enter an Ethereum address to specify a "dice roller", and click `rollDice`.
It takes a few minutes for the transaction to confirm and the response to be sent back. You can get your house by clicking the `house` function button with the address passed in `rollDice`. After the response is sent back, you'll be assigned a _Game of Thrones_ house!
## [Further reading](https://docs.chain.link/vrf/v2-5/getting-started\#further-reading)
To read more about generating random numbers in Solidity, read our blog posts:
- [35+ Blockchain RNG Use Cases Enabled by Chainlink VRF](https://blog.chain.link/blockchain-rng-use-cases-enabled-by-chainlink-vrf/)
- [How to Build Dynamic NFTs on Polygon](https://blog.chain.link/how-to-build-dynamic-nfts-on-polygon/)
- [Scaling Onchain Verifiable Randomness With Chainlink VRF v2.5](https://blog.chain.link/introducing-vrf-v2-5/)
## What's next
- [\> Security Considerations](https://docs.chain.link/vrf/v2-5/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2-5/best-practices)
- [\> Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Subscription
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Subscription Method](https://docs.chain.link/vrf/v2-5/overview/subscription\#overview)
This section explains how to generate random numbers using the subscription method.
## [Subscriptions](https://docs.chain.link/vrf/v2-5/overview/subscription\#subscriptions)
VRF v2.5 requests receive funding from subscription accounts. Creating a VRF subscription lets you create an account and pre-pay for VRF v2.5, so you don't provide funding each time your application requests randomness. This reduces the total gas cost to use VRF v2.5. It also provides a simple way to fund your use of Chainlink products from a single location, so you don't have to manage multiple wallets across several different systems and applications.
Subscriptions have the following core concepts:
- **Subscription id:** 256-bit unsigned integer representing the unique identifier of the subscription.
- **Subscription accounts:** An account that holds LINK and native tokens and makes them available to fund requests to Chainlink VRF v2.5 coordinators.
- **Subscription owner:** The wallet address that creates and manages a subscription account. Any account can add LINK or native tokens to the subscription balance, but only the owner can add approved consuming contracts or withdraw funds.
- **Consumers:** Consuming contracts that are approved to use funding from your subscription account.
- **Subscription balance:** The amount of funds in LINK or native tokens maintained on your subscription account. Your subscription can maintain balances for both LINK and native tokens. Requests from consuming contracts will continue to be funded until the balance runs out, so be sure to maintain sufficient funds in your subscription balance to pay for the requests and keep your applications running.
For Chainlink VRF v2.5 to fulfill your requests, you must maintain a sufficient amount of LINK or native tokens in your subscription balance. Gas cost calculation includes the following variables:
- **Gas price:** The current gas price, which fluctuates depending on network conditions.
- **Callback gas:** The amount of gas used for the callback request that returns your requested random values.
- **Verification gas:** The amount of gas used to verify randomness onchain.
The gas price depends on current network conditions. The callback gas depends on your callback function, and the number of random values in your request. The cost of each request is final only after the transaction is complete, but you define the limits you are willing to spend for the request with the following variables:
- **Gas lane:** The maximum gas price you are willing to pay for a request in wei. Define this limit by specifying the appropriate `keyHash` in your request. The limits of each gas lane are important for handling gas price spikes when Chainlink VRF bumps the gas price to fulfill your request quickly.
- **Callback gas limit:** Specifies the maximum amount of gas you are willing to spend on the callback request. Define this limit by specifying the `callbackGasLimit` value in your request.
## [Request and receive data](https://docs.chain.link/vrf/v2-5/overview/subscription\#request-and-receive-data)
Requests to Chainlink VRF v2.5 follow the request and receive data cycle similarly to VRF V2. This end-to-end diagram shows each step in the lifecycle of a VRF subscription request, and registering a smart contract with a VRF subscription account:

VRF v2.5 uses both offchain and onchain components:
- [VRF v2.5 Coordinator (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
- VRF service (offchain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
### [Account types used in VRF](https://docs.chain.link/vrf/v2-5/overview/subscription\#account-types-used-in-vrf)
Two types of accounts exist in the Ethereum ecosystem, and both are used in VRF:
- Externally Owned Account (EOA): An externally owned account that has a private key and can control a smart contract. Transactions can only be initiated by EOAs.
- Smart contract: A contract that does not have a private key and executes what it has been designed for as a decentralized application.
While only EOAs can initiate transactions, do **not** attempt to use EOAs to send VRF requests directly. Instead, your EOA should interact with your consuming contract: the smart contract that is consuming the random values you request from VRF. Your EOA initiates the transaction, and then your consuming contract sends the VRF request.
### [Set up your contract and request](https://docs.chain.link/vrf/v2-5/overview/subscription\#set-up-your-contract-and-request)
Set up your consuming contract:
1. Your contract must inherit [VRFConsumerBaseV2Plus](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol).
2. Your contract must implement the `fulfillRandomWords` function, which is the _callback VRF function_. Here, you add logic to handle the random values after they are returned to your contract.
3. Submit your VRF request by calling `requestRandomWords` of the [VRF Coordinator](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol). Include the following parameters in your request:
- `keyHash`: Identifier that maps to a job and a private key on the VRF service and that represents a specified gas lane. If your request is urgent, specify a gas lane with a higher gas price limit. The configuration for your network can be found [here](https://docs.chain.link/vrf/v2-5/supported-networks).
- `s_subscriptionId`: The subscription ID that the consuming contract is registered to. LINK funds are deducted from this subscription.
- `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](https://docs.chain.link/vrf/v2-5/supported-networks).
- `callbackGasLimit`: The maximum amount of gas a user is willing to pay for completing the callback VRF function. Note that you cannot put a value larger than `maxGasLimit` of the VRF Coordinator contract (read [coordinator contract limits](https://docs.chain.link/vrf/v2-5/overview/subscription#limits) for more details).
- `numWords`: The number of random numbers to request. The maximum random values that can be requested for your network can be found [here](https://docs.chain.link/vrf/v2-5/supported-networks).
In VRF 2.5, the request format has changed:

```solidity
uint256 requestID = s_vrfCoordinator.requestRandomWords(VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: subId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) // new parameter
})
);
```
1. Add the `setCoordinator` method to your contract. This makes it easier to update your contract for future VRF releases by setting the new coordinator.
### [How VRF processes your request](https://docs.chain.link/vrf/v2-5/overview/subscription\#how-vrf-processes-your-request)
After you submit your request, it is processed using the [Request & Receive Data](https://docs.chain.link/vrf/v2-5/overview/subscription#request-and-receive-data) cycle. The VRF coordinator processes the request and determines the final charge to your subscription using the following steps:
1. The VRF coordinator emits an event.
2. The VRF service picks up the event and waits for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof ( `requestConfirmations`).
3. The VRF coordinator verifies the proof onchain, then it calls back the consuming contract `fulfillRandomWords` function.
## [Limits](https://docs.chain.link/vrf/v2-5/overview/subscription\#limits)
Chainlink VRF v2.5 has [subscription limits](https://docs.chain.link/vrf/v2-5/overview/subscription#subscription-limits) and [coordinator contract limits](https://docs.chain.link/vrf/v2-5/overview/subscription#coordinator-contract-limits).
### [Subscription limits](https://docs.chain.link/vrf/v2-5/overview/subscription\#subscription-limits)
Subscriptions are required to maintain a minimum balance, and they can support a limited number of consuming contracts.
#### [Minimum subscription balance](https://docs.chain.link/vrf/v2-5/overview/subscription\#minimum-subscription-balance)
Each subscription must maintain a minimum balance to fund requests from consuming contracts. This minimum balance requirement serves as a buffer against gas volatility by ensuring that all your requests have more than enough funding to go through. If your balance is below the minimum, your requests remain pending for up to 24 hours before they expire. After you add sufficient LINK or native tokens to a subscription, pending requests automatically process as long as they have not expired.
In the Subscription Manager, the minimum subscription balance is displayed as the **Max Cost**, and it indicates the amount of LINK or native tokens you need to add for a pending request to process. After the request is processed, only the amount actually consumed by the request is deducted from your balance. For example, if you are paying for your VRF requests in LINK and your minimum balance is 10 LINK, but your subscription balance is 5 LINK, you need to add at least 5 more LINK for your request to process. This does not mean that your request will ultimately cost 10 LINK. If the request ultimately costs 3 LINK after it has processed, then 3 LINK is deducted from your subscription balance. The same concept applies if you are paying in native tokens.
The minimum subscription balance must be sufficient for each new consuming contract that you add to a subscription. For example, the minimum balance for a subscription that supports 20 consuming contracts needs to cover all the requests for all 20 contracts, while a subscription with one consuming contract only needs to cover that one contract.
For one request, the required size of the minimum balance depends on the gas lane and the size of the request. For example, a consuming contract that requests one random value will require a smaller minimum balance than a consuming contract that requests 50 random values. In general, you can estimate the required minimum balance using the following formula where max verification gas is always 200,000 gwei.
The following formulas show how the minimum subscription balance is calculated for LINK and native tokens in general. [Specific examples of each](https://docs.chain.link/vrf/v2-5/billing#estimate-minimum-subscription-balance) are available on the Billing page, where you can compare the higher minimum subscription balance with the lower amount for an actual request.
LINKNative tokens

```plaintext
(((Gas lane maximum * (Max verification gas + Callback gas limit)) * (100 + premium %)/100) / (1,000,000,000 Gwei/ETH)) / (ETH/LINK price) = Minimum LINK
```
Here is the same formula, broken out into steps:

```plaintext
Gas lane maximum * (Max verification gas + Callback gas limit) = Total estimated gas (Gwei)
Total estimated gas (Gwei) * ((100 + premium %)/100) = Total estimated gas with premium (Gwei)
Total estimated gas with premium (Gwei) / 1,000,000,000 Gwei/ETH = Total estimated gas with premium (ETH)
Total estimated gas with premium (ETH) / (ETH/LINK price) = Total estimated gas with premium (LINK)
```

```plaintext
(((Gas lane maximum * (Max verification gas + Callback gas limit)) * (100 + premium %)/100) / (1,000,000,000 Gwei/ETH)) / (ETH/[Native token] price) = Minimum [Native token]
```
Here is the same formula, broken out into steps:

```plaintext
Gas lane maximum * (Max verification gas + Callback gas limit) = Total estimated gas (Gwei)
Total estimated gas (Gwei) * ((100 + premium %)/100) = Total estimated gas with premium (Gwei)
Total estimated gas with premium (Gwei) / 1,000,000,000 Gwei/ETH = Total estimated gas with premium (ETH)
Total estimated gas with premium (ETH) / (ETH/[Native token] price) = Total estimated gas with premium (Native token)
```
#### [Maximum consuming contracts](https://docs.chain.link/vrf/v2-5/overview/subscription\#maximum-consuming-contracts)
Each subscription supports up to 100 consuming contracts. If you need more than 100 consuming contracts, create multiple subscriptions.
### [Coordinator contract limits](https://docs.chain.link/vrf/v2-5/overview/subscription\#coordinator-contract-limits)
You can see the configuration for each network on the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page. You can also view the full configuration for each coordinator contract directly in the block explorer for that network, for example, Etherscan or Polygonscan.
- Each coordinator has a `MAX_NUM_WORDS` parameter that limits the maximum number of random values you can receive in each request.
- Each coordinator has a `maxGasLimit` parameter, which is the maximum allowed `callbackGasLimit` value for your requests. You must specify a sufficient `callbackGasLimit` to fund the callback request to your consuming contract. This depends on the number of random values you request and how you process them in your `fulfillRandomWords()` function. If your `callbackGasLimit` is not sufficient, the callback fails but your subscription is still charged for the work done to generate your requested random values.
## Get the latest Chainlink content straight to your inbox.
Email Address
## VRF Migration Guide
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Migrating from VRF v1](https://docs.chain.link/vrf/v2-5/migration-from-v1\#overview)
VRF V2.5 replaces both VRF V1 and VRF V2 on November 29, 2024. [Learn more about VRF V2.5](https://blog.chain.link/introducing-vrf-v2-5/).
## [Comparing VRF v1 to VRF v2.5](https://docs.chain.link/vrf/v2-5/migration-from-v1\#comparing-vrf-v1-to-vrf-v25)
Chainlink VRF v2.5 includes several improvements and changes to the way you fund and request randomness for your smart contracts:
- You have the option to manage payment for your VRF requests by pre-funding a subscription account, or to directly fund your consuming contracts as you do with VRF V1. [Compare subscription and direct funding](https://docs.chain.link/vrf/#choosing-the-correct-method).
- VRF v2.5 introduces the option to pay for requests in either LINK or native tokens. This choice is available for both subscription and direct funding.
### [New billing options](https://docs.chain.link/vrf/v2-5/migration-from-v1\#new-billing-options)
- **Native billing:** You have the option to use either native tokens or LINK to pay for VRF requests. Instead of a flat LINK fee per request, there is percentage-based premium fee applied to each request. See the [Billing](https://docs.chain.link/vrf/v2-5/billing) page for more details. To find out the premium percentages for the networks you use, see the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- **Subscription management:** Chainlink VRF v2.5 has a [Subscription Manager](https://vrf.chain.link/) application that allows smart contract applications to pre-fund multiple requests for randomness using one subscription account. This reduces the gas fees for VRF requests by eliminating the need to transfer funds for each individual request. You transfer funds to the subscription balance only when it requires additional funding.
- **Unified Billing - Delegate Subscription Balance to Multiple Addresses:** Chainlink VRF v2.5 allows up to 100 smart contract addresses to fund their requests for verifiable randomness from a single subscription account, which is managed by the subscription owner.
- **Variable Callback Gas Limit:** Chainlink VRF v2.5 lets you adjust the callback gas limit when your smart contract application receives verifiable randomness. Consuming contracts can execute more complex logic in the callback request function that receives the random values. Tasks involving the delivered randomness are handled during the response process. The new gas limits are higher than the VRF V1 limit, and vary depending on the underlying blockchain you use. See the gas limits on the [VRF Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- **More configuration capability:** You can define how many block confirmations must pass before verifiable randomness is generated and delivered onchain when your application makes a request transaction. The range is from 3 to 200 blocks. VRF V1 always waited 10 blocks on Ethereum before delivering onchain randomness. Select a value that protects your application from block re-organizations while still providing sufficiently low latency from request to response. See the [Security Considerations](https://docs.chain.link/vrf/v2-5/security) page to learn more.
- **Multiple Random Outputs in a Single Request:** In VRF v2.5, you can request multiple random numbers (multi-word) in a single onchain transaction, which reduces gas costs. The fulfillment is also a single transaction, which reduces the latency of responses.
For direct funding, the configurations for overhead gas have changed:
- The amount of wrapper overhead gas is reduced compared to V2.
- The amount of coordinator overhead gas used varies depending on the network used for your request, whether you're paying in LINK or native tokens, and how many random values you want in each VRF request. See the [Billing](https://docs.chain.link/vrf/v2-5/billing) page for more details and examples. The new configurations are listed in the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
### [Updating your applications to use VRF v2.5](https://docs.chain.link/vrf/v2-5/migration-from-v1\#updating-your-applications-to-use-vrf-v25)
You have the option to manage payment for your VRF requests with a subscription account, or to directly fund your consuming contracts as you do with VRF V1. [Compare subscription and direct funding](https://docs.chain.link/vrf/#choosing-the-correct-method).
SubscriptionDirect funding
To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the [Get a Random Number](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number) guide for an example.
1. Set up and fund a subscription in the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/).
[Open the Subscription Manager](https://vrf.chain.link/)
2. Add the following imports to your contract:
- [`VRFConsumerBaseV2Plus`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol). Remove the v1 `VRFConsumerBase.sol` import. `VRFConsumerBaseV2Plus` includes the `fulfillRandomWords` function. The `VRFConsumerBaseV2Plus` contract imports the `IVRFCoordinatorV2Plus` interface, which includes the `requestRandomWords` function.
- [`VRFV2PlusClient`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev//libraries/VRFV2PlusClient.sol) is a library used to format your VRF requests.

```solidity
import { VRFConsumerBaseV2Plus } from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import { VRFV2PlusClient } from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
```
3. Add a `VRFConsumerBaseV2Plus` constructor, passing in the LINK token address for the network you're using, as shown in the [Get a Random Number](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number) example.
4. Change `requestRandomness` function calls to `requestRandomWords`. The `requestRandomWords` function requires several additional parameters. The `extraArgs` key allows you to add extra arguments related to new VRF features. Use the `nativePayment` argument to enable or disable payment in native tokens.

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
})
);
```
5. Change `fulfillRandomness` function calls to `fulfillRandomWords`. Update the call to handle the returned `uint256[]` array instead of the single `uint256` variable.
6. Use the `setCoordinator` function in your contract so that you can easily update the VRF coordinator for future VRF releases. This function is inherited from the [`IVRFCoordinatorV2Plus`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/interfaces/IVRFCoordinatorV2Plus.sol) interface.
To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the [Get a Random Number](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number) guide for an example.
1. Import and inherit the [`VRFV2PlusWrapperConsumerBase`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol) contract and remove the v1 `VRFConsumerBase.sol` import. This contract includes the `fulfillRandomWords` function.
2. Add a `VRFV2PlusWrapperConsumerBase` constructor, passing in the VRF wrapper address for the network you're using, as shown in the [Get a Random Number](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number) example.
3. You can still call the `requestRandomness` function. However, the v2 `requestRandomness` function requires several different parameters. See the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page to adjust them for your own needs.
- The `requestRandomness` function in the wrapper contract requires a new `extraArgs` argument that allows you to add extra arguments related to new VRF features. Use the `nativePayment` argument to enable or disable payment in native tokens.
- Additionally, the `requestRandomness` function now returns two arguments instead of one: the request ID and the request price.

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
);
(uint256 reqId, uint256 reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```
4. If you're paying for requests with LINK, you can still call the `requestRandomness` function. However, if you're paying with native tokens, call the `requestRandomnessPayInNative` function instead.
- Both functions return two arguments instead of one: the request ID and the request price.
- Both functions require one additional parameter, `extraArgs`. Use `nativePayment` to specify whether or not you want to pay for VRF requests using native tokens:
LINKNative tokens

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
);
(uint256 reqId, uint256 reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: true})
);
(uint256 reqId, uint256 reqPrice) = requestRandomnessPayInNative(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```
5. Change `fulfillRandomness` function calls to `fulfillRandomWords`. Update the call to handle the returned `uint256[]` array instead of the single `uint256` variable.
## [Migration walkthrough](https://docs.chain.link/vrf/v2-5/migration-from-v1\#migration-walkthrough)
VRF v2.5 currently supports subscriptions and direct funding on all [supported networks](https://docs.chain.link/vrf/v2-5/supported-networks). To migrate, you need to [update your existing smart contract code](https://docs.chain.link/vrf/v2-5/migration-from-v1#update-your-code) and redeploy your contracts.
If using subscriptions, [create and fund a new VRF v2.5 subscription](https://docs.chain.link/vrf/v2-5/subscription/create-manage).
For direct funding, deploy the [`DirectFundingConsumer`](https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) example:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
### [Update your code](https://docs.chain.link/vrf/v2-5/migration-from-v1\#update-your-code)
To modify your existing smart contract code to work with VRF v2.5, complete the following changes:
SubscriptionDirect funding
1. Import the [`VRFConsumerBaseV2Plus`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol) contract and remove the v2 `VRFConsumerBaseV2` import.
2. Import the VRF v2.5 coordinator, [`VRFCoordinatorV2_5`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol), and update any old references to the VRF V2 coordinator in your contract.
3. Add a `VRFConsumerBaseV2Plus` constructor, passing in the LINK token address for the network you're using.
4. Update your `requestRandomWords` function calls to reflect the new request structure for VRF v2.5. Make sure to include the new `extraArgs` part of the `VRFV2PlusClient.RandomWordsRequest` object, and specify whether or not you want to pay for VRF requests using native tokens:
LINKNative tokens

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}))
})
);
```

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
})
);
```
5. When using the [`@chainlink/contracts`](https://www.npmjs.com/package/@chainlink/contracts/v/1.1.1) package version 1.1.1 and later, update your `fulfillRandomWords` function signature to match the `VRFConsumerBaseV2Plus` contract, which has changed to:

```plaintext
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)
```
In the `@chainlink/contracts` package version 1.1.0 and earlier, the `randomWords` parameter has a `memory` storage location.
1. Import the [`VRFV2PlusWrapperConsumerBase`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol) contract and remove the v2 `VRFV2WrapperConsumerBase` import.
2. Add a `VRFV2PlusWrapperConsumerBase` constructor, passing in the VRF wrapper address for the network you're using. Unlike in V2, you don't have to pass the LINK token address to the constructor.
3. If you're paying for requests with LINK, you can still call the `requestRandomness` function. However, if you're paying with native tokens, call the `requestRandomnessPayInNative` function instead.
Both functions require one additional parameter, `extraArgs`. Use `nativePayment` to specify whether or not you want to pay for VRF requests using native tokens:
LINKNative tokens

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
);
(uint256 reqId, uint256 reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: true})
);
(uint256 reqId, uint256 reqPrice) = requestRandomnessPayInNative(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```
4. The V2.5 `requestRandomness` and `requestRandomnessPayInNative` functions both return a tuple: `(uint256 requestId, uint256 requestPrice)`. Adjust your `requestRandomWords` function or any other functions in your code where you call the V2.5 wrapper's `requestRandomness` or `requestRandomnessPayInNative` functions.
5. Make sure your contract has a withdraw function for both native tokens and LINK. Both are included in the [direct funding example code](https://docs.chain.link/vrf/v2-5/migration-from-v1#view-example-code) and the [`VRFV2PlusWrapperConsumerExample`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol) contract.
## [View example code](https://docs.chain.link/vrf/v2-5/migration-from-v1\#view-example-code)
View example code for both VRF 2.5 subscription and direct funding:
Open the full example `SubscriptionConsumer` contract:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open the full example `DirectFundingConsumer` contract:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
## Get the latest Chainlink content straight to your inbox.
Email Address
## VRF Cost Estimation
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
On this page
# [VRF Cost Estimation on Arbitrum](https://docs.chain.link/vrf/v2-5/arbitrum-cost-estimation\#overview)
The total transaction costs for using Arbitrum involve both L2 gas costs and L1 costs. Arbitrum transactions are [posted in batches to L1 Ethereum](https://developer.arbitrum.io/inside-arbitrum-nitro/#how-the-sequencer-publishes-the-sequence), which incurs an L1 cost. For an individual transaction, the total cost includes part of the L1 cost incurred to post the batch that included the transaction.
To learn how to estimate gas costs for Arbitrum, refer to the [Arbitrum gas estimation tutorial](https://developer.arbitrum.io/devs-how-tos/how-to-estimate-gas) and the full [Arbitrum gas estimation script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation) using their SDK. There is also a [**version of Arbitrum's gas estimation script extended to include VRF calculations**](https://docs.chain.link/vrf/v2-5/arbitrum-cost-estimation#arbitrum-and-vrf-gas-estimation-code).
#### [Estimating Arbitrum gas costs with VRF](https://docs.chain.link/vrf/v2-5/arbitrum-cost-estimation\#estimating-arbitrum-gas-costs-with-vrf)
SubscriptionDirect funding
VRF gas costs on L1 networks are calculated based on the amount of verification gas and callback gas used, multiplied by the gas price:

```plaintext
(Gas price * (Verification gas + Callback gas)) = total gas cost
```
For VRF Arbitrum transactions, add a buffer to estimate the additional L1 cost:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ L1 calldata gas buffer))) = total estimated gas cost
```
To calculate the L1 callback gas buffer:
- `calldataSizeBytes`: A static size for the transaction's calldata in bytes. Total: 720 bytes.
- The amount Arbitrum adds to account for the static part of the transaction, fixed at 140 bytes.
- The size of an ABI-encoded VRF V2.5 fulfillment, fixed at 580 bytes ( `fulfillmentTxSizeBytes`).
- `L1PricePerByte`: The estimated cost of posting 1 byte of data on L1, which varies with L1 network gas prices.
- `L2GasPrice`: The L2 gas price, which varies with L2 network gas prices.

```plaintext
L1 calldata gas buffer = (calldataSizeBytes * L1PricePerByte) / L2GasPrice
= (720 * L1PricePerByte) / L2GasPrice
```
This conversion allows us to estimate the L1 callback gas cost and incorporate it into the overall L2 gas estimate. You can add this estimated L1 callback gas buffer directly to the verification and callback gas:

```plaintext
(L2GasPrice
* (Verification gas
+ Callback gas
+ ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost
```
VRF gas costs on L1 networks are calculated based on the amount of coordinator overhead gas, wrapper overhead gas, and callback gas, multiplied by the gas price:

```plaintext
(Gas price * (Coordinator overhead gas + Callback gas + Wrapper overhead gas)) = total gas cost
```
For VRF Arbitrum transactions, add a buffer to estimate the additional L1 cost:

```plaintext
(L2GasPrice
* (Coordinator overhead gas
+ Callback gas
+ Wrapper overhead gas
+ L1 calldata gas buffer))) = total estimated gas cost
```
To calculate the L1 callback gas buffer:
- `calldataSizeBytes`: A static size for the transaction's calldata in bytes. Total: 720 bytes.
- The amount Arbitrum adds to account for the static part of the transaction, fixed at 140 bytes.
- The size of an ABI-encoded VRF V2.5 fulfillment, fixed at 580 bytes ( `fulfillmentTxSizeBytes`).
- `L1PricePerByte`: The estimated cost of posting 1 byte of data on L1, which varies with L1 network gas prices.
- `L2GasPrice`: The L2 gas price, which varies with L2 network gas prices.

```plaintext
L1 calldata gas buffer = (calldataSizeBytes * L1PricePerByte) / L2GasPrice
= (720 * L1PricePerByte) / L2GasPrice
```
This conversion allows us to estimate the L1 callback gas cost and incorporate it into the overall L2 gas estimate. You can add this estimated L1 callback gas buffer directly to the other gas figures:

```plaintext
(L2GasPrice
* (Coordinator overhead gas
+ Callback gas
+ Wrapper overhead gas
+ ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost
```
#### [Arbitrum and VRF gas estimation code](https://docs.chain.link/vrf/v2-5/arbitrum-cost-estimation\#arbitrum-and-vrf-gas-estimation-code)
This sample extends the [original Arbitrum gas estimation script](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/gas-estimation) to estimate gas costs for VRF subscription and direct funding requests on Arbitrum.
The following snippet shows only the VRF variables and calculations that were added to the Arbitrum gas estimation script. To learn more about how Arbitrum gas is calculated, refer to the [Arbitrum gas estimation tutorial](https://developer.arbitrum.io/devs-how-tos/how-to-estimate-gas). To run this code, use the [**full Arbitrum gas estimation script that includes VRF calculations**](https://github.com/smartcontractkit/smart-contract-examples/tree/main/vrf-arbitrum-gas-estimation).

```typescript
// VRF variables and calculations
// ---------------------------------
// Full script: https://github.com/smartcontractkit/smart-contract-examples/tree/main/vrf-arbitrum-gas-estimation
// ---------------------------------
// Estimated upper bound of verification gas for VRF subscription.
// To see an estimate with an average amount of verification gas,
// adjust this to 115000.
const maxVerificationGas = 200000
// The L1 Calldata size includes:
// Arbitrum's static 140 bytes for transaction metadata
// VRF V2's static 580 bytes, the size of a fulfillment's calldata abi-encoded in bytes
// (from s_fulfillmentTxSizeBytes in VRFV2Wrapper.sol)
const VRFCallDataSizeBytes = 140 + 580
// For direct funding only
// Coordinator gas is verification gas.
// Some overhead gas values vary by network. These are hardcoded for Sepolia.
// Refer to https://docs.chain.link/vrf/v2-5/supported-networks to find values for other networks.
const wrapperGasOverhead = 13400
const coordinatorGasOverheadNative = 90000
const coordinatorGasOverheadLink = 112000
const coordinatorGasOverheadPerWord = 435
// VRF user settings
const callbackGasLimit = 175000
const numWords = 2 // Max 10 per request
// Estimate VRF L1 buffer
const VRFL1CostEstimate = L1P.mul(VRFCallDataSizeBytes)
const VRFL1Buffer = VRFL1CostEstimate.div(P)
// VRF Subscription gas estimate
// L2 gas price (P) * (maxVerificationGas + callbackGasLimit + VRFL1Buffer)
const VRFL2SubscriptionGasSubtotal = BigNumber.from(maxVerificationGas + callbackGasLimit)
const VRFSubscriptionGasTotal = VRFL2SubscriptionGasSubtotal.add(VRFL1Buffer)
const VRFSubscriptionGasEstimate = P.mul(VRFSubscriptionGasTotal)
// VRF Direct funding gas estimate
// L2 gas price (P) * (coordinatorGasOverheadLink + callbackGasLimit + wrapperGasOverhead + VRFL1Buffer)
// If using native tokens, change coordinatorGasOverheadLink to coordinatorGasOverheadNative below
const directFundingGasOverheadPerWord = coordinatorGasOverheadPerWord.mul(numWords)
const VRFL2DirectFundingGasSubtotal = BigNumber.from(
coordinatorGasOverheadLink + wrapperGasOverhead + callbackGasLimit + directFundingGasOverheadPerWord
)
const VRFDirectFundingGasTotal = VRFL2DirectFundingGasSubtotal.add(VRFL1Buffer)
const VRFDirectFundingGasEstimate = P.mul(VRFDirectFundingGasTotal)
```
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF v2.5 Migration
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Migrating from VRF v2](https://docs.chain.link/vrf/v2-5/migration-from-v2\#overview)
VRF V2.5 replaces both VRF V1 and VRF V2 on November 29, 2024. [Learn more about VRF V2.5](https://blog.chain.link/introducing-vrf-v2-5/).
## [Benefits of VRF v2.5](https://docs.chain.link/vrf/v2-5/migration-from-v2\#benefits-of-vrf-v25)
Chainlink VRF v2.5 includes [all the same key benefits as VRF v2](https://blog.chain.link/vrf-v2-mainnet-launch/), along with the following additional benefits and changes:
- Easier upgrades to future versions by using the new `setCoordinator` function
- The option to pay for requests in either LINK or native tokens
- New, flexible request format in `requestRandomWords` to make any future upgrades easier
## [Code changes](https://docs.chain.link/vrf/v2-5/migration-from-v2\#code-changes)
VRF v2.5 introduces a new request format and the `setCoordinator` function. See the [full migration walkthrough](https://docs.chain.link/vrf/v2-5/migration-from-v2#migration-walkthrough) or the code example for more details.
### [New request format](https://docs.chain.link/vrf/v2-5/migration-from-v2\#new-request-format)
The request format for VRF v2.5 has changed:
SubscriptionDirect funding
The `requestRandomWords` function now uses `VRFV2PlusClient.RandomWordsRequest` with an object labeling each part of the request:

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
})
);
```
You must include a value for the new `extraArgs` key, which allows you to add extra arguments related to new VRF features. Use the `nativePayment` argument to enable or disable payment in native tokens.
The `requestRandomness` function in the wrapper contract requires a new `extraArgs` argument that allows you to add extra arguments related to new VRF features. Use the `nativePayment` argument to enable or disable payment in native tokens.
Additionally, the `requestRandomness` function now returns two arguments instead of one: the request ID and the request price.

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
);
(uint256 reqId, uint256 reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```
### [setCoordinator function](https://docs.chain.link/vrf/v2-5/migration-from-v2\#setcoordinator-function)
Add the `setCoordinator` function to your contract so that you can easily update the VRF coordinator for future VRF releases.
### [Subscription ID type change](https://docs.chain.link/vrf/v2-5/migration-from-v2\#subscription-id-type-change)
Note that the subscription ID has changed types from `uint64` in VRF V2 to `uint256` in VRF V2.5.
## [Billing changes](https://docs.chain.link/vrf/v2-5/migration-from-v2\#billing-changes)
You have the option to use either native tokens or LINK to pay for VRF requests. To accommodate this, the premium fee has changed from a flat LINK premium amount per request, to a percentage-based premium per request. Refer to the [Billing](https://docs.chain.link/vrf/v2-5/billing) page for more details. To find out the new premium percentages for the networks you use, see the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
For direct funding, the configurations for overhead gas have changed:
- The amount of wrapper overhead gas is reduced compared to V2.
- The amount of coordinator overhead gas used varies depending on the network used for your request, whether you're paying in LINK or native tokens, and how many random values you want in each VRF request. Refer to the [Billing](https://docs.chain.link/vrf/v2-5/billing) page for more details and examples, and see the new configurations on the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
## [Migration walkthrough](https://docs.chain.link/vrf/v2-5/migration-from-v2\#migration-walkthrough)
VRF v2.5 currently supports subscriptions and direct funding on all [supported networks](https://docs.chain.link/vrf/v2-5/supported-networks). To migrate, you need to [update your existing smart contract code](https://docs.chain.link/vrf/v2-5/migration-from-v2#update-your-code) and redeploy your contracts.
If using subscriptions, [create and fund a new VRF v2.5 subscription](https://docs.chain.link/vrf/v2-5/subscription/create-manage).
For direct funding, deploy the [`DirectFundingConsumer`](https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) example:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
### [Update your code](https://docs.chain.link/vrf/v2-5/migration-from-v2\#update-your-code)
To modify your existing smart contract code to work with VRF v2.5, complete the following changes:
SubscriptionDirect funding
1. Import the [`VRFConsumerBaseV2Plus`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol) contract and remove the v2 `VRFConsumerBaseV2` import.
2. Import the VRF v2.5 coordinator, [`VRFCoordinatorV2_5`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol), and update any old references to the VRF V2 coordinator in your contract.
3. Add a `VRFConsumerBaseV2Plus` constructor, passing in the VRF coordinator address for the network you're using.
4. Update your `requestRandomWords` function calls to reflect the new request structure for VRF v2.5. Make sure to include the new `extraArgs` part of the `VRFV2PlusClient.RandomWordsRequest` object, and specify whether or not you want to pay for VRF requests using native tokens:
LINKNative tokens

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}))
})
);
```

```solidity
uint256 requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_vrfSubscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true}))
})
);
```
5. When using the [`@chainlink/contracts`](https://www.npmjs.com/package/@chainlink/contracts/v/1.1.1) package version 1.1.1 and later, update your `fulfillRandomWords` function signature to match the `VRFConsumerBaseV2Plus` contract, which has changed to:

```plaintext
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)
```
In the `@chainlink/contracts` package version 1.1.0 and earlier, the `randomWords` parameter has a `memory` storage location.
1. Import the [`VRFV2PlusWrapperConsumerBase`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol) contract and remove the v2 `VRFV2WrapperConsumerBase` import.
2. Add a `VRFV2PlusWrapperConsumerBase` constructor, passing in the VRF wrapper address for the network you're using. Unlike in V2, you don't have to pass the LINK token address to the constructor.
3. If you're paying for requests with LINK, you can still call the `requestRandomness` function. However, if you're paying with native tokens, call the `requestRandomnessPayInNative` function instead.
Both functions require one additional parameter, `extraArgs`. Use `nativePayment` to specify whether or not you want to pay for VRF requests using native tokens:
LINKNative tokens

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
);
(uint256 reqId, uint256 reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```

```solidity
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: true})
);
(uint256 reqId, uint256 reqPrice) = requestRandomnessPayInNative(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
```
4. The V2.5 `requestRandomness` and `requestRandomnessPayInNative` functions both return a tuple: `(uint256 requestId, uint256 requestPrice)`. Adjust your `requestRandomWords` function or any other functions in your code where you call the V2.5 wrapper's `requestRandomness` or `requestRandomnessPayInNative` functions.
5. Make sure your contract has a withdraw function for both native tokens and LINK. Both are included in the [direct funding example code](https://docs.chain.link/vrf/v2-5/migration-from-v2#direct-funding-example-code) and the [`VRFV2PlusWrapperConsumerExample`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusWrapperConsumerExample.sol) contract.
### [Compare example code](https://docs.chain.link/vrf/v2-5/migration-from-v2\#compare-example-code)
#### [Subscription example code](https://docs.chain.link/vrf/v2-5/migration-from-v2\#subscription-example-code)
The example `SubscriptionConsumer` contract shows the migration steps above, applied to the example code from [this VRF V2 tutorial](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number#analyzing-the-contract). Both of these examples use the subscription method.
Open the full example `SubscriptionConsumer` contract:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Compare the major changes between V2.5 and V2:
VRF V2.5 example codeVRF V2 example code

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity 0.8.19;
///// UPDATE IMPORTS TO V2.5 /////
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.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.
\*/
///// INHERIT NEW CONSUMER BASE CONTRACT /////
contract SubscriptionConsumer is VRFConsumerBaseV2Plus {
...
///// No need to declare a coordinator variable /////
///// Use the `s_vrfCoordinator` from VRFConsumerBaseV2Plus.sol /////
///// SUBSCRIPTION ID IS NOW UINT256 /////
uint256 s_subscriptionId;
...
///// USE NEW KEYHASH FOR VRF 2.5 GAS LANE /////
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf/v2-5/supported-networks
bytes32 keyHash =
0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
...
///// USE NEW CONSUMER BASE CONSTRUCTOR /////
constructor(
///// UPDATE TO UINT256 /////
uint256 subscriptionId
)
VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B)
{
s_subscriptionId = subscriptionId;
}
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
///// UPDATE TO NEW V2.5 REQUEST FORMAT /////
// To enable payment in native tokens, set nativePayment to true.
// Use the `s_vrfCoordinator` from VRFConsumerBaseV2Plus.sol
requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
)
})
);
...
}
...
}
```

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;
///// USES V2 IMPORTS /////
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.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.
\*/
///// USES V2 CONSUMER BASE CONTRACT /////
contract VRFv2Consumer is VRFConsumerBaseV2, ConfirmedOwner {
...
///// OLD TYPE FOR SUBSCRIPTION ID /////
uint64 s_subscriptionId;
...
///// KEYHASH FOR VRF V2 GAS LANE /////
// 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/v2/subscription/supported-networks/#configurations
bytes32 keyHash =
0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
...
///// USES V2 CONSUMER BASE AND COORDINATOR CONSTRUCTORS /////
constructor(
uint64 subscriptionId
)
VRFConsumerBaseV2(0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625)
ConfirmedOwner(msg.sender)
{
COORDINATOR = VRFCoordinatorV2Interface(
0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
);
s_subscriptionId = subscriptionId;
}
...
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{ ///// USES V2 REQUEST FORMAT /////
requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
...
}
...
}
```
#### [Direct funding example code](https://docs.chain.link/vrf/v2-5/migration-from-v2\#direct-funding-example-code)
The example `DirectFundingConsumer` contract shows the migration steps above, applied to the example code from [this VRF V2 tutorial](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number#analyzing-the-contract). Both of these examples use the direct funding method.
Open the full example `DirectFundingConsumer` contract:
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Compare the major changes between V2.5 and V2:
VRF V2.5 example codeVRF V2 example code

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that directly pays for each request.
pragma solidity 0.8.20;
///// UPDATE IMPORTS TO V2.5 /////
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {VRFV2PlusWrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.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.
*/
///// INHERIT NEW WRAPPER CONSUMER BASE CONTRACT /////
contract DirectFundingConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner {
...
///// USE NEW WRAPPER CONSUMER BASE CONSTRUCTOR /////
constructor()
ConfirmedOwner(msg.sender)
VRFV2PlusWrapperConsumerBase(wrapperAddress) ///// ONLY PASS IN WRAPPER ADDRESS /////
{}
function requestRandomWords(
bool enableNativePayment
) external onlyOwner returns (uint256) {
///// UPDATE TO NEW V2.5 REQUEST FORMAT: ADD EXTRA ARGS /////
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: enableNativePayment})
);
uint256 requestId;
uint256 reqPrice;
if (enableNativePayment) {
///// USE THIS FUNCTION TO PAY IN NATIVE TOKENS /////
(requestId, reqPrice) = requestRandomnessPayInNative(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs ///// PASS IN EXTRA ARGS /////
);
} else {
///// USE THIS FUNCTION TO PAY IN LINK /////
(requestId, reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs ///// PASS IN EXTRA ARGS /////
);
}
...
return requestId;
}
...
}
```

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that directly pays for each request.
pragma solidity ^0.8.7;
///// USES V2 IMPORTS /////
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {VRFV2WrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.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.
\*/
///// USES V2 WRAPPER CONSUMER BASE CONTRACT /////
contract VRFv2DirectFundingConsumer is
VRFV2WrapperConsumerBase,
ConfirmedOwner
{
...
///// USES V2 WRAPPER CONSUMER BASE CONSTRUCTOR /////
constructor()
ConfirmedOwner(msg.sender)
VRFV2WrapperConsumerBase(linkAddress, wrapperAddress) ///// TWO PARAMETERS /////
{}
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
///// USES V2 REQUEST FORMAT /////
requestId = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords
);
...
return requestId;
}
...
}
```
## Get the latest Chainlink content straight to your inbox.
Email Address
## Direct Funding Overview
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Direct Funding Method](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#overview)
This guide explains how to generate random numbers using the _direct funding_ method. This method doesn't require a subscription and is optimal for one-off requests for randomness. This method also works best for applications where your end-users must pay the fees for VRF because the cost of the request is determined at request time.
Unlike the [subscription method](https://docs.chain.link/vrf/v2-5/overview/subscription), the direct funding method does not require you to create subscriptions and pre-fund them. Instead, you must directly fund consuming contracts with native tokens or LINK before they request randomness. Because the consuming contract directly pays for the request, the cost is calculated during the request and not during the callback when the randomness is fulfilled. Learn [how to estimate costs](https://docs.chain.link/vrf/v2-5/billing).
## [Request and receive data](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#request-and-receive-data)
Requests to Chainlink VRF v2.5 follow the request and receive data cycle similarly to VRF V2. This end-to-end diagram shows each step in the lifecycle of a VRF direct funding request:

The Chainlink VRF v2.5 solution uses both offchain and onchain components:
- [VRF v2.5 Wrapper (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol): A wrapper for the VRF Coordinator that provides an interface for consuming contracts.
- [VRF v2.5 Coordinator (onchain component)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol): A contract designed to interact with the VRF service. It emits an event when a request for randomness is made, and then verifies the random number and proof of how it was generated by the VRF service.
- VRF service (offchain component): Listens for requests by subscribing to the VRF Coordinator event logs and calculates a random number based on the block hash and nonce. The VRF service then sends a transaction to the `VRFCoordinator` including the random number and a proof of how it was generated.
### [Account types used in VRF](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#account-types-used-in-vrf)
Two types of accounts exist in the Ethereum ecosystem, and both are used in VRF:
- EOA (Externally Owned Account): An externally owned account that has a private key and can control a smart contract. Transactions can be initiated only by EOAs.
- Smart contract: A smart contract that does not have a private key and executes what it has been designed for as a decentralized application.
While only EOAs can initiate transactions, do not attempt to use EOAs to send VRF requests directly. Instead, your EOA should interact with your consuming contract: the smart contract that is consuming the random values you request from VRF. Your EOA initiates the transaction, and then your consuming contract interacts with the VRF Wrapper contract, which sends the VRF request.
### [Set up your contract and request](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#set-up-your-contract-and-request)
Set up your consuming contract:
1. Your contract must inherit [VRFV2PlusWrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol).
2. Your contract must implement the `fulfillRandomWords` function, which is the _callback VRF function_. Here, you add logic to handle the random values after they are returned to your contract.
3. Submit your VRF request by calling the `requestRandomness` function in the [VRFV2PlusWrapperConsumerBase](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol) contract. Include the following parameters in your request:
- `requestConfirmations`: The number of block confirmations the VRF service will wait to respond. The minimum and maximum confirmations for your network can be found [here](https://docs.chain.link/vrf/v2-5/supported-networks).
- `callbackGasLimit`: The maximum amount of gas to pay for completing the callback VRF function.
- `numWords`: The number of random numbers to request. You can find the maximum number of random values per request for your network in the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- `extraArgs`: A parameter for additional arguments related to new VRF features, such as enabling payment in native tokens.
### [How VRF processes your request](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#how-vrf-processes-your-request)
After you submit your request, it is processed using the [Request & Receive Data](https://docs.chain.link/vrf/v2-5/overview/direct-funding#request-and-receive-data) cycle:
1. The consuming contract calls the [VRFV2PlusWrapper](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol) `calculateRequestPrice` function to estimate the total transaction cost to fulfill randomness. Learn [how to estimate transaction costs](https://docs.chain.link/vrf/v2-5/billing).
2. The consuming contract calls the [LinkToken](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol) `transferAndCall` function to pay the wrapper with the calculated request price. This method sends LINK tokens and executes the [VRFV2PlusWrapper](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapper.sol) `onTokenTransfer` logic.
3. The VRFV2PlusWrapper's `onTokenTransfer` logic triggers the [VRF 2.5 Coordinator](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol) `requestRandomWords` function to request randomness.
4. The VRF coordinator emits an event.
5. The VRF service picks up the event and waits for the specified number of block confirmations to respond back to the VRF coordinator with the random values and a proof ( `requestConfirmations`).
6. The VRF coordinator verifies the proof onchain, then it calls back the wrapper contract's `fulfillRandomWords` function.
7. Finally, the VRF Wrapper calls back your consuming contract.
## [Limits](https://docs.chain.link/vrf/v2-5/overview/direct-funding\#limits)
You can see the configuration for each network on the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page. You can also view the full configuration for each VRF v2.5 Wrapper contract directly in Etherscan. As an example, view the [Ethereum Mainnet VRF v2.5 Wrapper contract](https://etherscan.io/address/0x02aae1A04f9828517b3007f83f6181900CaD910c#readContract) configuration by calling `getConfig` function.
- Each wrapper has a `maxNumWords` parameter that limits the maximum number of random values you can receive in each request.
- The maximum allowed `callbackGasLimit` value for your requests is defined in the [Coordinator contract supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page. Because the VRF v2.5 Wrapper adds an overhead, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`. Learn more about [estimating costs](https://docs.chain.link/vrf/v2-5/billing).
## What's next
- [\> Get a Random Number](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number)
- [\> Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Local Testing for Chainlink VRF
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Local testing using a mock subscription contract](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#overview)
This guide explains how to test Chainlink VRF v2.5 on a [Remix IDE](https://remix-ide.readthedocs.io/en/latest/run.html#environment) sandbox blockchain environment. **Note**: You can reuse the same logic on another development environment, such as Hardhat or Foundry. For example, read the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).
## [Benefits of local testing](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#benefits-of-local-testing)
Testing locally using mock contracts saves you time and resources during development. Some of the key benefits include:
- Faster feedback loop: Immediate feedback on the functionality and correctness of your smart contracts. This helps you quickly identify and fix issues without waiting for transactions to be mined/validated on a testnet.
- Saving your native testnet gas: Deploying and interacting with contracts requires paying gas fees. Although native testnet gas does not have any associated value, supply is limited by public faucets. Using mock contracts locally allows you to test your contracts freely without incurring any expenses.
- Controlled environment: Local testing allows you to create a controlled environment where you can manipulate various parameters, such as block time and gas prices, to test your smart contracts' function as expected under different conditions.
- Isolated testing: You can focus on testing individual parts of your contract, ensuring they work as intended before integrating them with other components.
- Easier debugging: Because local tests run on your machine, you have better control over the debugging process. You can set breakpoints, inspect variables, and step through your code to identify and fix issues.
- Comprehensive test coverage: You can create test cases to cover all possible scenarios and edge cases.
## [Testing logic](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#testing-logic)
Complete the following tasks to test your VRF v2.5 consumer locally:
1. Deploy the [VRFCoordinatorV2\_5Mock](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol). This contract is a mock of the [VRFCoordinatorV2\_5](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFCoordinatorV2_5.sol) contract.
2. Call the [createSubscription function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/interfaces/IVRFSubscriptionV2Plus.sol#L56) (which `VRFCoordinatorV2_5Mock` inherits) to create a new subscription.
3. Call the VRFCoordinatorV2\_5Mock [`fundSubscription` function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol#L174) to fund your newly created subscription. **Note**: You can fund with an arbitrary amount.
4. Deploy your VRF consumer contract.
5. Call the [addConsumer function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/interfaces/IVRFSubscriptionV2Plus.sol#L12) (which `VRFCoordinatorV2_5Mock` inherits) to add your consumer contract to your subscription.
6. Request random words from your consumer contract.
7. Call the VRFCoordinatorV2\_5Mock [fulfillRandomWords function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol#L101) to fulfill your consumer contract request.
## [Testing](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#testing)
### [Open the contracts on Remix IDE](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#open-the-contracts-on-remix-ide)
For local testing, use the default "Remix VM" environment.
Open _VRFv2\_5Consumer_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.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.
*/
/**
* @title The RandomNumberConsumerV2_5 contract
* @notice A contract that gets random values from Chainlink VRF V2_5
*/
contract RandomNumberConsumerV2_5 is VRFConsumerBaseV2Plus {
// Your subscription ID.
uint256 immutable s_subscriptionId;
// 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 immutable s_keyHash;
// 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 constant CALLBACK_GAS_LIMIT = 100000;
// The default is 3, but you can set this higher.
uint16 constant REQUEST_CONFIRMATIONS = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS.
uint32 constant NUM_WORDS = 2;
uint256[] public s_randomWords;
uint256 public s_requestId;
event ReturnedRandomness(uint256[] randomWords);
/**
* @notice Constructor inherits VRFConsumerBaseV2Plus
*
* @param subscriptionId - the subscription ID that this contract uses for funding requests
* @param vrfCoordinator - coordinator, check https://docs.chain.link/vrf/v2-5/supported-networks
* @param keyHash - the gas lane to use, which specifies the maximum gas price to bump to
*/
constructor(
uint256 subscriptionId,
address vrfCoordinator,
bytes32 keyHash
) VRFConsumerBaseV2Plus(vrfCoordinator) {
s_keyHash = keyHash;
s_subscriptionId = subscriptionId;
}
/**
* @notice Requests randomness
* Assumes the subscription is funded sufficiently; "Words" refers to unit of data in Computer Science
*/
function requestRandomWords() external onlyOwner {
// Will revert if subscription is not set and funded.
s_requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: s_keyHash,
subId: s_subscriptionId,
requestConfirmations: REQUEST_CONFIRMATIONS,
callbackGasLimit: CALLBACK_GAS_LIMIT,
numWords: NUM_WORDS,
extraArgs: VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
)
})
);
}
/**
* @notice Callback function used by VRF Coordinator
*
* @param - id of the request
* @param randomWords - array of random results from VRF Coordinator
*/
function fulfillRandomWords(
uint256 /* requestId */,
uint256[] calldata randomWords
) internal override {
s_randomWords = randomWords;
emit ReturnedRandomness(randomWords);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFv2_5Consumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _VRFCoordinatorV2\_5Mock_ in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFCoordinatorV2_5Mock.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
On the _Solidity Compiler_ tab, expand the _Advanced Configurations_ section and check the _Enable optimization_ box before you compile the _VRFCoordinatorV2\_5Mock_ contract:

Your Remix IDE file explorer should display _VRFCoordinatorV2\_5Mock.sol_ and _VRFv2\_5Consumer.sol_:

### [Deploy VRFCoordinatorV2\_5Mock](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#deploy-vrfcoordinatorv2_5mock)
1. Open _VRFCoordinatorV2\_5Mock.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _VRFCoordinatorV2\_5Mock_.

3. Under _DEPLOY_, fill in the `_BASEFEE`, `_GASPRICELINK` and `_WEIPERUNITLINK`. These variables are used in the _VRFCoordinatorV2\_5Mock_ contract to represent the base fee, the gas price (in LINK tokens), and the current LINK/ETH price for the VRF requests.

You can set:
- `_BASEFEE` to `100000000000000000`
- `_GASPRICELINK` to `1000000000`
- `_WEIPERUNITLINK` to the current LINK/ETH price. Click the "Latest Price" button to view it:
Latest Price:
Latest Price
4. Click _transact_ to deploy the _VRFCoordinatorV2\_5Mock_ contract.
5. Once deployed, you should see the _VRFCoordinatorV2\_5Mock_ contract under _Deployed Contracts_.

6. Note the address of the deployed contract.
### [Create and fund a subscription](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#create-and-fund-a-subscription)
1. Click `createSubscription` to create a new subscription.
2. In the Remix IDE console, read your transaction decoded output to find the subscription ID. Note the subscription ID, which is required for multiple steps in this tutorial.

3. Click on `fundSubscription` to fund your subscription. Fill in your subscription ID for `_subid` and set the `_amount` to `100000000000000000000`. This mocks funding your subscription with 100 LINK.
### [Deploy the VRF consumer contract](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#deploy-the-vrf-consumer-contract)
1. In the file explorer, open _VRFv2\_5Consumer.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _RandomNumberConsumerV2\_5_.

3. Under _DEPLOY_, fill in the following parameters:
- `SUBSCRIPTIONID` with your subscription ID
- `VRFCOORDINATOR` with the deployed _VRFCoordinatorV2\_5Mock_ address
- `_KEYHASH_` with an arbitrary `bytes32` (In this example, you can set the _KEYHASH_ to `0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae`).
4. Click _transact_ to deploy the _RandomNumberConsumerV2\_5_ contract.
5. After the consumer contract is deployed, you should see the _RandomNumberConsumerV2\_5_ contract under _Deployed Contracts_. Note the address of the deployed contract.
### [Add the consumer contract to your subscription](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#add-the-consumer-contract-to-your-subscription)
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2\_5Mock_ contract.
2. Click _addConsumer_ and fill in the `_subid` with your subscription ID and `_consumer` with your deployed consumer contract address.

3. Click _transact_.
### [Request random words](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#request-random-words)
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberConsumerV2\_5_ contract.
2. Click `requestRandomWords`.

3. Click `s_requestId` to display the last request ID. In this example, the output is _1_.

4. Note your request ID.
### [Fulfill the VRF request](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#fulfill-the-vrf-request)
Because you are testing on a local blockchain environment, you must fulfill the VRF request yourself.
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2\_5Mock_ contract.
2. Click `fulfillRandomWords` and fill in `_requestId` with your VRF request ID and `_consumer` with your consumer contract address.

3. Click `transact`.
### [Check the results](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#check-the-results)
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberConsumerV2\_5_ contract.
2. For each VRF request, your consumer contract requests two random words. After a request is fulfilled, the two random words are stored in the `s_randomWords` array. You can check the stored random words by reading the two first indexes of the `s_randomWords` array. To do so, click the _s\_randomWords_ function and:
1. Fill in the index with _0_ then click _call_ to read the first random word.

2. You can read the second random word in a similar way: fill in the index with _1_ then click _call_ to display the second random word.
## [Next steps](https://docs.chain.link/vrf/v2-5/subscription/test-locally\#next-steps)
This guide demonstrated how to test a VRF v2.5 consumer contract on your local blockchain. The guide uses the Remix IDE for learning purposes, but you can reuse the same [testing logic](https://docs.chain.link/vrf/v2-5/subscription/test-locally#testing-logic) in another development environment, such as Hardhat. For example, see the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Subscription
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Programmatic Subscription](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription\#overview)
How you manage the subscription depends on your randomness needs. You can configure your subscriptions using the [Subscription Manager](https://docs.chain.link/vrf/v2/subscription/ui), but these examples demonstrate how to create your subscription and add your consumer contracts programmatically. For these examples, the contract owns and manages the subscription. Any wallet can provide funding to those subscriptions.
You can view and monitor your subscriptions in the [Subscription Manager](https://docs.chain.link/vrf/v2/subscription/ui) even if you create them programmatically. Go to [vrf.chain.link](https://vrf.chain.link/) to open the Subscription Manager.
## [Modifying subscriptions and configurations](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription\#modifying-subscriptions-and-configurations)
Subscription configurations do not have to be static. You can change your subscription configuration dynamically by calling the following functions using the [VRFCoordinatorV2Interface](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol):
- Change the list of approved subscription consumers with:
- `addConsumer(uint64 subId, address consumer)`.
- `removeConsumer(uint64 subId, address consumer)`.
- Transfer the subscription ownership with:
- `requestSubscriptionOwnerTransfer(uint64 subId, address newOwner)`.
- `acceptSubscriptionOwnerTransfer(uint64 subId)`.
- View the subscription with `getSubscription(uint64 subId)`.
- Cancel the subscription with `cancelSubscription(uint64 subId)`.
To send LINK to the subscription balance, use the LINK token interface with `LINKTOKEN.transferAndCall(address(COORDINATOR), amount, abi.encode(subId))`. Any wallet can fund a subscription.
See the example in the [Subscription manager contract](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription#subscription-manager-contract) section to learn how to create a contract that can change your subscription configuration.
## [Subscription manager contract](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription\#subscription-manager-contract)
In this example, the contract operates as a subscription owner and can run functions to add consuming contracts to the subscription. The consuming contracts must include the `requestRandomWords()` function with the correct coordinator parameters and the correct subscription ID to request random values and use the subscription balance. The consuming contracts must also include the `fulfillRandomWords()` function to receive the random values.
Subscription owners and consumers do not have to be separate. This contract not only allows adding consumers with `addConsumer(address consumerAddress)` but can also act as a consumer by running its own `requestRandomWords()` function. This example contract includes a `createNewSubscription()` function in the `constructor()` that creates the subscription and adds itself as a consumer automatically when you deploy it.

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that also owns and manages the subscription
pragma solidity ^0.8.7;
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* 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 VRFv2SubscriptionManager is VRFConsumerBaseV2 {
VRFCoordinatorV2Interface COORDINATOR;
LinkTokenInterface LINKTOKEN;
// Sepolia coordinator. For other networks,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address vrfCoordinator = 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625;
// Sepolia LINK token contract. For other networks, see
// https://docs.chain.link/docs/vrf-contracts/#configurations
address link_token_contract = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
// 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 =
0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
// A reasonable default is 100000, but this value could be different
// on other networks.
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;
// Storage parameters
uint256[] public s_randomWords;
uint256 public s_requestId;
uint64 public s_subscriptionId;
address s_owner;
constructor() VRFConsumerBaseV2(vrfCoordinator) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
LINKTOKEN = LinkTokenInterface(link_token_contract);
s_owner = msg.sender;
//Create a new subscription when you deploy the contract.
createNewSubscription();
}
// 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;
}
// Create a new subscription when the contract is initially deployed.
function createNewSubscription() private onlyOwner {
s_subscriptionId = COORDINATOR.createSubscription();
// Add this contract as a consumer of its own subscription.
COORDINATOR.addConsumer(s_subscriptionId, address(this));
}
// Assumes this contract owns link.
// 1000000000000000000 = 1 LINK
function topUpSubscription(uint256 amount) external onlyOwner {
LINKTOKEN.transferAndCall(
address(COORDINATOR),
amount,
abi.encode(s_subscriptionId)
);
}
function addConsumer(address consumerAddress) external onlyOwner {
// Add a consumer contract to the subscription.
COORDINATOR.addConsumer(s_subscriptionId, consumerAddress);
}
function removeConsumer(address consumerAddress) external onlyOwner {
// Remove a consumer contract from the subscription.
COORDINATOR.removeConsumer(s_subscriptionId, consumerAddress);
}
function cancelSubscription(address receivingWallet) external onlyOwner {
// Cancel the subscription and send the remaining LINK to a wallet address.
COORDINATOR.cancelSubscription(s_subscriptionId, receivingWallet);
s_subscriptionId = 0;
}
// Transfer this contract's funds to an address.
// 1000000000000000000 = 1 LINK
function withdraw(uint256 amount, address to) external onlyOwner {
LINKTOKEN.transfer(to, amount);
}
modifier onlyOwner() {
require(msg.sender == s_owner);
_;
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2SubscriptionManager.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
To use this contract, compile and deploy it in Remix.
1. Open the contract in [Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2SubscriptionManager.sol).
2. Compile and deploy the contract using the Injected Provider environment. The contract includes all of the configuration variables that you need, but you can edit them if necessary. For a full list of available configuration variables, see the [Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks) page.
This contract automatically creates a new subscription when you deploy it. Read the `s_subscriptionId` variable to find your subscription ID. You can use this value to find the subscription at [vrf.chain.link](https://vrf.chain.link/).
3. In this example, the `topUpSubscription()` function sends LINK from your contract to the subscription. Fund your contract with at least three testnet LINK. Alternatively, you can send LINK directly to the subscription at [vrf.chain.link](https://vrf.chain.link/). Any address can provide funding to a subscription balance. If you need testnet LINK, you can get it from [faucets.chain.link](https://faucets.chain.link/sepolia/).
4. Run the `topUpSubscription()` function to send LINK from your contract to your subscription balance. For this example, specify a value of `3000000000000000000`, which is equivalent to three LINK.
5. Run the `requestRandomWords()` function. The request might take several minutes to process. Track the pending request status at [vrf.chain.link](https://vrf.chain.link/).
6. You can also add and test consumer contracts using the same programmatic subscription process:
1. Create and deploy a consumer contract that includes the following components:
- The `requestRandomWords()` function and the required variables and your subscription ID.
- The `fulfillRandomWords()` callback function.
You can use the example from the [Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number/#analyzing-the-contract) guide.
2. After you deploy the consumer contract, add it to the subscription as an approved consumer using the `addConsumer()` function on your subscription manager contract. Specify the address of your consumer contract.
3. On the consumer contract, run the `requestRandomWords()` function to request and receive random values. The request might take several minutes to process. Track the pending request status at [vrf.chain.link](https://vrf.chain.link/).
The consumer contract can continue to make requests until your subscription balance runs out. The subscription manager contract must maintain sufficient balance in the subscription so that the consumers can continue to operate.
4. If you need to remove consumer contracts from the subscription, use the `removeConsumer()` function. Specify the address of the consumer contract to be removed.
7. When you are done with your contracts and the subscription, run the `cancelSubscription()` function to close the subscription and send the remaining LINK to your wallet address. Specify the address of the receiving wallet.
## [Funding and requesting simultaneously](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription\#funding-and-requesting-simultaneously)
You can fund a subscription and request randomness in a single transaction. You must estimate how much the transaction might cost and determine the amount of funding to send to the subscription yourself. See the [Subscription billing](https://docs.chain.link/vrf/v2/subscription/#subscription-limits) page to learn how to estimate request costs.

```solidity
// Assumes this contract owns link
// You must estimate LINK cost yourself based on the gas lane and limits.
// 1_000_000_000_000_000_000 = 1 LINK
function fundAndRequestRandomWords(uint256 amount) external onlyOwner {
LINKTOKEN.transferAndCall(
address(COORDINATOR),
amount,
abi.encode(s_subscriptionId)
);
// Will revert if subscription is not set and funded.
s_requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
}
```
Add this function to your contracts if you need to provide funding simultaneously with your requests. The `transferAndCall()` function sends LINK from your contract to the subscription, and the `requestRandomWords()` function requests the random words. Your contract still needs the `fulfillRandomWords()` callback function to receive the random values.
## What's next
- [\> Subscription Manager UI](https://docs.chain.link/vrf/v2/subscription/ui)
- [\> Security Considerations](https://docs.chain.link/vrf/v2/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2/best-practices)
- [\> Migrating from VRF v1 to v2](https://docs.chain.link/vrf/v2/subscription/migration-from-v1)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## VRF Subscription Management
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Create and manage VRF V2.5 subscriptions](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#overview)
## [Using the VRF Subscription Manager](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#using-the-vrf-subscription-manager)
The [VRF Subscription Manager](https://vrf.chain.link/) is available to help you create and manage VRF V2.5 subscriptions. You can create and manage new V2.5 subscriptions, and manage existing V2 subscriptions, but you can no longer create new V2 subscriptions in the VRF Subscription Manager. Alternatively, you can [create and manage subscriptions programmatically](https://docs.chain.link/vrf/v2-5/subscription/create-manage#create-a-subscription-programmatically).
### [Create a subscription](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#create-a-subscription)
To create a VRF 2.5 subscription:
1. Use the VRF Subscription Manager at [vrf.chain.link](https://vrf.chain.link/). Connect your wallet in the upper right corner and then click **Create subscription**. The address of your connected wallet is automatically filled in the **Admin** address field.
2. When the subscription is successfully created, there will be an alert in the upper right corner telling you that the subscription was successfully created. Click **Home** to navigate back to your main dashboard.
3. Your new subscription shows in the **My Subscriptions** list, along with any previous V2 subscriptions you might have. Click the Subscription ID for your new subscription in the list.
### [Add a consumer](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#add-a-consumer)
To add a consuming contract:
1. On the details page for your subscription, select **Add Consumer**.
2. Provide the address of your consuming contract, and then select **Add Consumer** again. Confirm the resulting prompts in MetaMask or other wallet browser extension.
### [Fund your subscription](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#fund-your-subscription)
To fund your subscription:
1. On the page for your subscription, select the **Actions** menu and then select **Fund subscription**.
2. Your subscription has two balances: one for LINK, and one for the native token. Expand the **Asset** menu to select either LINK or the native token.
3. In **Amount to fund**, enter the amount you want to fund your subscription. Your wallet balance is displayed below the **Asset** field for easier reference. Select **Confirm** to fund your wallet, and then confirm the resulting prompts in MetaMask or other wallet browser extension.
### [Cancel your subscription and withdraw funds](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#cancel-your-subscription-and-withdraw-funds)
To withdraw your funds from a subscription, you must cancel the subscription.
1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
2. On your subscription details page, expand the **Actions** menu and select **Cancel subscription**. A field displays, prompting you to add the wallet address you want to send the remaining funds to.
3. 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.
If your subscription's admin address is a contract instead of an EOA, you may not be able to cancel the subscription directly. In this case, you must transfer ownership of your subscription to an EOA so that you can cancel the subscription and withdraw your funds.
## [Create a subscription programmatically](https://docs.chain.link/vrf/v2-5/subscription/create-manage\#create-a-subscription-programmatically)
If you prefer to create, fund and manage your subscriptions programmatically, you can either deploy a subscription manager contract or use your network's block explorer:
1. Create a new subscription for VRF v2.5:
Subscription contractUsing a block explorer
Deploy the [`SubscriptionManager` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionManager.sol). On deployment, the contract creates a new subscription and adds itself as a consumer to the new subscription.
1. Navigate to the VRF coordinator contract on the block explorer for the network you want to use (for example, Etherscan or Polygonscan). You can find the coordinator addresses with links to the block explorers on the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
2. In the **Contract** tab, select the **Write contract** tab. Connect your wallet to the block explorer.
3. Expand the `createSubscription` function and select the **Write** button. Follow the prompts in MetaMask to confirm the transaction.
4. Get your subscription ID for the next step, funding your subscription.
2. Fund your new VRF v2.5 subscription:
Subscription contractUsing a block explorer
1. [Fund your new `VRFv2PlusSubscriptionManager` contract](https://docs.chain.link/resources/fund-your-contract).
2. Call `topUpSubscription` from the `VRFv2PlusSubscriptionManager` contract. This function uses the LINK token contract's `transferAndCall` function to fund your new subscription.
1. [Fund your new `VRFv2PlusSubscriptionManager` contract](https://docs.chain.link/resources/fund-your-contract).
2. Navigate to the LINK token contract on the block explorer for the network you want to use (for example, Etherscan or Polygonscan). You can find the LINK token contract addresses with links to the block explorers on the [Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
3. In the **Contract** tab, select the **Write contract** tab. Connect your wallet to the block explorer.
4. Expand the `transferAndCall` function and fill in the following parameters:
- **to(address)**: The address of the VRF coordinator.
- **value(uint256)**: The amount you want to fund your subscription with.
- **data(bytes)**: The ABI-encoded subscription ID.
5. Select the **Write** button and follow the prompts in MetaMask to confirm the transaction.
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF Supported Networks
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Supported Networks - Direct Funding Method](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#overview)
Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract.
For implementation details, read [Introduction to Chainlink VRF v2 Direct funding method](https://docs.chain.link/vrf/v2/direct-funding).
## [Wrapper parameters](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#wrapper-parameters)
These parameters are configured in the VRF v2 Wrapper contract. You can view these values by running `getConfig` on the VRF v2 Wrapper or by viewing the VRF v2 Wrapper contract in a blockchain explorer.
- `uint32 stalenessSeconds`: How long the VRF v2 Wrapper waits until we consider the ETH/LINK price used for converting gas costs to LINK is stale and use `fallbackWeiPerUnitLink`.
- `uint32 wrapperGasOverhead`: The gas overhead of the VRF v2 Wrapper's `fulfillRandomWords` function.
- `uint32 coordinatorGasOverhead`: The gas overhead of the coordinator's `fulfillRandomWords` function.
- `uint8 maxNumWords`: Maximum number of words that can be requested in a single wrapped VRF request.
## [Coordinator parameters](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#coordinator-parameters)
Some parameters are important to know and are configured in the coordinator contract. You can view these values by running `getConfig` on the coordinator or by viewing the coordinator contract in a blockchain explorer.
- `uint16 minimumRequestConfirmations`: The minimum number of confirmation blocks on VRF requests before oracles respond
- `uint32 maxGasLimit`: The maximum gas limit supported for a `fulfillRandomWords` callback. Note that you still need to subtract the `wrapperGasOverhead` for the accurate limit, as explained in [Direct funding limits](https://docs.chain.link/vrf/v2/direct-funding/#limits).
## [Fee parameters](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#fee-parameters)
Fee parameters are configured in the VRF v2 Wrapper and the VRF v2 Coordinator contracts and specify the premium you pay per request in addition to the gas cost for the transaction. You can view them by running `getConfig` on the VRF v2 Wrapper:
- The `uint32 fulfillmentFlatFeeLinkPPM` parameter is a flat fee and defines the fees per request specified in millionths of LINK.
- The `uint8 wrapperPremiumPercentage` parameter defines the premium ratio in percentage. For example, a value of _0_ indicates no premium. A value of _15_ indicates a _15%_ premium.
The details for calculating the total transaction cost can be found [here](https://docs.chain.link/vrf/v2/direct-funding/#request-and-receive-data).
## [Configurations](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#configurations)
VRF v2 coordinators for direct funding are available on several networks. To see a list of coordinators for subscription funding, see the [Subscription Configurations](https://docs.chain.link/vrf/v2/subscription/supported-networks) page.
To use Chainlink VRF on certain networks, you may need to conduct token transfers. You can transfer tokens by using [Chainlink CCIP](https://docs.chain.link/ccip/tutorials/evm/transfer-tokens-from-contract), [Transporter](https://www.transporter.io/) or third-party applications such as [XSwap](https://xswap.link/).
### [Ethereum mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#ethereum-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA "0x514910771AF9Ca656af840dff83E8264EcF986CA") |
| VRF Wrapper | [0x5A861794B927983406fCE1D062e00b9368d97Df6](https://etherscan.io/address/0x5A861794B927983406fCE1D062e00b9368d97Df6 "0x5A861794B927983406fCE1D062e00b9368d97Df6") |
| VRF Coordinator | [0x271682DEB8C4E0901D1a1550aD2e64D568E69909](https://etherscan.io/address/0x271682DEB8C4E0901D1a1550aD2e64D568E69909 "0x271682DEB8C4E0901D1a1550aD2e64D568E69909") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.25 LINK |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Sepolia testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#sepolia-testnet)
Testnet LINK and ETH are available from [faucets.chain.link](https://faucets.chain.link/sepolia).
Testnet ETH is also available from several public [ETH faucets](https://faucetlink.to/sepolia).
| Item | Value |
| --- | --- |
| LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789 "0x779877A7B0D9E8603169DdbD7836e478b4624789") |
| | |
| VRF Wrapper | [0xab18414CD93297B0d12ac29E63Ca20f515b3DB46](https://sepolia.etherscan.io/address/0xab18414CD93297B0d12ac29E63Ca20f515b3DB46 "0xab18414CD93297B0d12ac29E63Ca20f515b3DB46") |
| VRF Coordinator | [0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625](https://sepolia.etherscan.io/address/0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625 "0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.25 LINK |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [BNB Chain mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#bnb-chain-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75 "0x404460C6A5EdE2D891e8297795264fDe62ADBB75") |
| VRF Wrapper | [0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42](https://bscscan.com/address/0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42 "0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42") |
| VRF Coordinator | [0xc587d9053cd1118f25F645F9E08BB98c9712A4EE](https://bscscan.com/address/0xc587d9053cd1118f25F645F9E08BB98c9712A4EE "0xc587d9053cd1118f25F645F9E08BB98c9712A4EE") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.005 LINK |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [BNB Chain testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#bnb-chain-testnet)
Testnet LINK is available from [https://faucets.chain.link/bnb-chain-testnet](https://faucets.chain.link/bnb-chain-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06](https://testnet.bscscan.com/address/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 "0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06") |
| VRF Wrapper | [0x699d428ee890d55D56d5FC6e26290f3247A762bd](https://testnet.bscscan.com/address/0x699d428ee890d55D56d5FC6e26290f3247A762bd "0x699d428ee890d55D56d5FC6e26290f3247A762bd") |
| VRF Coordinator | [0x6A2AAd07396B36Fe02a22b33cf443582f682c82f](https://testnet.bscscan.com/address/0x6A2AAd07396B36Fe02a22b33cf443582f682c82f "0x6A2AAd07396B36Fe02a22b33cf443582f682c82f") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.005 LINK |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Polygon mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#polygon-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1 "0xb0897686c545045aFc77CF20eC7A532E3120E0F1") |
| VRF Wrapper | [0x4e42f0adEB69203ef7AaA4B7c414e5b1331c14dc](https://polygonscan.com/address/0x4e42f0adEB69203ef7AaA4B7c414e5b1331c14dc "0x4e42f0adEB69203ef7AaA4B7c414e5b1331c14dc") |
| VRF Coordinator | [0xAE975071Be8F8eE67addBC1A82488F1C24858067](https://polygonscan.com/address/0xAE975071Be8F8eE67addBC1A82488F1C24858067 "0xAE975071Be8F8eE67addBC1A82488F1C24858067") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.0005 LINK |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Polygon Amoy testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#polygon-amoy-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904 "0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904") |
| VRF Coordinator | [0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908](https://amoy.polygonscan.com/address/0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908 "0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908") |
| 500 gwei Key Hash | `0x3f631d5ec60a0ce16203bcd6aff7ffbc423e22e452786288e172d467354304c8` |
| Premium | 0.0005 LINK |
| Max Gas Limit | 2,500,000 |
| Minimum Confirmations | 3 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Avalanche mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#avalanche-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3 "0x5947BB275c521040051D82396192181b413227A3") |
| VRF Wrapper | [0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42](https://snowtrace.io/address/0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42 "0x721DFbc5Cfe53d32ab00A9bdFa605d3b8E1f3f42") |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://snowtrace.io/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Avalanche Fuji testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#avalanche-fuji-testnet)
Testnet LINK is available from [https://faucets.chain.link/fuji](https://faucets.chain.link/fuji)
| Item | Value |
| --- | --- |
| LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846 "0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846") |
| | |
| VRF Wrapper | [0x9345AC54dA4D0B5Cda8CB749d8ef37e5F02BBb21](https://testnet.snowtrace.io/address/0x9345AC54dA4D0B5Cda8CB749d8ef37e5F02BBb21 "0x9345AC54dA4D0B5Cda8CB749d8ef37e5F02BBb21") |
| VRF Coordinator | [0x2eD832Ba664535e5886b75D64C46EB9a228C2610](https://testnet.snowtrace.io/address/0x2eD832Ba664535e5886b75D64C46EB9a228C2610 "0x2eD832Ba664535e5886b75D64C46EB9a228C2610") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Fantom mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#fantom-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0x6F43FF82CCA38001B6699a8AC47A2d0E66939407](https://ftmscan.com/token/0x6F43FF82CCA38001B6699a8AC47A2d0E66939407 "0x6F43FF82CCA38001B6699a8AC47A2d0E66939407") |
| | |
| VRF Wrapper | [0xeDA5B00fB33B13c730D004Cf5D1aDa1ac191Ddc2](https://ftmscan.com/address/0xeDA5B00fB33B13c730D004Cf5D1aDa1ac191Ddc2 "0xeDA5B00fB33B13c730D004Cf5D1aDa1ac191Ddc2") |
| VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://ftmscan.com/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634 "0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.0005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Fantom testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#fantom-testnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F](https://testnet.ftmscan.com/address/0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F "0xfaFedb041c0DD4fA2Dc0d87a6B0979Ee6FA7af5F") |
| | |
| VRF Wrapper | [0x38336BDaE79747a1d2c4e6C67BBF382244287ca6](https://testnet.ftmscan.com/address/0x38336BDaE79747a1d2c4e6C67BBF382244287ca6 "0x38336BDaE79747a1d2c4e6C67BBF382244287ca6") |
| VRF Coordinator | [0xbd13f08b8352A3635218ab9418E340c60d6Eb418](https://testnet.ftmscan.com/address/0xbd13f08b8352A3635218ab9418E340c60d6Eb418 "0xbd13f08b8352A3635218ab9418E340c60d6Eb418") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.0005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Arbitrum mainnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#arbitrum-mainnet)
| Item | Value |
| --- | --- |
| LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4 "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4") |
| | |
| VRF Coordinator | [0x41034678D6C633D8a95c75e1138A360a28bA15d1](https://arbiscan.io/address/0x41034678D6C633D8a95c75e1138A360a28bA15d1 "0x41034678D6C633D8a95c75e1138A360a28bA15d1") |
| VRF Wrapper | [0x2D159AE3bFf04a10A355B608D22BDEC092e934fa](https://arbiscan.io/address/0x2D159AE3bFf04a10A355B608D22BDEC092e934fa "0x2D159AE3bFf04a10A355B608D22BDEC092e934fa") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.0005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
### [Arbitrum Sepolia testnet](https://docs.chain.link/vrf/v2/direct-funding/supported-networks\#arbitrum-sepolia-testnet)
Testnet LINK is available from [https://faucets.chain.link/arbitrum-sepolia](https://faucets.chain.link/arbitrum-sepolia)
| Item | Value |
| --- | --- |
| LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E") |
| | |
| VRF Coordinator | [0x50d47e4142598E3411aA864e08a44284e471AC6f](https://sepolia.arbiscan.io/address/0x50d47e4142598E3411aA864e08a44284e471AC6f "0x50d47e4142598E3411aA864e08a44284e471AC6f") |
| VRF Wrapper | [0x1D3bb92db7659F2062438791F131CFA396dfb592](https://sepolia.arbiscan.io/address/0x1D3bb92db7659F2062438791F131CFA396dfb592 "0x1D3bb92db7659F2062438791F131CFA396dfb592") |
| Wrapper Premium Percentage | 0 |
| Coordinator Flat Fee | 0.0005 LINK |
| Minimum Confirmations | 1 |
| Maximum Confirmations | 200 |
| Maximum Random Values | 10 |
| Wrapper Gas overhead | 40000 |
| Coordinator Gas Overhead | 90000 |
## Get the latest Chainlink content straight to your inbox.
Email Address
## Local Testing for Chainlink VRF
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Local testing using a Mock contract](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#overview)
This guide explains how to test Chainlink VRF v2 on a [Remix IDE](https://remix-ide.readthedocs.io/en/latest/run.html#environment) sandbox blockchain environment. **Note**: You can reuse the same logic on another development environment, such as Hardhat or Truffle. For example, read the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).
## [Benefits of local testing](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#benefits-of-local-testing)
Testing locally using mock contracts saves you time and resources during development. Some of the key benefits include:
- Faster feedback loop: Immediate feedback on the functionality and correctness of your smart contracts. This helps you quickly identify and fix issues without waiting for transactions to be mined/validated on a testnet.
- Saving your native testnet gas: Deploying and interacting with contracts requires paying gas fees. Although native testnet gas does not have any associated value, supply is limited by public faucets. Using mock contracts locally allows you to test your contracts freely without incurring any expenses.
- Controlled environment: Local testing allows you to create a controlled environment where you can manipulate various parameters, such as block time and gas prices, to test your smart contracts' function as expected under different conditions.
- Isolated testing: You can focus on testing individual parts of your contract, ensuring they work as intended before integrating them with other components.
- Easier debugging: Because local tests run on your machine, you have better control over the debugging process. You can set breakpoints, inspect variables, and step through your code to identify and fix issues.
- Comprehensive test coverage: You can create test cases to cover all possible scenarios and edge cases.
## [Testing logic](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#testing-logic)
Complete the following tasks to test your VRF v2 consumer locally:
1. Deploy the [VRFCoordinatorV2Mock](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol). This contract is a mock of the [VRFCoordinatorV2](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol) contract.
2. Call the VRFCoordinatorV2Mock [createSubscription function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L194) to create a new subscription.
3. Call the VRFCoordinatorV2Mock [fundSubscription function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L156) to fund your newly created subscription. **Note**: You can fund with an arbitrary amount.
4. Deploy your VRF consumer contract.
5. Call the VRFCoordinatorV2Mock [addConsumer function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L230) to add your consumer contract to your subscription.
6. Request random words from your consumer contract.
7. Call the VRFCoordinatorV2Mock [fulfillRandomWords function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L108) to fulfill your consumer contract request.
## [Testing](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#testing)
### [Open the contracts on RemixIDE](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#open-the-contracts-on-remixide)
Open _VRFCoordinatorV2Mock_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFCoordinatorV2Mock.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _VRFv2Consumer_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/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.
*/
/**
* @title The RandomNumberConsumerV2 contract
* @notice A contract that gets random values from Chainlink VRF V2
*/
contract RandomNumberConsumerV2 is VRFConsumerBaseV2 {
VRFCoordinatorV2Interface immutable COORDINATOR;
// Your subscription ID.
uint64 immutable s_subscriptionId;
// 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 immutable s_keyHash;
// 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 constant CALLBACK_GAS_LIMIT = 100000;
// The default is 3, but you can set this higher.
uint16 constant REQUEST_CONFIRMATIONS = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 constant NUM_WORDS = 2;
uint256[] public s_randomWords;
uint256 public s_requestId;
address s_owner;
event ReturnedRandomness(uint256[] randomWords);
/**
* @notice Constructor inherits VRFConsumerBaseV2
*
* @param subscriptionId - the subscription ID that this contract uses for funding requests
* @param vrfCoordinator - coordinator, check https://docs.chain.link/docs/vrf-contracts/#configurations
* @param keyHash - the gas lane to use, which specifies the maximum gas price to bump to
*/
constructor(
uint64 subscriptionId,
address vrfCoordinator,
bytes32 keyHash
) VRFConsumerBaseV2(vrfCoordinator) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
s_keyHash = keyHash;
s_owner = msg.sender;
s_subscriptionId = subscriptionId;
}
/**
* @notice Requests randomness
* Assumes the subscription is funded sufficiently; "Words" refers to unit of data in Computer Science
*/
function requestRandomWords() external onlyOwner {
// Will revert if subscription is not set and funded.
s_requestId = COORDINATOR.requestRandomWords(
s_keyHash,
s_subscriptionId,
REQUEST_CONFIRMATIONS,
CALLBACK_GAS_LIMIT,
NUM_WORDS
);
}
/**
* @notice Callback function used by VRF Coordinator
*
* @param - id of the request
* @param randomWords - array of random results from VRF Coordinator
*/
function fulfillRandomWords(
uint256 /* requestId */,
uint256[] memory randomWords
) internal override {
s_randomWords = randomWords;
emit ReturnedRandomness(randomWords);
}
modifier onlyOwner() {
require(msg.sender == s_owner);
_;
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFv2Consumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Your RemixIDE file explorer should display _VRFCoordinatorV2Mock.sol_ and _VRFv2Consumer.sol_:

### [Deploy VRFCoordinatorV2Mock](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#deploy-vrfcoordinatorv2mock)
1. Open _VRFCoordinatorV2Mock.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _VRFCoordinatorV2Mock_.

3. Under _DEPLOY_, fill in the `_BASEFEE` and `_GASPRICELINK`. These variables are used in the _VRFCoordinatorV2Mock_ contract to represent the base fee and the gas price (in LINK tokens) for the VRF requests. You can set: `_BASEFEE=100000000000000000` and `_GASPRICELINK=1000000000`.
4. Click on _transact_ to deploy the _VRFCoordinatorV2Mock_ contract.
5. Once deployed, you should see the _VRFCoordinatorV2Mock_ contract under _Deployed Contracts_.

6. Note the address of the deployed contract.
### [Create and fund a subscription](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#create-and-fund-a-subscription)
1. Click on `createSubscription` to create a new subscription.
2. In the RemixIDE console, read your transaction decoded output to find the subscription ID. In this example, the subscription ID is _1_.

3. Click on `fundSubscription` to fund your subscription. In this example, you can set the `_subid` to `1` (which is your newly created subscription ID) and the `_amount` to `1000000000000000000`.
### [Deploy the VRF consumer contract](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#deploy-the-vrf-consumer-contract)
1. In the file explorer, open _VRFv2Consumer.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _RandomNumberConsumerV2_.

3. Under _DEPLOY_, fill in `SUBSCRIPTIONID` with your subscription ID, `vrfCoordinator` with the deployed _VRFCoordinatorV2Mock_ address and, _KEYHASH_ with an arbitrary `bytes32` (In this example, you can set the _KEYHASH_ to `0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc`).
4. Click on _transact_ to deploy the _RandomNumberConsumerV2_ contract.
5. After the consumer contract is deployed, you should see the _RandomNumberConsumerV2_ contract under _Deployed Contracts_.

6. Note the address of the deployed contract.
### [Add the consumer contract to your subscription](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#add-the-consumer-contract-to-your-subscription)
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2Mock_ contract.
2. Click on _addConsumer_ and fill in the `_subid` with your subscription ID and `_consumer` with your deployed consumer contract address.

3. Click on _transact_.
### [Request random words](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#request-random-words)
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberConsumerV2_ contract.
2. Click on `requestRandomWords`.

3. In the RemixIDE console, read your transaction logs to find the VRF request ID. In this example, the request ID is _1_.

4. Note your request ID.
### [Fulfill the VRF request](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#fulfill-the-vrf-request)
Because you are testing on a local blockchain environment, you must fulfill the VRF request yourself.
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2Mock_ contract.
2. Click `fulfillRandomWords` and fill in `_requestId` with your VRF request ID and `_consumer` with your consumer contract address.

3. Click on `transact`.
### [Check the results](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#check-the-results)
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberConsumerV2_ contract.
2. Click on `s_requestId` to display the last request ID. In this example, the output is _1_.

3. Each time you make a VRF request, your consumer contract requests two random words. After the request is fulfilled, the two random words are stored in the `s_randomWords` array. You can check the stored random words by reading the two first indexes of the `s_randomWords` array. To do so, click on the _s\_randomWords_ function and:
1. Fill in the index with _0_ then click on _call_ to read the first random word.

2. Fill in the index with _1_ then click on _call_ to read the second random word.

## [Next steps](https://docs.chain.link/vrf/v2/subscription/examples/test-locally\#next-steps)
This guide demonstrated how to test a VRF v2 consumer contract on your local blockchain. We made the guide on RemixIDE for learning purposes, but you can reuse the same [testing logic](https://docs.chain.link/vrf/v2/subscription/examples/test-locally#testing-logic) on another development environment, such as Truffle or Hardhat. For example, read the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).
## Get the latest Chainlink content straight to your inbox.
Email Address
## Testing Chainlink VRF Locally
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Local testing using a Mock contract](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#overview)
This guide explains how to test Chainlink VRF v2 on a [Remix IDE](https://remix-ide.readthedocs.io/en/latest/run.html#environment) sandbox blockchain environment. **Note**: You can reuse the same logic on another development environment, such as Hardhat or Truffle. For example, read the Hardhat Starter Kit [RandomNumberDirectFundingConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberDirectFundingConsumer.spec.js).
## [Benefits of local testing](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#benefits-of-local-testing)
Testing locally using mock contracts saves you time and resources during development. Some of the key benefits include:
- Faster feedback loop: Immediate feedback on the functionality and correctness of your smart contracts. This helps you quickly identify and fix issues without waiting for transactions to be mined/validated on a testnet.
- Saving your native testnet gas: Deploying and interacting with contracts requires paying gas fees. Although native testnet gas does not have any associated value, supply is limited by public faucets. Using mock contracts locally allows you to test your contracts freely without incurring any expenses.
- Controlled environment: Local testing allows you to create a controlled environment where you can manipulate various parameters, such as block time and gas prices, to test your smart contracts' function as expected under different conditions.
- Isolated testing: You can focus on testing individual parts of your contract, ensuring they work as intended before integrating them with other components.
- Easier debugging: Because local tests run on your machine, you have better control over the debugging process. You can set breakpoints, inspect variables, and step through your code to identify and fix issues.
- Comprehensive test coverage: You can create test cases to cover all possible scenarios and edge cases.
## [Testing logic](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#testing-logic)
Complete the following tasks to test your VRF v2 consumer locally:
01. Deploy the [VRFCoordinatorV2Mock](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol). This contract is a mock of the [VRFCoordinatorV2](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol) contract.
02. Deploy the [MockV3Aggregator](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/mocks/MockV3Aggregator.sol) contract.
03. Deploy the [LinkToken](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol) contract.
04. Deploy the [VRFV2Wrapper](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2Wrapper.sol) contract.
05. Call the VRFV2Wrapper [setConfig function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2Wrapper.sol#L119) to set wrapper specific parameters.
06. Fund the VRFv2Wrapper subscription.
07. Call the VRFCoordinatorV2Mock [addConsumer function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L230) to add the wrapper contract to your subscription.
08. Deploy your VRF consumer contract.
09. Fund your consumer contract with LINK tokens.
10. Request random words from your consumer contract.
11. Call the VRFCoordinatorV2Mock [fulfillRandomWords function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L108) to fulfill your consumer contract request.
## [Prerequisites](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#prerequisites)
This guide will require you to finetune the gas limit when fulfilling requests. When writing, manually setting up the gas limits on RemixIDE is not supported, so you will use RemixIDE in conjunction with [Metamask](https://metamask.io/).
[Ganache](https://trufflesuite.com/ganache/) lets you quickly fire up a personal Ethereum blockchain. If you still need to install Ganache, follow the [official guide](https://trufflesuite.com/docs/ganache/quickstart/).
1. Once Ganache is installed, click the _QUICKSTART_ button to start a local Ethereum node.

**Note**: Make sure to note the RPC server. In this example, the RPC server is _[http://127.0.0.1:7545/](http://127.0.0.1:7545/)_.
2. Follow the Metamask [official guide](https://support.metamask.io/hc/en-us/articles/360043227612-How-to-add-a-custom-network-RPC#h_01G63GGJ83DGDRCS2ZWXM37CV5) to add a custom network manually.

3. Import a Ganache account into Metamask.
1. On Ganache, click on the _key_ symbol of the first account:

2. Copy the private key:

3. Follow the Metamask [official guide](https://support.metamask.io/hc/en-us/articles/360015489331-How-to-import-an-account) to import an account using a private key.
4. Your Metamask is connected to _Ganache_, and you should have access to the newly imported account.

## [Testing](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#testing)
### [Open the contracts on RemixIDE](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#open-the-contracts-on-remixide)
Open _VRFCoordinatorV2Mock_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFCoordinatorV2Mock.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _MockV3Aggregator_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/shared/mocks/MockV3Aggregator.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/MockV3Aggregator.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _LinkToken_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@chainlink/contracts/src/v0.8/shared/token/ERC677/LinkToken.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/LinkToken.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _VRFV2Wrapper_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;
import "@chainlink/contracts/src/v0.8/vrf/VRFV2Wrapper.sol";
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/VRFV2Wrapper.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Open _RandomNumberDirectFundingConsumerV2_ and compile in Remix:

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that directly pays for each request.
pragma solidity ^0.8.7;
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {VRFV2WrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UNAUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract RandomNumberDirectFundingConsumerV2 is
VRFV2WrapperConsumerBase,
ConfirmedOwner
{
event RequestSent(uint256 requestId, uint32 numWords, uint256 paid);
event RequestFulfilled(
uint256 requestId,
uint256[] randomWords,
uint256 payment
);
error InsufficientFunds(uint256 balance, uint256 paid);
error RequestNotFound(uint256 requestId);
error LinkTransferError(address sender, address receiver, uint256 amount);
struct RequestStatus {
uint256 paid; // amount paid in link
bool fulfilled; // whether the request has been successfully fulfilled
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// configuration: https://docs.chain.link/vrf/v2/direct-funding/supported-networks#configurations
constructor(
address _linkAddress,
address _wrapperAddress
)
ConfirmedOwner(msg.sender)
VRFV2WrapperConsumerBase(_linkAddress, _wrapperAddress)
{}
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. 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.
// The default is 3, but you can set this higher.
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFV2Wrapper.getConfig().maxNumWords.
function requestRandomWords(
uint32 _callbackGasLimit,
uint16 _requestConfirmations,
uint32 _numWords
) external onlyOwner returns (uint256 requestId) {
requestId = requestRandomness(
_callbackGasLimit,
_requestConfirmations,
_numWords
);
uint256 paid = VRF_V2_WRAPPER.calculateRequestPrice(_callbackGasLimit);
uint256 balance = LINK.balanceOf(address(this));
if (balance < paid) revert InsufficientFunds(balance, paid);
s_requests[requestId] = RequestStatus({
paid: paid,
randomWords: new uint256[](0),
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, _numWords, paid);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
RequestStatus storage request = s_requests[_requestId];
if (request.paid == 0) revert RequestNotFound(_requestId);
request.fulfilled = true;
request.randomWords = _randomWords;
emit RequestFulfilled(_requestId, _randomWords, request.paid);
}
function getNumberOfRequests() external view returns (uint256) {
return requestIds.length;
}
function getRequestStatus(
uint256 _requestId
)
external
view
returns (uint256 paid, bool fulfilled, uint256[] memory randomWords)
{
RequestStatus memory request = s_requests[_requestId];
if (request.paid == 0) revert RequestNotFound(_requestId);
return (request.paid, request.fulfilled, request.randomWords);
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawLink(address _receiver) public onlyOwner {
bool success = LINK.transfer(_receiver, LINK.balanceOf(address(this)));
if (!success)
revert LinkTransferError(
msg.sender,
_receiver,
LINK.balanceOf(address(this))
);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/mock/RandomNumberDirectFundingConsumerV2.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
Your RemixIDE file explorer should display the opened contracts:

### [Select the correct RemixIDE environment](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#select-the-correct-remixide-environment)
Under _DEPLOY & RUN TRANSACTIONS_:
1. Set the Environment to _Injected Provider - Metamask_:

2. On Metamask, connect your Ganache account to the Remix IDE.

3. Click on Connect. The RemixIDE environment should be set to the correct environment, and the account should be the Ganache account.

### [Deploy VRFCoordinatorV2Mock](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#deploy-vrfcoordinatorv2mock)
1. Open _VRFCoordinatorV2Mock.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _VRFCoordinatorV2Mock_.

3. Under _DEPLOY_, fill in the `_BASEFEE` and `_GASPRICELINK`. These variables are used in the _VRFCoordinatorV2Mock_ contract to represent the base fee and the gas price (in LINK tokens) for the VRF requests. You can set: `_BASEFEE=100000000000000000` and `_GASPRICELINK=1000000000`.
4. Click on _transact_ to deploy the _VRFCoordinatorV2Mock_ contract.
5. A Metamask popup will open. Click on _Confirm_.
6. Once deployed, you should see the _VRFCoordinatorV2Mock_ contract under _Deployed Contracts_.

7. Note the address of the deployed contract.
### [Deploy MockV3Aggregator](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#deploy-mockv3aggregator)
The _MockV3Aggregator_ contract is designed for testing purposes, allowing you to simulate an oracle price feed without interacting with the existing Chainlink network.
1. Open _MockV3Aggregator.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _MockV3Aggregator_.

3. Under _DEPLOY_, fill in `_DECIMALS` and `_INITIALANSWER`. These variables are used in the _MockV3Aggregator_ contract to represent the number of decimals the aggregator's answer should have and the most recent price feed answer. You can set: `_DECIMALS=18` and `_INITIALANSWER=3000000000000000` (We are considering that `1 LINK = 0.003 native gas tokens`).
4. Click on _transact_ to deploy the _MockV3Aggregator_ contract.
5. A Metamask popup will open. Click on _Confirm_.
6. Once deployed, you should see the _MockV3Aggregator_ contract under _Deployed Contracts_.

7. Note the address of the deployed contract.
### [Deploy LinkToken](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#deploy-linktoken)
The Chainlink VRF v2 direct funding method requires your consumer contract to pay for VRF requests in LINK. Therefore, you have to deploy the _LinkToken_ contract to your local blockchain.
1. Open _LinkToken.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _LinkToken_.

3. Under _DEPLOY_, click on _transact_ to deploy the _LinkToken_ contract.
4. A Metamask popup will open. Click on _Confirm_.
5. Once deployed, you should see the _LinkToken_ contract under _Deployed Contracts_.

6. Note the address of the deployed contract.
### [Deploy VRFV2Wrapper](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#deploy-vrfv2wrapper)
As the VRF v2 direct funding [end-to-end diagram](https://docs.chain.link/vrf/v2/direct-funding#request-and-receive-data) explains, the _VRFV2Wrapper_ acts as a wrapper for the coordinator contract.
1. Open _VRFV2Wrapper.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _VRFV2Wrapper_.

3. Under _DEPLOY_, fill in `_LINK` with the _LinkToken_ contract address, `_LINKETHFEED` with the _MockV3Aggregator_ contract address, and `_COORDINATOR` with the _VRFCoordinatorV2Mock_ contract address.
4. click on _transact_ to deploy the _VRFV2Wrapper_ contract.
5. A Metamask popup will open. Click on _Confirm_.
6. Once deployed, you should see the _VRFV2Wrapper_ contract under _Deployed Contracts_.

7. Note the address of the deployed contract.
### [Configure the VRFV2Wrapper](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#configure-the-vrfv2wrapper)
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFV2Wrapper_ contract.
2. Click on `setConfig` and fill in `_wrapperGasOverhead` with `60000`, `_coordinatorGasOverhead` with `52000`, `_wrapperPremiumPercentage` with `10`, `_keyHash` with `0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc`, and `_maxNumWords` with `10`. **Note** on these variables:
1. `_wrapperGasOverhead`: This variable reflects the gas overhead of the wrapper's fulfillRandomWords function. The cost for this gas is passed to the user.
2. `_coordinatorGasOverhead`: This variable reflects the gas overhead of the coordinator's `fulfillRandomWords` function. The cost for this gas is billed to the _VRFV2Wrapper_ subscription and must, therefore, be included in the VRF v2 direct funding requests pricing.
3. `_wrapperPremiumPercentage`: This variable is the premium ratio in percentage. For example, a value of 0 indicates no premium. A value of 15 indicates a 15 percent premium.
4. `_keyHash`: The gas lane key hash value is the maximum gas price you are willing to pay for a request in wei.
5. `_maxNumWords`: This variable is the maximum number of words requested in a VRF v2 direct funding request.

3. click on _transact_.
4. A Metamask popup will open. Click on _Confirm_.
### [Fund the VRFV2Wrapper subscription](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#fund-the-vrfv2wrapper-subscription)
When deployed, the _VRFV2Wrapper_ contract creates a new subscription and adds itself to the newly created subscription. If you started this guide from scratch, the subscription ID should be 1.
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2Mock_ contract.
2. Click `fundSubscription` to fund the _VRFV2Wrapper_ subscription. In this example, you can set the `_subid` to `1` (which is your newly created subscription ID) and the `_amount` to `10000000000000000000` (10 LINK).
3. A Metamask popup will open. Click on _Confirm_.
### [Deploy the VRF consumer contract](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#deploy-the-vrf-consumer-contract)
1. In the file explorer, open _RandomNumberDirectFundingConsumerV2.sol_.
2. Under _DEPLOY & RUN TRANSACTIONS_, select _RandomNumberDirectFundingConsumerV2_.

3. Under _DEPLOY_, fill in `_LINKADDRESS_` with the _LinkToken_ contract address, and `_WRAPPERADDRESS_` with the deployed _VRFV2Wrapper_ address.
4. Click on _transact_ to deploy the _RandomNumberDirectFundingConsumerV2_ contract.
5. A Metamask popup will open. Click on _Confirm_.
6. Once deployed, you should see the _RandomNumberDirectFundingConsumerV2_ contract under _Deployed Contracts_.

7. Note the address of the deployed contract.
### [Fund your VRF consumer contract](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#fund-your-vrf-consumer-contract)
1. Under _Deployed Contracts_, open the functions list of your deployed _LinkToken_ contract.
2. Click on _transfer_ and fill in the `_to` with your consumer contract address and `_value` with LINK tokens amount. For this example, you can set the `_value` to `10000000000000000000` (10 LINK).

3. Click on _transact_.
4. A Metamask popup will open. Click on _Confirm_.
### [Request random words](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#request-random-words)
Request three random words.
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberConsumerV2_ contract.
2. In `requestRandomWords`, fill in `_callbackGasLimit` with `300000`, `_requestConfirmations` with `3` and `_numWords` with `3`.

3. Click on _transact_.
4. A Metamask popup will open.
5. Click on _Confirm_.
6. In the RemixIDE console, read your transaction logs to find the VRF request ID. In this example, the request ID is _1_.

7. Note your request ID.
### [Fulfill the VRF request](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#fulfill-the-vrf-request)
Because you are testing on a local blockchain environment, you must fulfill the VRF request yourself.
1. Under _Deployed Contracts_, open the functions list of your deployed _VRFCoordinatorV2Mock_ contract.
2. Click `fulfillRandomWords` and fill in `_requestId` with your VRF request ID and `_consumer` with the _VRFV2Wrapper_ contract address.

3. Click on `transact`.
4. A Metamask popup will open.
5. Click on _Confirm_.
6. In the RemixIDE console, read your transaction logs to find the random words.

### [Check the results](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#check-the-results)
1. Under _Deployed Contracts_, open the functions list of your deployed _RandomNumberDirectFundingConsumerV2_ contract.
2. Click on `lastRequestId` to display the last request ID. In this example, the output is _1_.

3. Click on `getRequestStatus` with `_requestId` equal to `1`:

4. You will get the amount paid, the status, and the random words.

## [Next steps](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally\#next-steps)
This guide demonstrated how to test a VRF v2 consumer contract on your local blockchain. We made the guide on RemixIDE for learning purposes, but you can reuse the same [testing logic](https://docs.chain.link/vrf/v2/direct-funding/examples/test-locally#testing-logic) on another development environment, such as Truffle or Hardhat. For example, read the Hardhat Starter Kit [RandomNumberDirectFundingConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberDirectFundingConsumer.spec.js).
## Get the latest Chainlink content straight to your inbox.
Email Address
## Get Random Numbers
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Get a Random Number \[v1\]](https://docs.chain.link/vrf/v1/examples/get-a-random-number\#overview)
This page explains how to get a random number inside a smart contract using Chainlink VRF.
## [Random Number Consumer](https://docs.chain.link/vrf/v1/examples/get-a-random-number\#random-number-consumer)
Chainlink VRF follows the [Request & Receive Data](https://docs.chain.link/any-api/introduction) cycle. To consume randomness, your contract should inherit from [VRFConsumerBase](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFConsumerBase.sol) and define two required functions:
- `requestRandomness`, which makes the initial request for randomness.
- `fulfillRandomness`, which is the function that receives and does something with verified randomness.
The contract should own enough LINK to pay the specified fee. The beginner walkthrough explains how to [fund your contract](https://docs.chain.link/resources/fund-your-contract).
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](https://docs.chain.link/vrf/v1/supported-networks).
- `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

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import {VRFConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBase.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.
*/
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
contract RandomNumberConsumer is VRFConsumerBase {
event RequestFulfilled(bytes32 requestId, uint256 randomness);
bytes32 internal keyHash;
uint256 internal fee;
uint256 public randomResult;
/**
* Constructor inherits VRFConsumerBase
*
* Network: Sepolia
* Chainlink VRF Coordinator address: 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
* LINK token address: 0x779877A7B0D9E8603169DdbD7836e478b4624789
* Key Hash: 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c
*/
constructor()
VRFConsumerBase(
0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625, // VRF Coordinator
0x779877A7B0D9E8603169DdbD7836e478b4624789 // LINK Token
)
{
keyHash = 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
fee = 0.1 * 10 ** 18; // 0.1 LINK (Varies by network)
}
/**
* Requests randomness
*/
function getRandomNumber() public returns (bytes32 requestId) {
require(
LINK.balanceOf(address(this)) >= fee,
"Not enough LINK - fill contract with faucet"
);
return requestRandomness(keyHash, fee);
}
/**
* Callback function used by VRF Coordinator
*/
function fulfillRandomness(
bytes32 requestId,
uint256 randomness
) internal override {
randomResult = randomness;
emit RequestFulfilled(requestId, randomness);
}
// function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/RandomNumberConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
## [Getting More Randomness](https://docs.chain.link/vrf/v1/examples/get-a-random-number\#getting-more-randomness)
If you are looking for how to turn a single result into multiple random numbers, check out our guide on [Randomness Expansion](https://docs.chain.link/vrf/v1/best-practices/#getting-multiple-random-numbers).
## [Network Congestion and Responsiveness](https://docs.chain.link/vrf/v1/examples/get-a-random-number\#network-congestion-and-responsiveness)
Network congestion can occur on all blockchains from time to time, which may result in transactions taking longer to get included in a block. During times of network congestion, the VRF service will continue responding to randomness requests, but fulfillment response times will corresponding increase based on the level of congestion. It is important you account for this in your use case and set expectations accordingly.
## What's next
- [\> Migrate to VRF V2.5](https://docs.chain.link/vrf/v2-5/migration-from-v1)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Get Random Numbers
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Get a Random Number](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#overview)
This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2.5. The guide uses the Subscription Manager to create and manage your subscription. Alternatively, you can also [create and manage subscriptions programmatically](https://docs.chain.link/vrf/v2-5/subscription/create-manage#create-a-subscription-programmatically). To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Requirements](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#requirements)
This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
- [The Remix IDE](https://remix.ethereum.org/)
- [MetaMask](https://metamask.io/)
- [Sepolia testnet ETH](https://docs.chain.link/resources/link-token-contracts/#sepolia-testnet)
If you are new to developing smart contracts on Ethereum, see the [Getting Started](https://docs.chain.link/getting-started/conceptual-overview) guide to learn the basics.
## [Create and fund a subscription](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#create-and-fund-a-subscription)
For this example, create a new subscription on the Sepolia testnet.
1. Open MetaMask and set it to use the Sepolia testnet. The [Subscription Manager](https://vrf.chain.link/) detects your network based on the active network in MetaMask.
2. Check MetaMask to make sure you have testnet ETH and LINK on Sepolia. You can get testnet ETH and LINK at [faucets.chain.link/sepolia](https://faucets.chain.link/sepolia/).
3. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/).
[Open the Subscription Manager](https://vrf.chain.link/)
4. Click **Create Subscription** and follow the instructions to create a new subscription account. If you connect your wallet to the Subscription Manager, the **Admin address** for your subscription is prefilled and not editable. Optionally, you can enter an email address and a project name for your subscription, and both of these are private. MetaMask opens and asks you to confirm payment to create the account onchain. After you approve the transaction, the network confirms the creation of your subscription account onchain.
5. After the subscription is created, click **Add funds** and follow the instructions to fund your subscription.
For your request to go through, you need to fund your subscription with enough testnet funds to meet your [minimum subscription balance](https://docs.chain.link/vrf/v2-5/overview/subscription#minimum-subscription-balance) to serve as a buffer against gas volatility.
- If you're paying with testnet LINK, fund your contract with 7 LINK. (After your request is processed, the actual cost will be around 0.06 LINK, and that amount will be deducted from your subscription balance.)
- If you're paying with testnet ETH, fund your contract with 0.03 ETH. (After your request is processed, the actual cost will be around 0.000247 ETH, and that amount will be deducted from your subscription balance.)
MetaMask opens to confirm the token transfer to your subscription. After you approve the transaction, the network confirms the transfer of your testnet funds to your subscription account.
6. After you add funds, click **Add consumer**. A page opens with your account details and subscription ID.
7. Record your subscription ID, which you need for your consuming contract. You will add the consuming contract to your subscription later.
You can always find your subscription IDs, balances, and consumers at [vrf.chain.link](https://vrf.chain.link/).
Now that you have a funded subscription account and your subscription ID, [create and deploy a VRF compatible contract](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number#create-and-deploy-a-vrf-compatible-contract).
## [Create and deploy a VRF compatible contract](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#create-and-deploy-a-vrf-compatible-contract)
For this example, use the [SubscriptionConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol) sample contract. This contract imports the following dependencies:
- `VRFConsumerBaseV2Plus.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol)
- `VRFV2PlusClient.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol)
The contract also includes pre-configured values for the necessary request parameters such as `vrfCoordinator` address, gas lane `keyHash`, `callbackGasLimit`, `requestConfirmations` and number of random words `numWords`. 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 Sepolia.
1. Open the [SubscriptionConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol) in Remix.
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
2. On the **Compile** tab in Remix, compile the `SubscriptionConsumer.sol` contract.
3. Configure your deployment. On the **Deploy** tab in Remix, select the **Injected Provider** environment, select the `SubscriptionConsumer` contract from the contract list, and specify your `subscriptionId` so the constructor can set it.

4. Click the **Deploy** button to deploy your contract onchain. MetaMask opens and asks you to confirm the transaction.
5. After you deploy your contract, copy the address from the **Deployed Contracts** list in Remix. Before you can request randomness from VRF v2.5, you must add this address as an approved consuming contract on your subscription account.

6. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
7. Under the **Consumers** section, click **Add consumer**.
8. Enter the address of your consuming 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.5 requests. Next, [request random values](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number#request-random-values) from Chainlink VRF.
## [Request random values](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#request-random-values)
The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
2. Expand the `requestRandomWords()` function to send the request for random values to Chainlink VRF. Use `enableNativePayment` to specify whether you want to pay in native tokens or LINK:
- To use native tokens, set `enableNativePayment` to `true`.
- To use LINK, set `enableNativePayment` to `false`.
When you click **transact**, 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. At this point, a new key `requestId` is added to the mapping `s_requests`.
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](https://vrf.chain.link/).
3. To fetch the request ID of your request, call `lastRequestId()`.
4. After the oracle returns the random values to your contract, the mapping `s_requests` is updated: The received random values are stored in `s_requests[_requestId].randomWords`.
5. Call `getRequestStatus()` specifying the `requestId` to display the random words.
You deployed a simple contract that can request and receive random values from Chainlink VRF. Next, learn how to [create and manage subscriptions programmatically](https://docs.chain.link/vrf/v2-5/subscription/create-manage#create-a-subscription-programmatically) by using a smart contract instead of the Subscription Manager.
## [Analyzing the contract](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#analyzing-the-contract)
In this example, your MetaMask wallet is the subscription owner and you created a consuming contract to use that subscription. The consuming contract uses static configuration parameters.

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity 0.8.19;
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* 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 SubscriptionConsumer is VRFConsumerBaseV2Plus {
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
struct RequestStatus {
bool fulfilled; // whether the request has been successfully fulfilled
bool exists; // whether a requestId exists
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// Your subscription ID.
uint256 public s_subscriptionId;
// Past request IDs.
uint256[] public requestIds;
uint256 public lastRequestId;
// 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/vrf/v2-5/supported-networks
bytes32 public keyHash =
0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae;
// 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 public callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 public requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFCoordinatorV2_5.MAX_NUM_WORDS.
uint32 public numWords = 2;
/**
* HARDCODED FOR SEPOLIA
* COORDINATOR: 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B
*/
constructor(
uint256 subscriptionId
) VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B) {
s_subscriptionId = subscriptionId;
}
// Assumes the subscription is funded sufficiently.
// @param enableNativePayment: Set to `true` to enable payment in native tokens, or
// `false` to pay in LINK
function requestRandomWords(
bool enableNativePayment
) external onlyOwner returns (uint256 requestId) {
// Will revert if subscription is not set and funded.
requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: keyHash,
subId: s_subscriptionId,
requestConfirmations: requestConfirmations,
callbackGasLimit: callbackGasLimit,
numWords: numWords,
extraArgs: VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({
nativePayment: enableNativePayment
})
)
})
);
s_requests[requestId] = RequestStatus({
randomWords: new uint256[](0),
exists: true,
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] calldata _randomWords
) internal override {
require(s_requests[_requestId].exists, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(_requestId, _randomWords);
}
function getRequestStatus(
uint256 _requestId
) external view returns (bool fulfilled, uint256[] memory randomWords) {
require(s_requests[_requestId].exists, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.fulfilled, request.randomWords);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
The parameters define how your requests will be processed. You can find the values for your network in the [Configuration](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- `uint256 s_subscriptionId`: The subscription ID that this contract uses for funding requests.
- `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 offchain 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. 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(bool enableNativePayment)`: Takes your specified parameters and submits the request to the VRF coordinator contract. Use `enableNativePayment` to specify for each request whether you want to pay in native tokens or LINK:
- To use native tokens, set `enableNativePayment` to `true`.
- To use LINK, set `enableNativePayment` to `false`.
- `fulfillRandomWords()`: Receives random values and stores them with your contract.
- `getRequestStatus()`: Retrieve request details for a given `_requestId`.
## [Clean up](https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number\#clean-up)
After you are done with this contract and the subscription, you can retrieve the remaining testnet tokens to use with other examples.
1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
2. On your subscription details page, expand the **Actions** menu and select **Cancel subscription**. A field displays, prompting you to add the wallet address you want to send the remaining funds to.
3. 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.
## What's next
- [\> Security Considerations](https://docs.chain.link/vrf/v2-5/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2-5/best-practices)
- [\> Migrating from V2](https://docs.chain.link/vrf/v2-5/migration-from-v2)
- [\> Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Chainlink VRF API
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Chainlink VRF API Reference \[v1\]](https://docs.chain.link/vrf/v1/api-reference\#overview)
API reference for [`VRFConsumerBase`](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFConsumerBase.sol).
## [Index](https://docs.chain.link/vrf/v1/api-reference\#index)
### [Constructors](https://docs.chain.link/vrf/v1/api-reference\#constructors)
| Name | Description |
| --- | --- |
| [constructor](https://docs.chain.link/vrf/v1/api-reference#constructor) | Initialize your consuming contract. |
### [Functions](https://docs.chain.link/vrf/v1/api-reference\#functions)
| Name | Description |
| --- | --- |
| [requestRandomness](https://docs.chain.link/vrf/v1/api-reference#requestrandomness) | Make a request to the VRFCoordinator. |
| [fulfillRandomness](https://docs.chain.link/vrf/v1/api-reference#fulfillrandomness) | Called by VRFCoordinator when it receives a valid VRF proof. |
* * *
## [Constructor](https://docs.chain.link/vrf/v1/api-reference\#constructor)
Initialize your consuming contract.

```solidity
constructor(address _vrfCoordinator, address _link)
```
- `_vrfCoordinator`: Address of the Chainlink VRF Coordinator. See [Chainlink VRF Addresses](https://docs.chain.link/vrf/v1/supported-networks) for details.
- `_link`: Address of the LINK token. See [LINK Token Addresses](https://docs.chain.link/resources/link-token-contracts) for details.
* * *
> Note: `_seed` has recently been deprecated.
## [Functions](https://docs.chain.link/vrf/v1/api-reference\#functions-1)
### [requestRandomness](https://docs.chain.link/vrf/v1/api-reference\#requestrandomness)
Make a request to the VRF coordinator.

```solidity
function requestRandomness(bytes32 _keyHash, uint256 _fee)
public returns (bytes32 requestId)
```
- `_keyHash`: The public key against which randomness is generated. See [Chainlink VRF supported networks](https://docs.chain.link/vrf/v1/supported-networks) for details.
- `_fee`: The fee, in LINK, for the request. Specified by the oracle.
- `RETURN`: The ID unique to a single request.
### [fulfillRandomness](https://docs.chain.link/vrf/v1/api-reference\#fulfillrandomness)
Called by VRFCoordinator when it receives a valid VRF proof. Override this function to act upon the random number generated by Chainlink VRF.

```solidity
function fulfillRandomness(bytes32 requestId, uint256 randomness)
internal virtual;
```
- `requestId`: The ID initially returned by `requestRandomness`.
- `randomness`: The random number generated by Chainlink VRF.
## [Reference](https://docs.chain.link/vrf/v1/api-reference\#reference)
### [Maximizing security](https://docs.chain.link/vrf/v1/api-reference\#maximizing-security)
Chainlink VRF provides powerful security guarantees and is easy to integrate. However, smart contract security is a nuanced topic. You can read about the [top security considerations for VRF](https://docs.chain.link/vrf/v1/security).
## Get the latest Chainlink content straight to your inbox.
Email Address
## Get Random Numbers with VRF
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Get a Random Number with VRF V2](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#overview)
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](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription) page. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Requirements](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#requirements)
This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
- [The Remix IDE](https://remix.ethereum.org/)
- [MetaMask](https://metamask.io/)
- [Sepolia testnet ETH](https://docs.chain.link/resources/link-token-contracts/#sepolia-testnet)
If you are new to developing smart contracts on Ethereum, see the [Getting Started](https://docs.chain.link/getting-started/conceptual-overview) guide to learn the basics.
## [Create and fund a subscription](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#create-and-fund-a-subscription)
For this example, create a new subscription on the Sepolia testnet.
1. Open MetaMask and set it to use the Sepolia testnet. The [Subscription Manager](https://docs.chain.link/vrf/v2/subscription/ui) detects your network based on the active network in MetaMask.
2. Check MetaMask to make sure you have testnet ETH and LINK on Sepolia. You can get testnet ETH and LINK at [faucets.chain.link](https://faucets.chain.link/sepolia/).
3. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/).
[Open the Subscription Manager](https://vrf.chain.link/)
4. Click **Create Subscription** and follow the instructions to create a new subscription account. If you connect your wallet to the Subscription Manager, the **Admin address** for your subscription is prefilled and not editable. Optionally, you can enter an email address and a project name for your subscription, and both of these are private. MetaMask opens and asks you to confirm payment to create the account onchain. After you approve the transaction, the network confirms the creation of your subscription account onchain.
5. After the subscription is created, click **Add funds** and follow the instructions to fund your subscription.
- For your request to go through, you need to fund your subscription with enough LINK to meet your [minimum subscription balance](https://docs.chain.link/vrf/v2/subscription#minimum-subscription-balance) to serve as a buffer against gas volatility. For this example, a balance of 12 LINK is sufficient. (After your request is processed, it costs around 3 LINK, and that amount will be deducted from your subscription balance.)
- 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.
6. After you add funds, click **Add consumer**. A page opens with your account details and subscription ID.
7. Record your subscription ID, which you need for your consuming contract. You will add the consuming contract to your subscription later.
You can always find your subscription IDs, balances, and consumers at [vrf.chain.link](https://vrf.chain.link/).
Now that you have a funded subscription account and your subscription ID, [create and deploy a VRF v2 compatible contract](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number#create-and-deploy-a-vrf-v2-compatible-contract).
## [Create and deploy a VRF v2 compatible contract](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#create-and-deploy-a-vrf-v2-compatible-contract)
For this example, use the [VRFv2Consumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol) sample contract. This contract imports the following dependencies:
- `VRFConsumerBaseV2.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol)
- `VRFCoordinatorV2Interface.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol)
- `ConfirmedOwner.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/access/ConfirmedOwner.sol)
The contract also includes pre-configured values for the necessary request parameters such as `vrfCoordinator` address, gas lane `keyHash`, `callbackGasLimit`, `requestConfirmations` and number of random words `numWords`. 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 Sepolia.
1. Open the [`VRFv2Consumer.sol` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol) in Remix.
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
2. On the **Compile** tab in Remix, compile the `VRFv2Consumer.sol` contract.
3. 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.

4. Click the **Deploy** button to deploy your contract onchain. MetaMask opens and asks you to confirm the transaction.
5. 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 consuming contract on your subscription account.

6. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
7. Under the **Consumers** section, click **Add consumer**.
8. Enter the address of your consuming 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](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number#request-random-values) from Chainlink VRF.
## [Request random values](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#request-random-values)
The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
2. 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. At this point, a new key `requestId` is added to the mapping `s_requests`.
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](https://vrf.chain.link/).
3. To fetch the request ID of your request, call `lastRequestId()`.
4. After the oracle returns the random values to your contract, the mapping `s_requests` is updated: The received random values are stored in `s_requests[_requestId].randomWords`.
5. Call `getRequestStatus()` specifying the `requestId` to display the random words.
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](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription) page.
## [Analyzing the contract](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#analyzing-the-contract)
In this example, your MetaMask wallet is the subscription owner and you created a consuming contract to use that subscription. The consuming contract uses static configuration parameters.

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";
import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* 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, ConfirmedOwner {
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
struct RequestStatus {
bool fulfilled; // whether the request has been successfully fulfilled
bool exists; // whether a requestId exists
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
VRFCoordinatorV2Interface COORDINATOR;
// Your subscription ID.
uint64 s_subscriptionId;
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// 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/v2/subscription/supported-networks/#configurations
bytes32 keyHash =
0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
// 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;
/**
* HARDCODED FOR SEPOLIA
* COORDINATOR: 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
*/
constructor(
uint64 subscriptionId
)
VRFConsumerBaseV2(0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625)
ConfirmedOwner(msg.sender)
{
COORDINATOR = VRFCoordinatorV2Interface(
0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
);
s_subscriptionId = subscriptionId;
}
// Assumes the subscription is funded sufficiently.
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
// Will revert if subscription is not set and funded.
requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
s_requests[requestId] = RequestStatus({
randomWords: new uint256[](0),
exists: true,
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].exists, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(_requestId, _randomWords);
}
function getRequestStatus(
uint256 _requestId
) external view returns (bool fulfilled, uint256[] memory randomWords) {
require(s_requests[_requestId].exists, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.fulfilled, request.randomWords);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2Consumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
The parameters define how your requests will be processed. You can find the values for your network in the [Configuration](https://docs.chain.link/vrf/v2/subscription/supported-networks) page.
- `uint64 s_subscriptionId`: The subscription ID that this contract uses for funding requests.
- `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 offchain 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. 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.
- `getRequestStatus()`: Retrieve request details for a given `_requestId`.
## [Clean up](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#clean-up)
After you are done with this contract and the subscription, you can retrieve the remaining testnet LINK to use with other examples.
1. Open the Subscription Manager at [vrf.chain.link](https://vrf.chain.link/) and click the ID of your new subscription under the **My Subscriptions** list. The subscription details page opens.
2. On your subscription details page, expand the **Actions** menu and select **Cancel subscription**. A field displays, prompting you to add the wallet address you want to send the remaining funds to.
3. 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.
## [Vyper example](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number\#vyper-example)
You must import the `VRFCoordinatorV2` Vyper interface. You can find it [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/interfaces/VRFCoordinatorV2.vy).
You can find a `VRFConsumerV2` example [here](https://github.com/smartcontractkit/apeworx-starter-kit/blob/main/contracts/VRFConsumerV2.vy). Read the _**apeworx-starter-kit**_ [README](https://github.com/smartcontractkit/apeworx-starter-kit) to learn how to run the example.
## What's next
- [\> Programmatic Subscription](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription)
- [\> Subscription Manager UI](https://docs.chain.link/vrf/v2/subscription/ui)
- [\> Security Considerations](https://docs.chain.link/vrf/v2/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2/best-practices)
- [\> Migrating from VRF v1 to v2](https://docs.chain.link/vrf/v2/subscription/migration-from-v1)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## VRF Subscription Manager
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Subscription Manager User Interface](https://docs.chain.link/vrf/v2/subscription/ui\#overview)
The [VRF Subscription Manager](https://vrf.chain.link/) is available to help you create and manage VRF subscriptions. You can create and manage new V2.5 subscriptions, and manage existing V2 subscriptions, but you can no longer create new V2 subscriptions in the VRF Subscription Manager. Alternatively, you can [create and manage V2 subscriptions programmatically](https://docs.chain.link/vrf/v2/subscription/examples/programmatic-subscription).
This guide walks you through the main sections of the UI.

Subscription components:
- **Status**: Indicates if the subscription is still active or not.
- **ID**: The unique subscription identifier. Approved consuming contracts use LINK from this subscription to pay for each randomness request.
- **Admin**: The account address that owns this subscription ID.
- **Consumers**: The number of consuming contracts that are approved to make VRF requests using this subscription.
- **Fulfillment**: The number of successful randomness requests that are already completed.
- **Balance**: The amount of LINK remaining to be used for requests that use this subscription.
## [Actions menu](https://docs.chain.link/vrf/v2/subscription/ui\#actions-menu)
Expand the **Actions** menu to display actions you can take for any subscription that you own:

- **Fund subscription**: Displays a field allowing you to fund your subscription from your connected wallet.
Specify how much LINK you'd like to send to your subscription.
- **Add email address**: Displays a field allowing you to add an email address to your subscription. This is an
optional field.
- **Cancel subscription**: Displays a field allowing you to specify the account address to receive the remaining balance.
See the clean up instructions in the [Get a Random Number](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number/#clean-up) guide to learn more.
Note: It is possible to fund subscriptions that you do not own. In that case, the Actions menu displays only the
**Fund subscription** option.
## [Consumers](https://docs.chain.link/vrf/v2/subscription/ui\#consumers)

The **Consumers** section lists the contracts that are allowed to use your subscription to pay for requests.
- **Address**: The address of the consuming contract.
- **Added**: The time when the consumer was added to the subscription.
- **Last fulfillment**: The last time a VRF request was fulfilled for the consumer.
- **Total spent**: The total amount of LINK that has been used by the consuming contract.
You can use this section to add or remove consumers.
## [Pending](https://docs.chain.link/vrf/v2/subscription/ui\#pending)

The **Pending** list appears if there are requests currently being processed.
- **Time**: The time when the pending VRF request was made.
- **Consumer**: The address of the consuming contract.
- **Transaction hash**: The transaction hash of the pending VRF request.
- **Status**: A timer that informs you when the pending VRF request will move to a failed status. **Note**: Pending requests fail after 24h.
- **Max Cost**: The estimated upper limit of the transaction cost in LINK based on the configuration. Learn more about the [minimum subscription balance](https://docs.chain.link/vrf/v2/subscription/#minimum-subscription-balance).
- **Projected Balance**: This indicates when the subscription is underfunded and how many LINK tokens are required to fund the subscription.
## [History](https://docs.chain.link/vrf/v2/subscription/ui\#history)
### [Recent fulfillments](https://docs.chain.link/vrf/v2/subscription/ui\#recent-fulfillments)

The **Recent fulfillments** tab shows the details for successful VRF fulfillments.
- **Time**: The time and block number indicating when the VRF request was successfully fulfilled.
- **Consumer**: The address of the consuming contract that initiated the VRF request.
- **Transaction Hash**: The transaction hash of the VRF callback.
- **Status**: The status of the request. Recent fulfillments always show _Success_.
- **Spent**: The total amount of LINK spent to fulfill the VRF request.
- **Balance**: The LINK balance of the subscription after the VRF request was fulfilled.
### [Events](https://docs.chain.link/vrf/v2/subscription/ui\#events)

The **Events** tab displays events linked to the subscription. There are five main events:
- Subscription created
- Subscription funded
- Consumer added
- Consumer removed
- Subscription canceled
Components of VRF events:
- **Time**: The time when the event happened.
- **Event**: The type of the event.
- **Transaction Hash**: The transaction hash for the event.
- **Consumer**: The address of the consuming contract. This is used only for _Consumer added_ and _Consumer canceled_ events.
- **Amount**:
- For _Subscription funded_ events, this indicates the amount of LINK added to the subscription balance.
- For _Subscription canceled_ events, this indicates the amount of LINK withdrawn from the subscription balance.
- **Balance**:
- For _Subscription funded_ events, this indicates the LINK balance of the subscription after it was funded.
- For _Subscription canceled_ events, this field should display _0_.
### [Failed requests](https://docs.chain.link/vrf/v2/subscription/ui\#failed-requests)

The **Failed requests** tab displays failed VRF requests.
- **Time**: The time when the VRF request was made.
- **Transaction Hash**: This can be either the transaction hash of the originating VRF request if the request was pending for over 24 hours _or_ the transaction hash of the VRF callback if the callback failed.
- **Status**: The status of the request. Failed requests always show _Failed_.
- **Reason**: The reason why the request failed. Requests fail for one of the following reasons:
- Pending for over 24 hours
- Wrong key hash specified
- Callback gas limit set too low
## What's next
- [\> Security Considerations](https://docs.chain.link/vrf/v2/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2/best-practices)
- [\> Migrating from VRF v1 to v2](https://docs.chain.link/vrf/v2/subscription/migration-from-v1)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/subscription/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Get Random Numbers with VRF
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Get a Random Number with VRF V2](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#overview)
This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2 without managing a subscription. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Requirements](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#requirements)
This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
- [The Remix IDE](https://remix.ethereum.org/)
- [MetaMask](https://metamask.io/)
- [Sepolia testnet ETH](https://docs.chain.link/resources/link-token-contracts/#sepolia-testnet)
If you are new to developing smart contracts on Ethereum, see the [Getting Started](https://docs.chain.link/getting-started/conceptual-overview) guide to learn the basics.
## [Create and deploy a VRF v2 compatible contract](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#create-and-deploy-a-vrf-v2-compatible-contract)
For this example, use the [VRFv2DirectFundingConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol) sample contract. This contract imports the following dependencies:
- `VRFV2WrapperConsumerBase.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol)
- `ConfirmedOwner.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/shared/access/ConfirmedOwner.sol)
The contract also includes pre-configured values for the necessary request parameters such as `callbackGasLimit`, `requestConfirmations`, the number of random words `numWords`, the VRF v2 Wrapper address `wrapperAddress`, and the LINK token address `linkAddress`. You can change these parameters if you want to experiment on different testnets.
Build and deploy the contract on Sepolia.
1. Open the [`VRFv2DirectFundingConsumer.sol` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol) in Remix.
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
2. On the **Compile** tab in Remix, compile the `VRFv2DirectFundingConsumer` contract.
3. Configure your deployment. On the **Deploy** tab in Remix, select the **Injected Web3 Environment** and select the `VRFv2DirectFundingConsumer` contract from the contract list.
4. Click the **Deploy** button to deploy your contract onchain. MetaMask opens and asks you to confirm the transaction.
5. 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 fund your consuming contract with enough LINK tokens in order to request for randomness. Next, [fund your contract](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number#fund-your-contract).
## [Fund Your Contract](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#fund-your-contract)
Requests for randomness will fail unless your consuming contract has enough LINK.
1. [Acquire testnet LINK](https://docs.chain.link/resources/acquire-link).
2. [Fund your contract with testnet LINK](https://docs.chain.link/resources/fund-your-contract). For this example, funding your contract with 2 LINK should be sufficient.
## [Request random values](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#request-random-values)
The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them, and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
2. 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. At this point, a new key `requestId` is added to the mapping `s_requests`. Depending on current testnet conditions, it might take a few minutes for the callback to return the requested random values to your contract.
3. To fetch the request ID of your request, call `lastRequestId()`.
4. After the oracle returns the random values to your contract, the mapping `s_requests` is updated. The received random values are stored in `s_requests[_requestId].randomWords`.
5. Call `getRequestStatus()` and specify the `requestId` to display the random words.
## [Analyzing the contract](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#analyzing-the-contract)
In this example, the consuming contract uses static configuration parameters.

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that directly pays for each request.
pragma solidity ^0.8.7;
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {VRFV2WrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* 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 VRFv2DirectFundingConsumer is
VRFV2WrapperConsumerBase,
ConfirmedOwner
{
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(
uint256 requestId,
uint256[] randomWords,
uint256 payment
);
struct RequestStatus {
uint256 paid; // amount paid in link
bool fulfilled; // whether the request has been successfully fulfilled
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. 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 VRFV2Wrapper.getConfig().maxNumWords.
uint32 numWords = 2;
// Address LINK - hardcoded for Sepolia
address linkAddress = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
// address WRAPPER - hardcoded for Sepolia
address wrapperAddress = 0xab18414CD93297B0d12ac29E63Ca20f515b3DB46;
constructor()
ConfirmedOwner(msg.sender)
VRFV2WrapperConsumerBase(linkAddress, wrapperAddress)
{}
function requestRandomWords()
external
onlyOwner
returns (uint256 requestId)
{
requestId = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords
);
s_requests[requestId] = RequestStatus({
paid: VRF_V2_WRAPPER.calculateRequestPrice(callbackGasLimit),
randomWords: new uint256[](0),
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].paid > 0, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(
_requestId,
_randomWords,
s_requests[_requestId].paid
);
}
function getRequestStatus(
uint256 _requestId
)
external
view
returns (uint256 paid, bool fulfilled, uint256[] memory randomWords)
{
require(s_requests[_requestId].paid > 0, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.paid, request.fulfilled, request.randomWords);
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(linkAddress);
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/VRFv2DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
The parameters define how your requests will be processed. You can find the values for your network in the [Supported networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks) page.
- `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 minus the `wrapperGasOverhead`. See the [VRF v2 Direct funding limits](https://docs.chain.link/vrf/v2/direct-funding/#limits) for more details. 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 consuming contract 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 v2 Wrapper contract.
- `fulfillRandomWords()`: Receives random values and stores them with your contract.
- `getRequestStatus()`: Retrieve request details for a given `_requestId`.
- `withdrawLink()`: At any time, the owner of the contract can withdraw outstanding LINK balance from it.
## [Clean up](https://docs.chain.link/vrf/v2/direct-funding/examples/get-a-random-number\#clean-up)
After you are done with this contract, you can retrieve the remaining testnet LINK to use with other examples.
1. Call `withdrawLink()` function. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, the remaining LINK will be transferred from your consuming contract to your wallet address.
## What's next
- [\> Security Considerations](https://docs.chain.link/vrf/v2/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2/best-practices)
- [\> Migrating from VRF v1](https://docs.chain.link/vrf/v2/direct-funding/migration-from-v1)
- [\> Supported Networks](https://docs.chain.link/vrf/v2/direct-funding/supported-networks)
## Get the latest Chainlink content straight to your inbox.
Email Address
## Get Random Numbers
[iframe](https://www.googletagmanager.com/ns.html?id=GTM-N6DQ47T)
Chainlink CCIP is now officially live on Solana. [View lanes and tokens.](https://docs.chain.link/ccip/directory/mainnet/chain/solana-mainnet?utm_medium=referral&utm_source=chainlink-docs&utm_campaign=solana-ccip)
On this page
# [Get a Random Number](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#overview)
This guide explains how to get random values using a simple contract to request and receive random values from Chainlink VRF v2.5 without managing a subscription. To explore more applications of VRF, refer to our [blog](https://blog.chain.link/).
## [Requirements](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#requirements)
This guide assumes that you know how to create and deploy smart contracts on Ethereum testnets using the following tools:
- [The Remix IDE](https://remix.ethereum.org/)
- [MetaMask](https://metamask.io/)
- [Sepolia testnet ETH](https://docs.chain.link/resources/link-token-contracts/#sepolia-testnet)
If you are new to developing smart contracts on Ethereum, see the [Getting Started](https://docs.chain.link/getting-started/conceptual-overview) guide to learn the basics.
## [Create and deploy a VRF compatible contract](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#create-and-deploy-a-vrf-compatible-contract)
For this example, use the [DirectFundingConsumer.sol](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) sample contract. This contract imports the following dependencies:
- `VRFV2PlusWrapperConsumerBase.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol)
- `VRFV2PlusClient.sol` [(link)](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol)
The contract also includes pre-configured values for the necessary request parameters such as `callbackGasLimit`, `requestConfirmations`, the number of random words `numWords`, the VRF v2.5 Wrapper address `wrapperAddress`, and the LINK token address `linkAddress`. You can change these parameters if you want to experiment on different testnets.
Build and deploy the contract on Sepolia.
1. Open the [`DirectFundingConsumer.sol` contract](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) in Remix.
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
2. On the **Compile** tab in Remix, compile the `DirectFundingConsumer` contract.
3. Configure your deployment. On the **Deploy** tab in Remix, select the **Injected Web3 Environment** and select the `DirectFundingConsumer` contract from the contract list.
4. Click the **Deploy** button to deploy your contract onchain. MetaMask opens and asks you to confirm the transaction.
5. After you deploy your contract, copy the address from the **Deployed Contracts** list in Remix. Before you can request randomness from VRF v2.5, you must fund your consuming contract with enough tokens in order to request for randomness. Next, [fund your contract](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number#fund-your-contract).
## [Fund your contract](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#fund-your-contract)
Requests for randomness will fail unless your consuming contract has enough tokens. VRF V2.5 allows you to use either native tokens or LINK to pay for your requests.
1. [Acquire testnet LINK and Sepolia ETH](https://faucets.chain.link/sepolia).
2. [Fund your contract](https://docs.chain.link/resources/fund-your-contract) with either testnet LINK or Sepolia ETH, depending on how you want to pay for your VRF requests. For this example, fund your contract with 2 LINK or 0.01 Sepolia ETH. (The actual request cost is closer to 0.877 LINK or 0.001 ETH. You can [withdraw the excess funds](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number#clean-up) after you're done with this contract.)
## [Request random values](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#request-random-values)
The deployed contract requests random values from Chainlink VRF, receives those values, builds a struct `RequestStatus` containing them, and stores the struct in a mapping `s_requests`. Run the `requestRandomWords()` function on your contract to start the request.
1. Return to Remix and view your deployed contract functions in the **Deployed Contracts** list.
2. Expand the `requestRandomWords()` function. For `enableNativePayment`, fill in `true` if you're paying for your request with Sepolia ETH, or `false` if you're paying with testnet LINK. Click **transact** 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. At this point, a new key `requestId` is added to the mapping `s_requests`. Depending on current testnet conditions, it might take a few minutes for the callback to return the requested random values to your contract.
3. To fetch the request ID of your request, call `lastRequestId()`.
4. After the oracle returns the random values to your contract, the mapping `s_requests` is updated. The received random values are stored in `s_requests[_requestId].randomWords`.
5. Call `getRequestStatus()` and specify the `requestId` to display the random words.
## [Analyzing the contract](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#analyzing-the-contract)
In this example, the consuming contract uses static configuration parameters.

```solidity
// SPDX-License-Identifier: MIT
// An example of a consumer contract that directly pays for each request.
pragma solidity 0.8.19;
import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";
import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol";
import {VRFV2PlusWrapperConsumerBase} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFV2PlusWrapperConsumerBase.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* 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 DirectFundingConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner {
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(
uint256 requestId,
uint256[] randomWords,
uint256 payment
);
struct RequestStatus {
uint256 paid; // amount paid in link
bool fulfilled; // whether the request has been successfully fulfilled
uint256[] randomWords;
}
mapping(uint256 => RequestStatus)
public s_requests; /* requestId --> requestStatus */
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. 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 public callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 public requestConfirmations = 3;
// For this example, retrieve 2 random values in one request.
// Cannot exceed VRFV2Wrapper.getConfig().maxNumWords.
uint32 public numWords = 2;
// Address LINK - hardcoded for Sepolia
address public linkAddress = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
// address WRAPPER - hardcoded for Sepolia
address public wrapperAddress = 0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1;
constructor()
ConfirmedOwner(msg.sender)
VRFV2PlusWrapperConsumerBase(wrapperAddress)
{}
function requestRandomWords(
bool enableNativePayment
) external onlyOwner returns (uint256) {
bytes memory extraArgs = VRFV2PlusClient._argsToBytes(
VRFV2PlusClient.ExtraArgsV1({nativePayment: enableNativePayment})
);
uint256 requestId;
uint256 reqPrice;
if (enableNativePayment) {
(requestId, reqPrice) = requestRandomnessPayInNative(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
} else {
(requestId, reqPrice) = requestRandomness(
callbackGasLimit,
requestConfirmations,
numWords,
extraArgs
);
}
s_requests[requestId] = RequestStatus({
paid: reqPrice,
randomWords: new uint256[](0),
fulfilled: false
});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].paid > 0, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(
_requestId,
_randomWords,
s_requests[_requestId].paid
);
}
function getRequestStatus(
uint256 _requestId
)
external
view
returns (uint256 paid, bool fulfilled, uint256[] memory randomWords)
{
require(s_requests[_requestId].paid > 0, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.paid, request.fulfilled, request.randomWords);
}
/**
* Allow withdraw of Link tokens from the contract
*/
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(linkAddress);
require(
link.transfer(msg.sender, link.balanceOf(address(this))),
"Unable to transfer"
);
}
/// @notice withdrawNative withdraws the amount specified in amount to the owner
/// @param amount the amount to withdraw, in wei
function withdrawNative(uint256 amount) external onlyOwner {
(bool success, ) = payable(owner()).call{value: amount}("");
// solhint-disable-next-line gas-custom-errors
require(success, "withdrawNative failed");
}
event Received(address, uint256);
receive() external payable {
emit Received(msg.sender, msg.value);
}
}
```
[Open in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol&autoCompile=true) [What is Remix?](https://docs.chain.link/getting-started/conceptual-overview#what-is-remix)
The parameters define how your requests will be processed. You can find the values for your network in the [Supported networks](https://docs.chain.link/vrf/v2-5/supported-networks) page.
- `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 minus the `wrapperGasOverhead`. See the [VRF v2.5 Direct funding limits](https://docs.chain.link/vrf/v2-5/overview/direct-funding#limits) for more details. 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 consuming contract 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 v2.5 Wrapper contract.
- `fulfillRandomWords()`: Receives random values and stores them with your contract.
- `getRequestStatus()`: Retrieve request details for a given `_requestId`.
- `withdrawLink()`: At any time, the owner of the contract can withdraw the outstanding LINK balance from it.
- `withdrawNative()`: At any time, the owner of the contract can withdraw the outstanding native token balance from it.
## [Clean up](https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number\#clean-up)
After you are done with this contract, you can retrieve the remaining testnet tokens to use with other examples:
LINKNative tokens
Call the `withdrawLink()` function. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, the remaining LINK will be transferred from your consuming contract to your wallet address.
Call `getBalance` to retrieve your contract's ETH balance in wei, and then pass that into the `withdrawNative()` function. MetaMask opens and asks you to confirm the transaction. After you approve the transaction, the remaining Sepolia ETH will be transferred from your consuming contract to your wallet address.
## What's next
- [\> Security Considerations](https://docs.chain.link/vrf/v2-5/security)
- [\> Best Practices](https://docs.chain.link/vrf/v2-5/best-practices)
- [\> Migrating from V2](https://docs.chain.link/vrf/v2-5/migration-from-v2)
- [\> Supported Networks](https://docs.chain.link/vrf/v2-5/supported-networks)