Skip to content

Instantly share code, notes, and snippets.

@lebe24
Created April 7, 2023 16:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lebe24/b05105dd7fdf9acac33458c2567c4fea to your computer and use it in GitHub Desktop.
Save lebe24/b05105dd7fdf9acac33458c2567c4fea to your computer and use it in GitHub Desktop.
Random number generation with chainlink VRF
// 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";
contract VRFv2Consumer is VRFConsumerBaseV2, ConfirmedOwner {
VRFCoordinatorV2Interface COORDINATOR;
// Your subscription ID.
uint64 public s_subscriptionId;
// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf/v2/subscription/supported-networks/#configurations
bytes32 keyHash = 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
// Depends on the number of requested values that you want sent to the
// fulfillRandomWords() function. Storing each word costs about 20,000 gas,
// so 100,000 is a safe default for this example contract. Test and adjust
// this limit based on the network that you select, the size of the request,
// and the processing of the callback request in the fulfillRandomWords()
// function.
uint32 callbackGasLimit = 100000;
// The default is 3, but you can set this higher.
uint16 requestConfirmations = 3;
// Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
uint32 numWords = 2;
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 */
/**
* HARDCODED FOR SEPOLIA
* COORDINATOR: 0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
*/
constructor(
uint64 subscriptionId
)
VRFConsumerBaseV2(0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625)
ConfirmedOwner(msg.sender)
{
COORDINATOR = VRFCoordinatorV2Interface(
0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
);
s_subscriptionId = subscriptionId;
}
function fulfillRandomWords(
uint256 _requestId,
uint256[] memory _randomWords
) internal override {
require(s_requests[_requestId].exists, "request not found");
s_requests[_requestId].fulfilled = true;
// Generate a number from 0 - 20
for (uint256 i = 0; i < _randomWords.length; i++) {
_randomWords[i] = _randomWords[i] % uint256(20) + 1;
}
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(_requestId, _randomWords);
}
// 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 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);
}
}
@lebe24
Copy link
Author

lebe24 commented Apr 7, 2023

Generating random number with chainlink vrf subscription method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment