Skip to main content

How to use Randomizer.ai's verifiable random functions (VRFs) in Arbitrum

Community member contribution

The following third-party document was contributed by @DeanPress. Give them a shoutout if you find it useful!

Verifiable random functions (VRFs) are cryptographic methods to generate random numbers in a way that is verifiable and unpredictable. That means anyone can verify that a given number was generated correctly, but no one can predict the output before it's generated, even if they know the input.

VRFs can offer a reliable source of randomness for decentralized apps (dApps), such as games (e.g. card dealing, XP gain, treasure opening, hit/dodge rates), generating NFT traits, and airdrops.

Randomizer VRF

Randomizer is a decentralized VRF protocol on Arbitrum. It uses native ETH for fee settlement, makes fast callbacks to smart contracts, and offers an npm module to bring real-time results to dApps.

Requesting a random number from Randomizer

Here’s an example of how to use the Randomizer VRF with your Arbitrum smart contract:

    interface IRandomizer {
function request(uint256 callbackGasLimit) external returns (uint256);
function request(uint256 callbackGasLimit, uint256 confirmations) external returns (uint256);
function clientWithdrawTo(address _to, uint256 _amount) external;
}

// Coinflip contract
contract CoinFlip {
// Using Randomizer's Arbitrum Goerli address
IRandomizer public randomizer = IRandomizer(0x923096Da90a3b60eb7E12723fA2E1547BA9236Bc);
address public owner;

// Stores each game to the player
mapping(uint256 => address) public flipToAddress;

// Events
event Win(address winner);
event Lose(address loser);

modifier onlyOwner() {
require(msg.sender == owner, "Sender is not owner");
_;
}

// The coin flip containing the random request
function flip() external returns (uint256) {
// Get the latest randomizer contract from the testnet proxy
// Request a random number from the randomizer contract (50k callback limit)
uint256 id = randomizer.request(50000);
// You can also do randomizer.request(50000, 20) to get a callback after 20 confirmations for increased finality security (you can do 1-40 confirmations).
// Store the flip ID and the player address
flipToAddress[id] = msg.sender;
// Return the flip ID
return id;
}

// Callback function called by the randomizer contract when the random value is generated
function randomizerCallback(uint256 _id, bytes32 _value) external {
//Callback can only be called by randomizer
require(msg.sender == address(randomizer), "Caller not Randomizer");
// Get the player address from the flip ID
address player = flipToAddress[_id];
// Convert the random bytes to a number between 0 and 99
uint256 random = uint256(_value) % 100;
// If the random number is less than 50, the player wins
if (random < 50) {
emit Win(player);
} else {
emit Lose(player);
}
}

// Allows the owner to withdraw their deposited randomizer funds
function randomizerWithdraw(uint256 amount) external onlyOwner {
randomizer.clientWithdrawTo(msg.sender, amount);
}
}

Randomizer contract addresses

  • Arbitrum One: 0x5b8bB80f2d72D0C85caB8fB169e8170A05C94bAF
  • Arbitrum Goerli Testnet: 0x923096Da90a3b60eb7E12723fA2E1547BA9236Bc

Full documentation

Refer to Randomizer's documentation for more examples and instructions on how to integrate common features like having the end-user pay the VRF fee, refunding users for overdraft fees, and real-time results.

Full dApp example

Refer to Randomizer's Coinflip game source code for a full-stack example dApp (front-end and smart contract) that integrates real-time results, user payments for fees, and user refunds for overdraft fees.