Documentation Randomizer Quick Start
Funding your contract
- Open the Dashboard, connect with Metamask to the desired network and wallet.
- Under Fund Contract, paste your contract address.
- Enter an amount of ETH you'd like to fund the contract with and click Deposit.
Make sure your contract remains funded so it can make request calls. You can also have contract end-users pay for the fee by implementing estimateFee. To withdraw funds from Randomizer, implement the clientWithdrawTo function.
Making a request
NOTE: zkSync v2 Testnet version is coming back soon.
To make a request, make sure your contract is funded with ETH and then implement the function randomizer.request(uint256 callbackGasLimit)
in an external function within your smart contract. This function will return a unique uint256 ID
that your contract can store and retrieve once it receives the callback.
The Randomizer protocol will then call your
randomizerCallback(uint256 id, bytes32 value)
function with the
request id and random value.
Contract addresses
Implement any address below to make calls to Randomizer.
- Arbitrum One: 0x5b8bB80f2d72D0C85caB8fB169e8170A05C94bAF
- Arbitrum Goerli: 0x923096Da90a3b60eb7E12723fA2E1547BA9236Bc
Contract Example
// Randomizer protocol interface
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 {
// Arbitrum goerli
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) % 99;
// 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);
}
}
Withdrawing Funds
To withdraw funds, implement the function randomizer.clientWithdrawTo(address to, uint256 amount)
into your smart contract. Make sure it's only callable by pre-approved accounts.
You can also call require the fees to be covered by users by using one of the following functions in your smart contract:
randomizer.estimateFee(uint256 callbackGasLimit)
randomizer.estimateFee(uint256 callbackGasLimit, uint256 confirmations)
You can use these estimateFee functions to get the contract user to pay for the gas fee before
making the request, by making your request-making function "payable" and adding
require(msg.value >= estimateFee)
.
You can also use these special views in your front-end for fee estimates, using a gas price given by a web3 provider, which you can use to calculate how much ETH users should attach to their transaction to pay for the request:
await randomizer.estimateFeeUsingGasPrice(uint256 callbackGasLimit, uint256 gasPrice)
await randomizer.estimateFeeUsingConfirmationsAndGasPrice(uint256 callbackGasLimit, uint256 confirmations, uint256 gasPrice)
- ✅ Launch alpha versions Layer 2 testnets.
- ✅ Onboard community-operated beacons.
- ✅ Complete code audits.
- ✅ Deploy platform under a Business Service License, a.k.a. a time-delayed GPL-2.0-or-later license (BUSL-1.1).
- ✅ Launch platform to mainnet.
- Distribute original digital assets.
Real-time Results
You can implement Randomizer's Real-Time npm package to give users a real-time experience. For example, you can display the results of a coinflip directly after a "flip" transaction, and update the user balance immediately in the front-end, all before the result is on-chain and your contract's callback function is called.
Front-end source code + a smart contract for an example coinflip game is available here.
How it works: Beacons send their VRF data to the sequencer before their transactions are verified on-chain. This lets the sequencer process the data off-chain and send the expected result to your front-end using websockets.
Expected Result Ensurance: In the case where a beacon sent VRF data to the sequencer but hasn't submitted the data on-chain (e.g. due to inability to pay for gas fees), the sequencer can submit the beacon's VRF data on their behalf after half the request's expiration period has passed. This helps to ensure that the expected real-time result matches the eventual on-chain result. This time window is enforced in the smart contract, so the Sequencer can never front-run any beacons. In the case neither the beacon or the sequencer were able to submit the request, the request will be renewed. In the case of a renewal, the initial value returned to your front-end by the sequencer will not be the same as the final result. Therefore if you integrate the Real-Time package, your frontend should always clarify that the real-time result is the "expected" result and you should update the front-end on a final on-chain result.
Roadmap
Beacons
Beacons are in the process of being operated by independent projects and ecosystem developers on mainnet.
Governance
The protocol will be governed in a decentralized manner, TBA.