Migrating from VRF v1
VRF V2.5 replaces both VRF V1 and VRF V2 on November 29, 2024. Learn more about 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 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 page for more details. To find out the premium percentages for the networks you use, see the Supported Networks page.
-
Subscription management: Chainlink VRF v2.5 has a Subscription Manager 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 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 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 page for more details and examples. The new configurations are listed in the 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.
To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the Get a Random Number guide for an example.
-
Set up and fund a subscription in the Subscription Manager at vrf.chain.link.
-
Add the following imports to your contract:
VRFConsumerBaseV2Plus. Remove the v1VRFConsumerBase.solimport.VRFConsumerBaseV2Plusincludes thefulfillRandomWordsfunction. TheVRFConsumerBaseV2Pluscontract imports theIVRFCoordinatorV2Plusinterface, which includes therequestRandomWordsfunction.VRFV2PlusClientis a library used to format your VRF requests.
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"; -
Add a
VRFConsumerBaseV2Plusconstructor, passing in the LINK token address for the network you're using, as shown in the Get a Random Number example. -
Change
requestRandomnessfunction calls torequestRandomWords. TherequestRandomWordsfunction requires several additional parameters. TheextraArgskey allows you to add extra arguments related to new VRF features. Use thenativePaymentargument to enable or disable payment in native tokens.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})) }) ); -
Change
fulfillRandomnessfunction calls tofulfillRandomWords. Update the call to handle the returneduint256[]array instead of the singleuint256variable. -
Use the
setCoordinatorfunction in your contract so that you can easily update the VRF coordinator for future VRF releases. This function is inherited from theIVRFCoordinatorV2Plusinterface.
To modify your existing smart contract code to work with VRF v2.5, complete the following changes. See the Get a Random Number guide for an example.
-
Import and inherit the
VRFV2PlusWrapperConsumerBasecontract and remove the v1VRFConsumerBase.solimport. This contract includes thefulfillRandomWordsfunction. -
Add a
VRFV2PlusWrapperConsumerBaseconstructor, passing in the VRF wrapper address for the network you're using, as shown in the Get a Random Number example. -
You can still call the
requestRandomnessfunction. However, the v2requestRandomnessfunction requires several different parameters. See the Supported networks page to adjust them for your own needs.- The
requestRandomnessfunction in the wrapper contract requires a newextraArgsargument that allows you to add extra arguments related to new VRF features. Use thenativePaymentargument to enable or disable payment in native tokens. - Additionally, the
requestRandomnessfunction now returns two arguments instead of one: the request ID and the request price.
bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs ); - The
-
If you're paying for requests with LINK, you can still call the
requestRandomnessfunction. However, if you're paying with native tokens, call therequestRandomnessPayInNativefunction instead.-
Both functions return two arguments instead of one: the request ID and the request price.
-
Both functions require one additional parameter,
extraArgs. UsenativePaymentto specify whether or not you want to pay for VRF requests using native tokens:bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs );bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: true}) ); (uint256 reqId, uint256 reqPrice) = requestRandomnessPayInNative( callbackGasLimit, requestConfirmations, numWords, extraArgs );
-
-
Change
fulfillRandomnessfunction calls tofulfillRandomWords. Update the call to handle the returneduint256[]array instead of the singleuint256variable.
Migration walkthrough
VRF v2.5 currently supports subscriptions and direct funding on all supported networks. To migrate, you need to update your existing smart contract code and redeploy your contracts.
If using subscriptions, create and fund a new VRF v2.5 subscription.
For direct funding, deploy the DirectFundingConsumer example:
Update your code
To modify your existing smart contract code to work with VRF v2.5, complete the following changes:
-
Import the
VRFConsumerBaseV2Pluscontract and remove the v2VRFConsumerBaseV2import. -
Import the VRF v2.5 coordinator,
VRFCoordinatorV2_5, and update any old references to the VRF V2 coordinator in your contract. -
Add a
VRFConsumerBaseV2Plusconstructor, passing in the LINK token address for the network you're using. -
Update your
requestRandomWordsfunction calls to reflect the new request structure for VRF v2.5. Make sure to include the newextraArgspart of theVRFV2PlusClient.RandomWordsRequestobject, and specify whether or not you want to pay for VRF requests using native tokens: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})) }) );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})) }) ); -
When using the
@chainlink/contractspackage version 1.1.1 and later, update yourfulfillRandomWordsfunction signature to match theVRFConsumerBaseV2Pluscontract, which has changed to:function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords)In the
@chainlink/contractspackage version 1.1.0 and earlier, therandomWordsparameter has amemorystorage location.
-
Import the
VRFV2PlusWrapperConsumerBasecontract and remove the v2VRFV2WrapperConsumerBaseimport. -
Add a
VRFV2PlusWrapperConsumerBaseconstructor, 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. -
If you're paying for requests with LINK, you can still call the
requestRandomnessfunction. However, if you're paying with native tokens, call therequestRandomnessPayInNativefunction instead.Both functions require one additional parameter,
extraArgs. UsenativePaymentto specify whether or not you want to pay for VRF requests using native tokens:bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ); (uint256 reqId, uint256 reqPrice) = requestRandomness( callbackGasLimit, requestConfirmations, numWords, extraArgs );bytes memory extraArgs = VRFV2PlusClient._argsToBytes( VRFV2PlusClient.ExtraArgsV1({nativePayment: true}) ); (uint256 reqId, uint256 reqPrice) = requestRandomnessPayInNative( callbackGasLimit, requestConfirmations, numWords, extraArgs ); -
The V2.5
requestRandomnessandrequestRandomnessPayInNativefunctions both return a tuple:(uint256 requestId, uint256 requestPrice). Adjust yourrequestRandomWordsfunction or any other functions in your code where you call the V2.5 wrapper'srequestRandomnessorrequestRandomnessPayInNativefunctions. -
Make sure your contract has a withdraw function for both native tokens and LINK. Both are included in the direct funding example code and the
VRFV2PlusWrapperConsumerExamplecontract.
View example code
View example code for both VRF 2.5 subscription and direct funding:
Open the full example SubscriptionConsumer contract:
Open the full example DirectFundingConsumer contract: