Introduction to chainlink
Chainlink is a decentralized oracle network that connects smart contracts to external data sources, APIs, and payment systems. It was created by Sergey Nazarov and Steve Ellis in 2017 and operates on the Ethereum blockchain.
Chainlink provides a decentralized solution to the Oracle problem by allowing smart contracts to securely and reliably access data and interact with external systems.
Verifiable Randomness Function (VRF)
A blockchain is a predictable, deterministic machine which means the blockchain network behaviour can be accurately predicted and replicated, given the same set of inputs or conditions.
Chainlink VRF provides a verifiable random number generator (RNG) that enables smart contracts to access random values without compromising security or usability. Therefore eliminating the deterministic nature of the blockchain.
There are two means by which smart contracts can get a random number with chainlink VRF, which are:
SUBSCRIPTION METHOD
DIRECT FUNDING METHOD
For the purpose to make this article short, we will discuss the subscription method alone but you can access the chainlink doc to gain more insight.
SUBSCRIPTION METHOD
Getting a random number from the subscription method can be achieved using the two processes of the subscription method, using either Subscription Manager UI or using Programmatic Subscription.
Subscription Manager UI
Manager UI
To create and fund a subscription we first, go to the Subscription Manager and make sure the network is on Sepolia testnet ETH. Add Link token to the subscription, you can get a Link fauet, note funding your subscription manager with Link Token the amount of Link must be between 2 or above Link.
Add the consumer contract to the Subscription Manager UI. You can find the final code in the Github gist.
Subscription Manager UI
Code Explanation
The COORDINATOR
variable is an interface to interact with Chainlink's VRF coordinator from the imported VRFCoordinatorV2Interface.sol
contract,s_subscriptionId
variable stores the subscription ID for the VRF service and requestIds
and lastRequestId
stores the IDs for past VRF requests.
keyHash
is a unique identifier for the VRF service. callbackGasLimit
is the maximum amount of gas that can be used to process a callback request.requestConfirmations
sets the number of confirmations required for a VRF request.numWords
sets the number of random words to generate for a VRF request.
The two events RequestSent
and RequestFulfilled
will emit a VRF request when sent and fulfilled respectively. RequestStatus
stores the status of a VRF request,s_requests
mapping associates a RequestStatus
with a request ID.
Constructor
provides the subscription id for the contract.
VRFCoordinatorV2Interface COORDINATOR;
uint64 public s_subscriptionId;
uint256[] public requestIds;
uint256 public lastRequestId;
bytes32 keyHash = 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c;
uint32 callbackGasLimit = 100000;
uint16 requestConfirmations = 3;
uint32 numWords = 2;
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
struct RequestStatus {
bool fulfilled;
bool exists;
uint256[] randomWords;
}
mapping(uint256 => RequestStatus) public s_requests;
constructor(
uint64 subscriptionId
)
VRFConsumerBaseV2(0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625)
ConfirmedOwner(msg.sender)
{
COORDINATOR = VRFCoordinatorV2Interface(
0x8103B0A8A00be2DDC778e6e7eaa21791Cd364625
);
s_subscriptionId = subscriptionId;
}
fulfillRandomWords
function is an internal function that is called by the VRFConsumerBaseV2 contract when the VRF service returns the requested random numbers. requestRandomWords
is an external function that can be called by the owner of the contract to request random numbers from the VRF service. It calls the requestRandomWords function on the COORDINATOR contract and stores the request ID and status in the contract's state. getRequestStatus
function can be called by anyone to check the status of a specific request ID. It returns a boolean indicating whether the request has been fulfilled and an array of random numbers if it has been fulfilled.
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);
}
Execution of Contract
Using Remix editor to execute the random.sol
contract, After deploying the contract check to get the owner and subscription id of the contract.
To request a random number, call the requestRandomWords
function that generates the random number from the VRF.
Get the initial call to the requestRandomWords
and provide it to the s_requests
to check the status of the request.
Two random number 12 and 19
were generated by the VRF coordinator.
Great, you successfully generated a truly randomised number Bravo ๐ฅณ.
Final Thought
In conclusion, the Chainlink Verifiable Randomness Function (VRF) is a powerful tool that provides secure and verifiable randomness to smart contracts on the blockchain. With VRF, developers can create applications with fair and unbiased random outcomes, enabling a wide range of use cases in areas such as gaming, Defi, lotteries, and prediction markets.
If find this article helpful leave a like and follow me on all my socials. Thanks for reading.