Introducing Randomizer.AI: Random Numbers for Layer 2 (out now on zkSync v2!)
Current RNG solutions
If you want random numbers, you may have considered one of the following solutions:
Using block data like a combination of the last block’s hash with the current block difficulty is an easy way to get a number that’s random but predictable. A miner can simply not include a specific transaction until the “random” number benefits them.
To make this method less predictable, you can have the user “lock in” their request by having them call the function first, and then utilize a future block’s data after the transaction is made (e.g.
n + 10 where n is the block height of the first transaction’s block).
This is more secure but requires a specific future block’s data (e.g. the 10th block after the request). So you need a callback function that’s called within 255 blocks from when the request is made, otherwise the future block’s data is no longer available from within the smart contract.
2. RANDAO on Ethereum PoS
After The Merge you can get relatively unpredictable pseudo-random numbers by requesting the next RANDAO value.
This is a reliable source of randomness: it’s very difficult for nodes to influence a future RANDAO value, but it also takes a minimum of 6 minutes to generate (the higher the delay the more secure the number).
Unpredictable for users.
Native on Ethereum PoS.
If EIP-1449 passes you can already rely on a future block’s
difficultyvalue (in Ethereum PoW) and the slot will automatically transition to the PoS
prevrandaovalue in the future.
Usage limited to the Ethereum network. Other EVM-based L1 and L2 networks may not support RANDAO, creating “blockchain lock-in” for your smart contract.
Need to integrate callbacks yourself. Like when using a future blockhash, a smart contract function needs to be called to store or use the future randao value once it’s available.
3. Chainlink VRF
A third-party solution is Chainlink Verifiable Random Numbers. The process is as follows:
A developer creates a subscription account in the Chainlink VRF contract for their contract’s address and funds it with LINK tokens.
When a user calls the contract, the contract requests randomness from the Chainlink VRF contract.
Chainlink oracles generate random values with the method of generation verified on-chain, ensuring the random values could not have been tampered with by any party.
Chainlink’s coordinator calls your contract’s callback function with the random values.
Your contract’s callback function is called automatically when the random value is available.
Used by many projects e.g. for NFT trait generation.
Most expensive out of all available solutions on Ethereum: At time of writing a single request costs roughly $85 USD ($35 request, $4.45 premium, $40 fulfillment).
Developers need to fund a subscription account with LINK tokens which adds extra complexity and gas fees if you want to fund it with ETH (i.e. route in-contract DEX calls).
Gas fees converted to LINK (plus a static fee of currently 0.25 LINK) makes the cost of a single request fluctuate with the price of LINK.
If your subscription account runs out of LINK then your contract stops working until it’s funded again.
Currently only a few networks are supported (Ethereum, Polygon, BNB Chain).
It’s generally unclear how the Chainlink protocol works, shown by this recent thread about how code reviewers had to dive into the contracts to show that Chainlink’s price oracles are simply a 3/20 multisig: “If 3 of these 20 keys are compromised in any way (hack, regulatory attack, etc), DeFi could experience an unprecedented black swan and suffer irreversible destruction.”
4. API3 QRNG
A centralized “quantum-powered” random number generator service offered by API3 in partnership with the Australian National University.
No premium fees: this service is built to “give back” to the Web3 industry, so developers are expected to only pay for gas fees.
Centralized: the service is a smart contract that accepts any value sent to it from the owner wallet.
“Just trust us, bro”: You have to trust that the numbers are random. There is no on-chain proof that the values are random or unpredictable. The only source of reliability is that the node (sourcing the random values) is operated by the Australian National University. If a bad actor gains access to the private key of the node, it’s over.
One party has full control over your deposit: To pay for the randomness fees you have to send ETH to a “sponsor wallet”. The “QRNG node” owns the private keys to these addresses, so they have full ownership over your deposit.
In short: the API3 QRNG is a fully centralized service where you have to trust a single party with not only the values being sent to your contract, but also with your deposited funds.
None of these solutions worked for our needs, so we built...
Randomizer: a simple and effective solution
Randomizer.AI is a new RNG solution built on Solidity.
Randomizer sends verifiably unpredictable bytes to requesting contracts on any L1 or L2 chain, using ETH for settlement.
You don’t need to mess with other tokens to pay for randomness. Simply deposit ETH to Randomizer's contract (you can also have the end user pay for it within a function), and receive a callback with random bytes in seconds!
The method is as follows:
A developer calls the
clientDeposit()function in the Randomizer contract along with some ETH and their contract address.
Their smart contract requests a random number to Randomizer, to be signed by 3 beacons.
2 beacons are pseudo-randomly selected, sign request’s unique data, and then send their VRF response to the Randomizer contract. VRF responses are verified using on-chain elliptic curve cryptography to guarantee there has been no possible tampering.
The 2nd beacon uses both submitted values as a random hash to select the final beacon (this ensures that the final submitter beacon is not known at request time).
The final beacon submits its signature, then combines all signatures in the order that the beacons were selected and generates the unpredictable bytes.
The requesting contract’s
RandomizerCallback(id, value)function is called by Randomizer's contract, with the request id and random bytes. The contract can now do anything it wants with the value.
With on-chain validation, the values cannot be tampered with. The result value is unpredictable to the user and smart contract.
Values are verified on-chain (i.e. VRF), making the result tamper-proof.
Fast and cheap on Ethereum Layer 2 (e.g. Arbitrum, Optimism, and zkSync).
Native ETH payments. Developers can even relay the fees for random number generation to the user by making their request function
Decentralized: you don’t need to trust any centralized party to not tamper with your values, and fee transfers are handled within Randomizer's smart contract, so you’re never overpaying.
Zero-cost randomness by using a future random value requested by other contracts (only request your own as a fallback).
Randomizer will become a DAO in the future with its own unique Governance NFT.
Want to build with Randomizer? Visit https://randomizer.ai for access to the docs, dashboard, and Discord!