🛠️ Implementation: Build a Lottery

Discover how to integrate Chainlink VRF in smart contracts

Generate provably fair random numbers on-chain

Implementation Guide

Implementing verifiable randomness depends on your application's requirements: security level, cost constraints, and latency tolerance. Chainlink VRF offers the easiest integration for most projects, while commit-reveal is ideal for low-cost applications, and VDF provides maximum security for high-value scenarios.

Implementation Comparison

Choose your implementation approach based on security, cost, and complexity requirements.

Chainlink VRF v2

Complexity
Medium
Gas Cost
~200k gas
External Cost
$5-10 per request
Setup
Subscription required

Smart Contract Code

Solidity ^0.8.0
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";

contract RandomNFT is VRFConsumerBaseV2 {
    VRFCoordinatorV2Interface COORDINATOR;
    uint64 subscriptionId;
    bytes32 keyHash;
    uint32 callbackGasLimit = 100000;
    uint16 requestConfirmations = 3;
    uint32 numWords = 1;
    
    mapping(uint256 => address) public requestToSender;
    
    constructor(uint64 _subscriptionId) 
        VRFConsumerBaseV2(0x271682DEB8C4E0901D1a1550aD2e64D568E69909) 
    {
        COORDINATOR = VRFCoordinatorV2Interface(
            0x271682DEB8C4E0901D1a1550aD2e64D568E69909
        );
        subscriptionId = _subscriptionId;
        keyHash = 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef;
    }
    
    function requestRandomNFT() external returns (uint256 requestId) {
        requestId = COORDINATOR.requestRandomWords(
            keyHash,
            subscriptionId,
            requestConfirmations,
            callbackGasLimit,
            numWords
        );
        requestToSender[requestId] = msg.sender;
        return requestId;
    }
    
    function fulfillRandomWords(
        uint256 requestId,
        uint256[] memory randomWords
    ) internal override {
        uint256 randomTokenId = randomWords[0] % 10000;
        address nftOwner = requestToSender[requestId];
        _mintNFT(nftOwner, randomTokenId);
    }
}

Gas Cost Estimator

Estimated Gas
100,000
gas units
Cost @ 50 gwei
$10.00
assuming $2000 ETH
Requests per ETH
200
at current gas price

📝 Best Practices

1.
Choose the right solution
Low-value gaming: commit-reveal. High-value DeFi: Chainlink VRF. Maximum security: VDF
2.
Handle callback failures
VRF callbacks can fail. Implement fallback mechanisms and re-request logic
3.
Don't trust block.prevrandao alone
Validators can manipulate. Always combine with VRF or commit-reveal
4.
Monitor subscription balance
Chainlink VRF requires funded subscription. Set up alerts to avoid service interruption

Production Checklist

Security Audit
Audit randomness implementation by reputable firm
Test on Testnet
Verify VRF requests and callbacks work correctly
Fallback Mechanisms
Handle edge cases: callback failures, non-reveals, timeouts
Monitoring & Alerts
Track request status, subscription balance, callback success rate
Documentation
Document randomness source and verification process for transparency