LogoLogo
  • DFK Developer Docs
  • Contracts
    • Exchanges
      • The Trader
      • The Bazaar
    • Sales & Rentals
      • Hero Auction
      • Hero Rental
      • Equipment Auction
      • Pet Auction
      • Land Auction
    • Summoning
      • Hero Summoning
        • Dark Summoning
      • Pet Hatching
    • Meditation Circle
    • Quests
      • Quest Core
      • Historical Contracts
        • Quest Core
        • Profession Quests
        • Training Quests
    • Void Hunts
    • Patrols
    • PVP Combat
    • Influence System
    • Gardens
      • Master Gardener
    • Jeweler 2.0
      • Power-Ups
      • Jeweler 1.0
    • Profiles
    • DFK Duel
      • Previous Seasons
      • Raffle Master
    • Events
      • Gen0 Reroll
      • Gene Reroll
      • Perilous Journey
    • Bridging
      • Hero Bridge (Synapse)
      • Hero Bridge (LayerZero)
      • Equipment Bridge (Synapse)
      • Equipment Bridge (LayerZero)
      • Item Bridge V2
        • Item Bridge V1 (Deprecated)
      • Gaia's Tear Bridge
    • Miscellaneous
      • Airdrops
      • Charity
      • Flag Storage
      • Gen0 Airdrop (Harmony)
      • Gen0 Sale (Harmony)
      • Graveyard
      • Locked Token Claim
      • Locked Token Raffle
      • Token Disburse
  • NFTs
    • Heroes
      • HeroV4 (Metis)
    • Equipment
      • Weapons
      • Armor
      • Accessories
      • Shared Equipment Mappings
      • CacheCore
      • Equipment Shop
      • Visage Shop
    • Pets
      • Pet Exchange
    • Lands
  • Tokens
    • Ecosystem Token
    • Power Tokens
    • Governance Tokens
    • Currencies
      • DFK Gold
      • Gaia's Tears
    • Inventory Items
    • Gold Crops
    • Combat Items
    • Miscellaneous Tokens
      • Collectible Items
      • Raffle Tickets
  • Crafting
    • Alchemist
    • Nutritionist
    • Stone Carver
    • Vendor (Item Gold Trader)
  • Collections
    • Runes
    • Pet Eggs
    • Pet Treats
    • Potions & Consumables
      • Item Consumer
      • Potion Migrator
    • Enhancement Stones
    • Attunement Crystals
      • Atonement Crystals
    • Pages of the Eternal Story
  • API
    • Community GraphQL API
      • Getting Started
      • Auctions
      • Bazaar
      • Heroes
      • Pets
      • Profiles
    • Hero Metadata & Image API
    • Pet Metadata & Image API
    • Token Supply API
  • Community Builders
    • Kingdom Building Program
    • Developer Resources
    • Community Projects
  • DFK CHain
    • Getting Started
    • Nodes & Validators
    • Bridged Tokens
    • Ecosystem Partners
      • Covalent API
      • SupraOracles Price Feeds
      • SupraOracles VRF
    • Miscellaneous Contracts
Powered by GitBook
On this page
  • What is a Verifiable Random Function (VRF)?
  • How to use SupraOracles' VRF
  • Connect with us!
  1. DFK CHain
  2. Ecosystem Partners

SupraOracles VRF

PreviousSupraOracles Price FeedsNextMiscellaneous Contracts

Last updated 1 year ago

What is a Verifiable Random Function (VRF)?

Blockchain-based verifiable random functions (VRFs) enable the generation of numbers that are as good as random (pseudorandom), and can be (publicly) verified cryptographically. Pseudorandomness guarantees both unpredictability and fairness, whereas tamper-proofness is guaranteed by their public verifiability.

Using a VRF for random number generation (RNG) is the gold standard for on-chain applications that require these properties, such as gaming operations, NFT-minting, lotteries, and randomized processes. More information about VRF can be found .

How to use SupraOracles' VRF

Integrating with SupraOracles' VRF is quick and easy. SupraOracles currently supports many Solidity/EVM-based networks, like DFK Chain TestNet, and non-EVM networks such as Sui and Aptos.

To see all of the networks SupraOracles supports, please visit !

To get started, you will want to visit and review the documentation or continue to follow this guide for a quick start.

Step 1: Create The Supra Router Contract Interface

Add the following code to the requester contract i.e, the contract which uses VRF as a service. You can also add the code in a separate Interface and inherit the interface in the requester contract.

interface ISupraRouter { 
    function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations) external returns(uint256); 
    function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations, uint256 _clientSeed) external returns(uint256); 
}

This interface will help the requester contract interact with the Supra Router contract and through which the requester contract can use the VRF service.

Step 2: Configure the Supra Router Contract Address

Contracts that need random numbers should utilize the Supra Router Contract. In order to do that, they need to create an interface and bind it to the on-chain address of the Supra Router contract.

For DFK TestNet, the address is: 0x473ab8E0FC37CFf3c64ee72C2Aecf3925c2EC086

We’ll store the set the address within the constructor and use it later to interact with the interface.

contract ExampleContract {

    address supraAddr;

    constructor() {
        supraAddr = 0x473ab8E0FC37CFf3c64ee72C2Aecf3925c2EC086;
    }
}

Step 3: Use the VRF service and request a Random Number

In this step, we'll use the “generateRequest” function of the Supra Router Contract to create a request for random numbers. There are two modes for the "generateRequest" function. The only difference between them is that you can optionally provide a client-side input, which will also be part of the payload being threshold signed to provide randomness.

  • _functionSig - a string parameter, here the requester contract will have to pass the function signature which will receive the callback i.e., a random number from the Supra Router Contract. The function signature should be in the form of the function name following the parameters it accepts. We'll see an example later in the document.

  • _rngCount - an integer parameter, it is for the number of random numbers a particular requester wants to generate. Currently, we can generate a maximum of 255 random numbers per request.

  • numConfirmations - an integer parameter that specifies the number of block confirmations needed before supra VRF can generate the random number.

  • _clientSeed (optional) - an optional integer parameter that could be provided by the client (defaults to 0). This is for additional unpredictability. The source of the seed can be a UUID of 256 bits. This can also be from a centralized source. Supra's VRF process requires splitting the contract logic into two functions.

  • The request function - the signature of this function is up to the developer

  • The callback function - the signature must be of the form “uint256 nonce, uint256[] calldata rngList”

function exampleRNG() external {  
     //Function validation and logic
     // requesting 10 random numbers
     uint8 rngCount = 10; 

     // we want to wait for 1 confirmation before the request is considered complete/final
     uint256 numConfirmations = 1; 
     uint256 generated_nonce = ISupraRouter(supraAddr).generateRequest(“exampleCallback(uint256,uint256[])”, rngCount, numConfirmations);

     // store generated_nonce if necessary (eg: in a hashmap)
     // this can be used to track parameters related to the request, such as user address, nft address etc in a lookup table
     // these can be accessed inside the callback since the response from supra will include the nonce
}

Step 4 - Add the validation in the callback function of requester contract

Inside the callback function where the requester contract wants the random number (in this example the callback function is exampleCallback), the requester contract will have to add the validation such that only the Supra router contract can call the function. The validation is necessary to protect against malicious contracts/users executing the callback with fake data.

function exampleCallback(uint256 _nonce ,uint256[] _rngList) external {
    require(msg.sender == supraAddr);
    // Following the required logic of the function
 }

Example Implementation

In the example below,

  • The function getRNGForUser is using the VRF service by calling the generateRequest function of the Supra Router Contract.

  • Then we store the username of the user requesting the random number mapped to the nonce returned by generateRequest.

  • Then the callback function prints the random numbers requested by a specific user and it has the signature: myCallbackUsername(uint256 nonce, uint256[] calldata rngList) Once Supra generates the random number and it is verified by the on-chain logic to be authentic, myCallbackUsername is executed by the Supra Router, which completes the second half of the process. The nonce from the first argument is used to look up the username that originated the request.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ISupraRouter {
   function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations, uint256 _clientSeed) external returns(uint256);
   function generateRequest(string memory _functionSig , uint8 _rngCount, uint256 _numConfirmations) external returns(uint256);
}

contract Interaction {
   address supraAddr;
   constructor() {
       supraAddr = 0x473ab8E0FC37CFf3c64ee72C2Aecf3925c2EC086;
   }

   mapping (uint256 => string ) result;
   mapping (string => uint256[] ) rngForUser;
   function getRNGForUser(uint8 rngCount, string memory username) external {
      uint256 nonce =  ISupraRouter(supraAddr).generateRequest("myCallbackUsername(uint256,uint256[])", rngCount, 1, 123);
      result[nonce] = username;
   }

   function myCallbackUsername(uint256 nonce, uint256[] calldata rngList) external {
      require(msg.sender == supraAddr, "only supra router can call this function");
      uint8 i = 0;
      uint256[] memory x = new uint256[](rngList.length);
      rngForUser[result[nonce]] = x;
      for(i=0; i<rngList.length;i++){
         rngForUser[result[nonce]][i] = rngList[i] % 100;
      }
   }
   
   function viewUserName(string memory username) external view returns (uint256[] memory) {
      return rngForUser[username];
   }
}

Connect with us!

Still looking for answers? We got them! Check out all the ways you can reach us:

For additional tutorials and guides based on example use-cases, please refer to the .

Visit us at

Read our

Chat with us on

Follow us on

Join our

Check us out on

Supra
here
SupraOracles' Networks
SupraOracles' docs site
Supra Docs
supraoracles.com
Docs
Telegram
Twitter
Discord
Youtube