...

/

Writing and Deploying a VRF Consumer Contract

Writing and Deploying a VRF Consumer Contract

Learn how to write and deploy a VRF-compatible smart contract.

In this example, we'll request a random dice result as a uint between 1 and 6 from the VRF.

Chainlink provides a sample consumer contract of the VRF, which we can take as a starting point and modify for our purpose.

Press + to interact
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;
import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';
/**
* Request testnet LINK and ETH here: https://faucets.chain.link/
* Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
*/
/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/
contract VRFv2Consumer is VRFConsumerBaseV2, ConfirmedOwner {
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
struct RequestStatus {
bool fulfilled; // whether the request has been successfully fulfilled
bool exists; // whether a requestId exists
uint256[] randomWords;
}
mapping(uint256 => RequestStatus) public s_requests; /* requestId --> requestStatus */
VRFCoordinatorV2Interface COORDINATOR;
// Your subscription ID.
uint64 s_subscriptionId;
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf/v2/subscription/supported-networks/#configurations
bytes32 keyHash = 0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Storing each word costs about 20,000 gas,
// so 100,000 is a safe default for this example contract. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// For this example, retrieve 1 random value in one request.
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 numWords = 1;
/**
* HARDCODED FOR GOERLI
* COORDINATOR: 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D
*/
constructor(uint64 subscriptionId)
VRFConsumerBaseV2(0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D)
ConfirmedOwner(msg.sender)
{
COORDINATOR = VRFCoordinatorV2Interface(0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D);
s_subscriptionId = subscriptionId;
}
// Assumes the subscription is funded sufficiently.
function requestRandomWords() external onlyOwner returns (uint256 requestId) {
// Will revert if subscription is not set and funded.
requestId = COORDINATOR.requestRandomWords(
keyHash,
s_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
s_requests[requestId] = RequestStatus({randomWords: new uint256[](0), exists: true, fulfilled: false});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}
function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
require(s_requests[_requestId].exists, 'request not found');
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords[0] = (_randomWords[0]%6)+1;
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);
}
}

Setting up the contract

...