# Chainlink VRF Source: https://docs.chain.link/vrf **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 helps ensure that results cannot be tampered with or manipulated by any single entity including oracle operators, smart contract developers, users, miners, or block builders\*. \*In the unlikely event that an adversary compromises VRF's randomness-generating secret key and obtains the ability to construct blocks on the target chain, they could strongly bias the result. > **NOTE: Migrate to V2.5** > > Follow the [migration guide](/vrf/v2-5/migration-from-v2) to learn how VRF has changed in V2.5 and to get example > code. 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](/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 Similarly to VRF v2, VRF v2.5 will offer two methods for requesting randomness: - [Subscription](/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](/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 Depending on your use case, one method might be more suitable than another. Consider the following characteristics when you choose a method: | [Subscription method](/vrf/v2-5/overview/subscription) | [Direct funding method](/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](/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](/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](/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](/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 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](/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](/resources/developer-communications?parent=vrf). --- # Getting Started with Chainlink VRF V2.5 Source: https://docs.chain.link/vrf/v2-5/getting-started > **NOTE: Requirements** > > This guide assumes that you have basic knowledge about writing and deploying smart contracts. If you are new to smart > contract development, learn how to [Deploy Your First Smart Contract](/quickstarts/deploy-your-first-contract) before > you begin. 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? 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**](/vrf), also known as Chainlink Verifiable Random Function. ## What is the Request and Receive cycle? The [Data Feeds Getting Started](/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](/architecture-overview/architecture-request-model)**. ## 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](/vrf/v2-5/overview/subscription#subscription-limits). ## 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 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](/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 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 This example is adapted for [Sepolia testnet](/vrf/v2-5/supported-networks#ethereum-sepolia-testnet) but you can change the configuration and make it run for any [supported network](/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 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 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 `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 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 VRFD20.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/VRFD20.sol) 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? 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](/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: ![Remix contract selected](/images/vrf/v2-5/select-vrfd20-contract.png) 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. ![Remix contract parameters to deploy](/images/vrf/v2-5/deploy-with-sub-id.png) Then click the `Deploy` button and use your MetaMask account to confirm the transaction. > **NOTE: Address, Key Hashes and more** > > For a full reference of the addresses, key hashes and fees for each network, see [VRF Supported > Networks](/vrf/v2-5/supported-networks). 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? 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: ![Copy Remix contract address](/images/vrf/v2-5/copy-contract-address.png) 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: ![Add a consumer to your VRF subscription](/images/vrf/v2-5/ui-add-consumer.png) ## 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 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/) --- # Migrating from VRF v2 Source: https://docs.chain.link/vrf/v2-5/migration-from-v2 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 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 VRF v2.5 introduces a new request format and the `setCoordinator` function. See the [full migration walkthrough](#migration-walkthrough) or the code example for more details. ### New request format The request format for VRF v2.5 has changed: ### Subscription 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. ### Direct funding 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 Add the `setCoordinator` function to your contract so that you can easily update the VRF coordinator for future VRF releases. ### 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 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](/vrf/v2-5/billing) page for more details. To find out the new premium percentages for the networks you use, see the [Supported Networks](/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](/vrf/v2-5/billing) page for more details and examples, and see the new configurations on the [Supported Networks](/vrf/v2-5/supported-networks) page. ## Migration walkthrough VRF v2.5 currently supports subscriptions and direct funding on all [supported networks](/vrf/v2-5/supported-networks). To migrate, you need to [update your existing smart contract code](#update-your-code) and redeploy your contracts. If using subscriptions, [create and fund a new VRF v2.5 subscription](/vrf/v2-5/subscription/create-manage). For direct funding, deploy the [`DirectFundingConsumer`](/samples/VRF/v2-5/DirectFundingConsumer.sol) example: [Open DirectFundingConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) ### Update your code To modify your existing smart contract code to work with VRF v2.5, complete the following changes: ### Subscription 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: ### LINK ```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})) }) ); ``` ### 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. 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: ``` 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. ### Direct funding 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: ### LINK ```solidity bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs ); ``` ### Native tokens ```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](#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 #### Subscription example code The example `SubscriptionConsumer` contract shows the migration steps above, applied to the example code from [this VRF V2 tutorial](/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 SubscriptionConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol) Compare the major changes between V2.5 and V2: ### VRF V2.5 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}) ) }) ); ... } ... } ``` ### VRF 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.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 The example `DirectFundingConsumer` contract shows the migration steps above, applied to the example code from [this VRF V2 tutorial](/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 DirectFundingConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) Compare the major changes between V2.5 and V2: ### VRF V2.5 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; } ... } ``` ### VRF V2 example code ```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; } ... } ``` --- # Migrating from VRF v1 Source: https://docs.chain.link/vrf/v2-5/migration-from-v1 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 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](/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 - **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](/vrf/v2-5/billing) page for more details. To find out the premium percentages for the networks you use, see the [Supported Networks](/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](/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](/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](/vrf/v2-5/billing) page for more details and examples. The new configurations are listed in the [Supported Networks](/vrf/v2-5/supported-networks) page. ### Updating your applications to use VRF v2.5 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](/vrf/#choosing-the-correct-method). ### Subscription To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the [Get a Random Number](/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](/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. ### Direct funding To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the [Get a Random Number](/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](/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](/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: ### LINK ```solidity bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs ); ``` ### Native tokens ```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 VRF v2.5 currently supports subscriptions and direct funding on all [supported networks](/vrf/v2-5/supported-networks). To migrate, you need to [update your existing smart contract code](#update-your-code) and redeploy your contracts. If using subscriptions, [create and fund a new VRF v2.5 subscription](/vrf/v2-5/subscription/create-manage). For direct funding, deploy the [`DirectFundingConsumer`](/samples/VRF/v2-5/DirectFundingConsumer.sol) example: [Open DirectFundingConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) ### Update your code To modify your existing smart contract code to work with VRF v2.5, complete the following changes: ### Subscription 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: ### LINK ```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})) }) ); ``` ### 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. 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: ``` 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. ### Direct funding 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: ### LINK ```solidity bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs ); ``` ### Native tokens ```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](#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 View example code for both VRF 2.5 subscription and direct funding: Open the full example `SubscriptionConsumer` contract: [Open SubscriptionConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol) Open the full example `DirectFundingConsumer` contract: [Open DirectFundingConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) --- # Supported Networks Source: https://docs.chain.link/vrf/v2-5/supported-networks Chainlink VRF allows you to integrate provably fair and verifiably random data in your smart contract. For implementation details, read [Introduction to Chainlink VRF](/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](/ccip/evm/tutorials/application-developers/transfer-tokens-from-contract), [Transporter](https://www.transporter.io/) or third-party applications such as [XSwap](https://xswap.link/). > **NOTE: Interfaces and Applications** > > Chainlink CCIP is a messaging protocol. Third parties may build user interfaces or other applications on top of CCIP. > Neither Chainlink Labs nor the Chainlink Foundation owns, controls, endorses, or assumes any responsibility for any > such interfaces or applications. You are solely responsible for your use of such interfaces or applications. Please > visit the Chainlink Foundation [Terms of Service](https://chain.link/terms) for more information. > **CAUTION: Understand Risks associated with Bridges** > > If you are using a cross-chain bridge to transfer your LINK tokens, read the [Bridges and Associated Risks](/resources/bridge-risks) guide to understand what cross-chain bridges are and the risks associated with using them. ## 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 ### Arbitrum Mainnet ### Subscription | Item | Value | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4) | | VRF Coordinator | [0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e](https://arbiscan.io/address/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 | ### Direct funding | Item | Value | | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0xf97f4df75117a78c1A5a0DBb814Af92458539FB4](https://arbiscan.io/address/0xf97f4df75117a78c1A5a0DBb814Af92458539FB4) | | | VRF Wrapper | [0x14632CD5c12eC5875D41350B55e825c54406BaaB](https://arbiscan.io/address/0x14632CD5c12eC5875D41350B55e825c54406BaaB) | | | VRF Coordinator | [0x3C0Ca683b403E37668AE3DC4FB62F4B29B6f7a3e](https://arbiscan.io/address/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 Testnet ETH and LINK are available from [https://faucets.chain.link/arbitrum-sepolia](https://faucets.chain.link/arbitrum-sepolia) ### Subscription | Item | Value | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E) | | VRF Coordinator | [0x5CE8D5A2BC84beb22a398CCA51996F7930313D61](https://sepolia.arbiscan.io/address/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 | ### Direct funding | Item | Value | | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0xb1D4538B4571d411F07960EF2838Ce337FE1E80E](https://sepolia.arbiscan.io/address/0xb1D4538B4571d411F07960EF2838Ce337FE1E80E) | | | VRF Wrapper | [0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC](https://sepolia.arbiscan.io/address/0x29576aB8152A09b9DC634804e4aDE73dA1f3a3CC) | | | VRF Coordinator | [0x5CE8D5A2BC84beb22a398CCA51996F7930313D61](https://sepolia.arbiscan.io/address/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 ### Avalanche Mainnet ### Subscription | Item | Value | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3) | | VRF Coordinator | [0xE40895D055bccd2053dD0638C9695E326152b1A4](https://snowtrace.io/address/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 | ### Direct funding | Item | Value | | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x5947BB275c521040051D82396192181b413227A3](https://snowtrace.io/address/0x5947BB275c521040051D82396192181b413227A3) | | | VRF Wrapper | [0x62Fb87c10A917580cA99AB9a86E213Eb98aa820C](https://snowtrace.io/address/0x62Fb87c10A917580cA99AB9a86E213Eb98aa820C) | | | VRF Coordinator | [0xE40895D055bccd2053dD0638C9695E326152b1A4](https://snowtrace.io/address/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 Testnet LINK is available from [https://faucets.chain.link/fuji](https://faucets.chain.link/fuji) ### Subscription | Item | Value | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846) | | VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://testnet.snowtrace.io/address/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 | ### Direct funding | Item | Value | | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846](https://testnet.snowtrace.io/address/0x0b9d5D9136855f6FEc3c0993feE6E9CE8a297846) | | | VRF Wrapper | [0x327B83F409E1D5f13985c6d0584420FA648f1F56](https://testnet.snowtrace.io/address/0x327B83F409E1D5f13985c6d0584420FA648f1F56) | | | VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://testnet.snowtrace.io/address/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 ### BASE Mainnet ### Subscription | Item | Value | | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196](https://basescan.org/address/0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196) | | VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://basescan.org/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634) | | 2 gwei Key Hash | 0x00b81b5a830cb0a4009fbd8904de511e28631e62ce5ad231373d3cdad373ccab | | 30 gwei Key Hash | 0xdc2f87677b01473c763cb0aee938ed3341512f6057324a584e5944e786144d70 | | Premium percentage (paying with BASE Mainnet ETH) | 60 | | Premium percentage (paying with LINK) | 50 | | Max Gas Limit | 2,500,000 | | Minimum Confirmations | 0 | | Maximum Confirmations | 200 | | Maximum Random Values | 500 | ### Direct funding | Item | Value | | | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196](https://basescan.org/address/0x88Fb150BDc53A65fe94Dea0c9BA0a6dAf8C6e196) | | | VRF Wrapper | [0xb0407dbe851f8318bd31404A49e658143C982F23](https://basescan.org/address/0xb0407dbe851f8318bd31404A49e658143C982F23) | | | VRF Coordinator | [0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634](https://basescan.org/address/0xd5D517aBE5cF79B7e95eC98dB0f0277788aFF634) | | | 2 gwei Key Hash | 0x00b81b5a830cb0a4009fbd8904de511e28631e62ce5ad231373d3cdad373ccab | | | 30 gwei Key Hash | 0xdc2f87677b01473c763cb0aee938ed3341512f6057324a584e5944e786144d70 | | | Premium percentage (paying with BASE Mainnet 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 | | ### BASE Sepolia Testnet ### Subscription | Item | Value | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia.basescan.org/address/0xE4aB69C077896252FAFBD49EFD26B5D171A32410) | | VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://sepolia.basescan.org/address/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 | ### Direct funding | Item | Value | | | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia.basescan.org/address/0xE4aB69C077896252FAFBD49EFD26B5D171A32410) | | | VRF Wrapper | [0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed](https://sepolia.basescan.org/address/0x7a1BaC17Ccc5b313516C5E16fb24f7659aA5ebed) | | | VRF Coordinator | [0x5C210eF41CD1a72de73bF76eC39637bB0d3d7BEE](https://sepolia.basescan.org/address/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 ### 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/). ### Subscription | Item | Value | | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75) | | VRF Coordinator | [0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9](https://bscscan.com/address/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 | ### Direct funding | Item | Value | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x404460C6A5EdE2D891e8297795264fDe62ADBB75](https://bscscan.com/token/0x404460C6A5EdE2D891e8297795264fDe62ADBB75) | | VRF Wrapper | [0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94](https://bscscan.com/address/0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94) | | VRF Coordinator | [0xd691f04bc0C9a24Edb78af9E005Cf85768F694C9](https://bscscan.com/address/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 ### Subscription 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) | | VRF Coordinator | [0xDA3b641D438362C440Ac5458c57e00a712b66700](https://testnet.bscscan.com/address/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 | ### Direct funding | Item | Value | | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06](https://testnet.bscscan.com/address/0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06) | | | VRF Wrapper | [0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94](https://testnet.bscscan.com/address/0x471506e6ADED0b9811D05B8cAc8Db25eE839Ac94) | | | VRF Coordinator | [0xDA3b641D438362C440Ac5458c57e00a712b66700](https://testnet.bscscan.com/address/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 ### Ethereum Mainnet ### Subscription | Item | Value | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA) | | VRF Coordinator | [0xD7f86b4b8Cae7D942340FF628F82735b7a20893a](https://etherscan.io/address/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 | ### Direct funding | Item | Value | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/token/0x514910771AF9Ca656af840dff83E8264EcF986CA) | | VRF Wrapper | [0x02aae1A04f9828517b3007f83f6181900CaD910c](https://etherscan.io/address/0x02aae1A04f9828517b3007f83f6181900CaD910c) | | VRF Coordinator | [0xD7f86b4b8Cae7D942340FF628F82735b7a20893a](https://etherscan.io/address/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 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). ### Subscription | Item | Value | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789) | | VRF Coordinator | [0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B](https://sepolia.etherscan.io/address/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 | ### Direct funding | Item | Value | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x779877A7B0D9E8603169DdbD7836e478b4624789](https://sepolia.etherscan.io/token/0x779877A7B0D9E8603169DdbD7836e478b4624789) | | VRF Wrapper | [0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1](https://sepolia.etherscan.io/address/0x195f15F2d49d693cE265b4fB0fdDbE15b1850Cc1) | | VRF Coordinator | [0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B](https://sepolia.etherscan.io/address/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 ### OP Mainnet ### Subscription | Item | Value | | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6](https://optimistic.etherscan.io/address/0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6) | | VRF Coordinator | [0x5FE58960F730153eb5A84a47C51BD4E58302E1c8](https://optimistic.etherscan.io/address/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 | ### Direct funding | Item | Value | | | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6](https://optimistic.etherscan.io/address/0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6) | | | VRF Wrapper | [0x6A39cE9604FAD060B32bc35BE2e0D3825B2b8D4B](https://optimistic.etherscan.io/address/0x6A39cE9604FAD060B32bc35BE2e0D3825B2b8D4B) | | | VRF Coordinator | [0x5FE58960F730153eb5A84a47C51BD4E58302E1c8](https://optimistic.etherscan.io/address/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 ### Subscription | Item | Value | | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia-optimism.etherscan.io/token/0xE4aB69C077896252FAFBD49EFD26B5D171A32410) | | VRF Coordinator | [0x02667f44a6a44E4BDddCF80e724512Ad3426B17d](https://sepolia-optimism.etherscan.io/address/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 | ### Direct funding | Item | Value | | | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0xE4aB69C077896252FAFBD49EFD26B5D171A32410](https://sepolia-optimism.etherscan.io/token/0xE4aB69C077896252FAFBD49EFD26B5D171A32410) | | | VRF Wrapper | [0xA8A278BF534BCa72eFd6e6C9ac573E98c21A6171](https://sepolia-optimism.etherscan.io/address/0xA8A278BF534BCa72eFd6e6C9ac573E98c21A6171) | | | VRF Coordinator | [0x02667f44a6a44E4BDddCF80e724512Ad3426B17d](https://sepolia-optimism.etherscan.io/address/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 ### 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/) ### Subscription | Item | Value | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1) | | VRF Coordinator | [0xec0Ed46f36576541C75739E915ADbCb3DE24bD77](https://polygonscan.com/address/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 | ### Direct funding | Item | Value | | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | - | | LINK Token | [0xb0897686c545045aFc77CF20eC7A532E3120E0F1](https://polygonscan.com/address/0xb0897686c545045aFc77CF20eC7A532E3120E0F1) | | | VRF Wrapper | [0xc8F13422c49909F4Ec24BF65EDFBEbe410BB9D7c](https://polygonscan.com/address/0xc8F13422c49909F4Ec24BF65EDFBEbe410BB9D7c) | | | VRF Coordinator | [0xec0Ed46f36576541C75739E915ADbCb3DE24bD77](https://polygonscan.com/address/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 ### Subscription | Item | Value | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904) | | VRF Coordinator | [0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2](https://amoy.polygonscan.com/address/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 | ### Direct funding | Item | Value | | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | - | | LINK Token | [0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904](https://amoy.polygonscan.com/address/0x0fd9e8d3af1aaee056eb9e802c3a762a667b1904) | | | VRF Wrapper | [0x6e6c366a1cd1F92ba87Fd6f96F743B0e6c967Bf0](https://amoy.polygonscan.com/address/0x6e6c366a1cd1F92ba87Fd6f96F743B0e6c967Bf0) | | | VRF Coordinator | [0x343300b5d84D444B2ADc9116FEF1bED02BE49Cf2](https://amoy.polygonscan.com/address/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 ### Ronin Mainnet ### Subscription | Item | Value | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b](https://app.roninchain.com/address/0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b) | | VRF Coordinator | [0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda](https://app.roninchain.com/address/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 | ### Direct funding | Item | Value | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b](https://app.roninchain.com/address/0x3902228D6A3d2Dc44731fD9d45FeE6a61c722D0b) | | VRF Wrapper | [0x3B7d0d0CeC08eBF8dad58aCCa4719791378b2329](https://app.roninchain.com/address/0x3B7d0d0CeC08eBF8dad58aCCa4719791378b2329) | | VRF Coordinator | [0xa18FD3db9B869AD2A8c55267e0D54dbf6ECEbEda](https://app.roninchain.com/address/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 ### Subscription | Item | Value | | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15](https://saigon-app.roninchain.com/address/0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15) | | VRF Coordinator | [0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8](https://saigon-app.roninchain.com/address/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 | ### Direct funding | Item | Value | | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15](https://saigon-app.roninchain.com/address/0x5bB50A6888ee6a67E22afFDFD9513be7740F1c15) | | VRF Wrapper | [0x4664273cf5Eb350c864c2F37F63b045a883F93C6](https://saigon-app.roninchain.com/address/0x4664273cf5Eb350c864c2F37F63b045a883F93C6) | | VRF Coordinator | [0xc052324E6A27D0E4b2CbF0FdFFBCb3796ea8f8B8](https://saigon-app.roninchain.com/address/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 ### Soneium Mainnet ### Subscription | Item | Value | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec](https://soneium.blockscout.com/address/0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec) | | VRF Coordinator | [0xb89BB0aB64b219Ba7702f862020d879786a2BC49](https://soneium.blockscout.com/address/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 | ### Direct funding | Item | Value | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec](https://soneium.blockscout.com/address/0x32D8F819C8080ae44375F8d383Ffd39FC642f3Ec) | | VRF Wrapper | [0x656155C8bD09d1741385C525010590522758345c](https://soneium.blockscout.com/address/0x656155C8bD09d1741385C525010590522758345c) | | VRF Coordinator | [0xb89BB0aB64b219Ba7702f862020d879786a2BC49](https://soneium.blockscout.com/address/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 ### Subscription | Item | Value | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2](https://soneium-minato.blockscout.com/address/0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2) | | VRF Coordinator | [0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47](https://soneium-minato.blockscout.com/address/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 | ### Direct funding | Item | Value | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | LINK Token | [0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2](https://soneium-minato.blockscout.com/address/0x7ea13478Ea3961A0e8b538cb05a9DF0477c79Cd2) | | VRF Wrapper | [0xB64019F234f2A4951261B111C6B43eb0d8f33b76](https://soneium-minato.blockscout.com/address/0xB64019F234f2A4951261B111C6B43eb0d8f33b76) | | VRF Coordinator | [0x3Fa01AB73beB4EA09e78FC0849FCe31d0b035b47](https://soneium-minato.blockscout.com/address/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 | --- # VRF Security Considerations Source: https://docs.chain.link/vrf/v2-5/security 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 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 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 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 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 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](/chainlink-automation). ## Use `VRFConsumerBaseV2Plus` in your contract, to interact with the VRF service If you implement the [subscription method](/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`. ## Avoid ERC-4337 account-abstracted (smart-account) wallets for subscription management Pre-signed ERC-4337 UserOperations can be executed by any bundler until they expire. If executed inside a fulfillment transaction callback, the subscription management call can no-op, delaying or preventing the change. ## Keep your subscription funded well above the minimum balance Fulfillments require sufficient subscription balance at processing time. If the balance sits near the minimum and multiple consumers make concurrent requests, fulfillments can be delayed. After adding funds, it can take some time for previous requests to be processed again. --- # VRF Best Practices Source: https://docs.chain.link/vrf/v2-5/best-practices 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 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 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](/vrf/v2-5/migration-from-v2#compare-example-code) for an example where one request returns multiple random values. ## 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 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); } } ``` --- # VRF Billing Source: https://docs.chain.link/vrf/v2-5/billing This guide explains how to estimate VRF 2.5 costs for both the subscription and direct funding methods. ## Understanding transaction costs ### Subscription 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. ### Direct funding 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 ### Subscription You need to pre-fund your subscription enough to meet the [minimum subscription balance](/vrf/v2-5/overview/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: ``` (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](/vrf/v2-5/supported-networks) for your selected network. ### Direct funding 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: ``` (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](/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](/vrf/v2-5/supported-networks) page. Because the VRF v2.5 Wrapper adds gas overheads, your `callbackGasLimit` must not exceed `maxGasLimit - wrapperGasOverhead`. ### Apply premium ### Subscription The premium is charged as a percentage of the overall gas cost. The premium is defined in the [coordinator contract](/vrf/v2-5/supported-networks). Premium percentages are listed there as whole integers. For example, a 20% premium is listed as `20`. ``` (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. ### Direct funding 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](/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](/vrf/v2-5/supported-networks) page. ``` (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 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](/vrf/v2-5/supported-networks) page. The examples show how to estimate the following: - The [minimum subscription balance](/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 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 LINK | 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](#estimate-vrf-request-cost) for an example of how to calculate the actual request cost. ### Paying in ETH | 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](#estimate-vrf-request-cost) for an example of how to calculate the actual request cost. #### 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 LINK | 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. ### Paying in ETH | 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 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](/vrf/v2-5/supported-networks) page. ### Paying in LINK | 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. ### Paying in ETH | 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. --- # Subscription Method Source: https://docs.chain.link/vrf/v2-5/overview/subscription This section explains how to generate random numbers using the subscription method. > **NOTE: Migrate to V2.5** > > Follow the [migration guide](/vrf/v2-5/migration-from-v2) to learn how VRF has changed in V2.5 and to get example > code. ## 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 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: ![Image](/images/vrf/v2-5/subscription-architecture-diagram.png) 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 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 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](/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](/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](#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](/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 After you submit your request, it is processed using the [Request & Receive Data](#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 Chainlink VRF v2.5 has [subscription limits](#subscription-limits) and [coordinator contract limits](#coordinator-contract-limits). ### Subscription limits Subscriptions are required to maintain a minimum balance, and they can support a limited number of consuming contracts. #### 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](/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. ### LINK ``` (((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: ``` 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) ``` ### Native tokens ``` (((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: ``` 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 Each subscription supports up to 100 consuming contracts. If you need more than 100 consuming contracts, create multiple subscriptions. ### Coordinator contract limits You can see the configuration for each network on the [Supported networks](/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. --- # Direct Funding Method Source: https://docs.chain.link/vrf/v2-5/overview/direct-funding 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. > **NOTE: Migrate to V2.5** > > Follow the [migration guide](/vrf/v2-5/migration-from-v2) to learn how VRF has changed in V2.5 and to get example > code. Unlike the [subscription method](/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](/vrf/v2-5/billing). ## 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: ![Image](/images/vrf/v2-5/direct-funding-architecture-diagram.png) 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 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 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](/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](/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 After you submit your request, it is processed using the [Request & Receive Data](#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](/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 You can see the configuration for each network on the [Supported networks](/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](/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](/vrf/v2-5/billing). --- # VRF Cost Estimation on Arbitrum Source: https://docs.chain.link/vrf/v2-5/arbitrum-cost-estimation 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**](#arbitrum-and-vrf-gas-estimation-code). #### Estimating Arbitrum gas costs with VRF ### Subscription VRF gas costs on L1 networks are calculated based on the amount of verification gas and callback gas used, multiplied by the gas price: ``` (Gas price * (Verification gas + Callback gas)) = total gas cost ``` For VRF Arbitrum transactions, add a buffer to estimate the additional L1 cost: ``` (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. ``` 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: ``` (L2GasPrice * (Verification gas + Callback gas + ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost ``` ### Direct funding 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: ``` (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: ``` (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. ``` 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: ``` (L2GasPrice * (Coordinator overhead gas + Callback gas + Wrapper overhead gas + ((calldataSizeBytes * L1PricePerByte) / L2GasPrice)))) = total estimated gas cost ``` #### 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) ``` --- # Create and manage VRF V2.5 subscriptions Source: 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](#create-a-subscription-programmatically). ### 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 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 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 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 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 contract 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. ### Using a block explorer 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](/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 contract 1. [Fund your new `VRFv2PlusSubscriptionManager` contract](/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. ### Using a block explorer 1. [Fund your new `VRFv2PlusSubscriptionManager` contract](/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](/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 a Random Number Source: https://docs.chain.link/vrf/v2-5/subscription/get-a-random-number 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](/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 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](/resources/link-token-contracts/#sepolia-testnet) If you are new to developing smart contracts on Ethereum, see the [Getting Started](/getting-started/conceptual-overview) guide to learn the basics. ## 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](/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](#create-and-deploy-a-vrf-compatible-contract). ## 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 SubscriptionConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/SubscriptionConsumer.sol) 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. ![Example showing the deploy button with the subscriptionID field filled in Remix](/images/vrf/v2-5/deploy-with-sub-id-filled.png) 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. ![Example showing the contract address listed under the Contracts list in Remix](/images/vrf/v2-5/contract-address-copy-button.png) 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](#request-random-values) from Chainlink VRF. ## 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](/vrf/v2-5/subscription/create-manage#create-a-subscription-programmatically) by using a smart contract instead of the Subscription Manager. > **NOTE: Note on Requesting Randomness** > > Do not allow re-requesting or cancellation of randomness. For more information, see the [VRF Security > Considerations](/vrf/v2-5/security#do-not-allow-re-requesting-or-cancellation-of-randomness) page. ## 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. ```sol // SPDX-License-Identifier: MIT // An example of a consumer contract that relies on a subscription for funding. pragma solidity ^0.8.20; 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 = 100_000; // 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); } } ``` The parameters define how your requests will be processed. You can find the values for your network in the [Configuration](/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`. > **NOTE: Security Considerations** > > Be sure to review your contracts to make sure they follow the best practices on the [security > considerations](/vrf/v2-5/security) page. ## 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. --- # Local testing using a mock subscription contract Source: https://docs.chain.link/vrf/v2-5/subscription/test-locally 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). > **CAUTION: Test on public testnets thoroughly** > > Even though local testing has several benefits, testing with a VRF mock covers the bare minimum of use cases. Make > sure to test your consumer contract thoroughly on public testnets. ## Benefits of local testing ## 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 ### Open the contracts on Remix IDE For local testing, use the default "Remix VM" environment. Open *VRFv2_5Consumer* and compile in Remix: ```sol // SPDX-License-Identifier: MIT // An example of a consumer contract that relies on a subscription for funding. pragma solidity ^0.8.20; 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 = 100_000; // 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 *VRFCoordinatorV2_5Mock* in Remix: ```sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol"; ``` On the *Solidity Compiler* tab, expand the *Advanced Configurations* section and check the *Enable optimization* box before you compile the *VRFCoordinatorV2_5Mock* contract: ![Image](/images/vrf/v2-5/mock/enable-optimization.png) Your Remix IDE file explorer should display *VRFCoordinatorV2_5Mock.sol* and *VRFv2_5Consumer.sol*: ![Image](/images/vrf/v2-5/mock/file-explorer.png) ### Deploy VRFCoordinatorV2_5Mock 1. Open *VRFCoordinatorV2_5Mock.sol*. 2. Under *DEPLOY & RUN TRANSACTIONS*, select *VRFCoordinatorV2_5Mock*. ![Image](/images/vrf/v2-5/mock/deployment-contracts-list.png) 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. ![Image](/images/vrf/v2-5/mock/mock-deployment-parameters.png) You can set: - `_BASEFEE` to 100000000000000000 - `_GASPRICELINK` to 1000000000 - `_WEIPERUNITLINK` to the current LINK/ETH price. Click the "Latest Price" button to view it: 4. Click *transact* to deploy the *VRFCoordinatorV2_5Mock* contract. 5. Once deployed, you should see the *VRFCoordinatorV2_5Mock* contract under *Deployed Contracts*. ![Image](/images/vrf/v2-5/mock/deployed-mock.png) 6. Note the address of the deployed contract. ### 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. ![Image](/images/vrf/v2-5/mock/example-output-sub-id.png) 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 1. In the file explorer, open *VRFv2_5Consumer.sol*. 2. Under *DEPLOY & RUN TRANSACTIONS*, select *RandomNumberConsumerV2_5*. ![Image](/images/vrf/v2-5/mock/deploy-consumer.png) 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 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. ![Image](/images/vrf/v2-5/mock/add-consumer.png) 3. Click *transact*. ### Request random words 1. Under *Deployed Contracts*, open the functions list of your deployed *RandomNumberConsumerV2_5* contract. 2. Click `requestRandomWords`. ![Image](/images/vrf/mock/v2-requestrandomwords.jpg) 3. Click `s_requestId` to display the last request ID. In this example, the output is *1*. ![Image](/images/vrf/v2-5/mock/show-last-request-id.png) 4. Note your request ID. ### 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. ![Image](/images/vrf/v2-5/mock/manual-fulfill-request.png) 3. Click `transact`. ### 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. ![Image](/images/vrf/v2-5/mock/show-random-word.png) 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 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](#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 a Random Number Source: https://docs.chain.link/vrf/v2-5/direct-funding/get-a-random-number 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 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](/resources/link-token-contracts/#sepolia-testnet) If you are new to developing smart contracts on Ethereum, see the [Getting Started](/getting-started/conceptual-overview) guide to learn the basics. ## 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 DirectFundingConsumer.sol in Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/VRF/v2-5/DirectFundingConsumer.sol) 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](#fund-your-contract). ## 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](/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](#clean-up) after you're done with this contract.) ## 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. > **NOTE: Note on Requesting or Cancelling Randomness** > > Do not allow re-requesting or cancellation of randomness. For more information, see the [VRF Security > Considerations](/vrf/v2-5/security#do-not-allow-re-requesting-or-cancellation-of-randomness) page. ## Analyzing the contract In this example, the consuming contract uses static configuration parameters. ```sol // SPDX-License-Identifier: MIT // An example of a consumer contract that directly pays for each request. pragma solidity ^0.8.20; 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 = 100_000; // 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); } } ``` The parameters define how your requests will be processed. You can find the values for your network in the [Supported networks](/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](/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. > **NOTE: Security Considerations** > > Be sure to review your contracts to make sure they follow the best practices on the [security > considerations](/vrf/v2-5/security) page. ## Clean up After you are done with this contract, you can retrieve the remaining testnet tokens to use with other examples: ### LINK 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. ### Native tokens 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.