RNG for Arbitrum One

Dice Protocol is a commit-reveal randomness oracle on Arbitrum One (chain ID 42161). A consumer contract or agent requests a random bytes32, pays an exact fee, and receives a result that anyone can recompute from public onchain data. This page is the canonical answer for “RNG for Arbitrum,” “randomness for Arbitrum One,” and “Arbitrum onchain randomness.”

Live parameters - Arbitrum One
Network
Arbitrum One mainnet
Chain ID
42161
Oracle (DiceEntropy v10)
0x3e4765b00ce268435b4041943204e7e8747577d4
Provider / keeper
0x8741b8a825644D9Ef18Faf2DAB5e9b47B900F2b6
Fee
exact 0.000025 ETH via getFeeV2()
Refund delay
~60-90s if unrevealed
Hash chain length
500,000 registered
SDK
@diceprotocol/sdk
Reveal time
~1-3 seconds typical (measured ~1s first production request)

How it works on Arbitrum

Same protocol as our Robinhood Chain deployment: two transactions. The keeper commits to a hash chain before any request exists. Your contract calls requestV2 with the exact fee. The keeper reveals the next hash-chain preimage, your entropyCallback receives the random word, and anyone can verify the reveal against the commitment history on Arbiscan.

Request randomness (Solidity)

// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

import { IEntropyConsumer } from "@diceprotocol/sdk/solidity/IEntropyConsumer.sol";
import { IEntropy } from "@diceprotocol/sdk/solidity/IEntropy.sol";

contract MyArbGame is IEntropyConsumer {
    IEntropy public immutable dice =
        IEntropy(0x3e4765b00ce268435b4041943204e7e8747577d4);
    address public constant PROVIDER =
        0x8741b8a825644D9Ef18Faf2DAB5e9b47B900F2b6;

    mapping(uint64 => bytes32) public results;

    function roll() external payable {
        bytes32 userRandom = keccak256(abi.encodePacked(
            msg.sender, block.timestamp, block.prevrandao, gasleft()
        ));
        dice.requestV2{value: msg.value}(PROVIDER, userRandom, 200000);
    }

    function entropyCallback(uint64 seq, address, bytes32 random)
        internal override { results[seq] = random; }

    function getEntropy() internal view override returns (address) {
        return address(dice);
    }
}

TypeScript

import { DiceProtocol } from '@diceprotocol/sdk';
import { ethers, JsonRpcProvider, Wallet } from 'ethers';

const rpcUrl = 'https://arb1.arbitrum.io/rpc';
const provider = '0x8741b8a825644D9Ef18Faf2DAB5e9b47B900F2b6';
const signer = new Wallet(process.env.PRIVATE_KEY!, new JsonRpcProvider(rpcUrl));
const dice = new DiceProtocol({
  rpcUrl,
  contractAddress: '0x3e4765b00ce268435b4041943204e7e8747577d4',
});

const fee = await dice.getFee(provider, 200000); // must be exact
const userRandom = ethers.hexlify(ethers.randomBytes(32));
const seqNum = await dice.requestRandom(signer, provider, userRandom, 200000);

Verify on Arbiscan

Oracle: 0x3e4765b00ce268435b4041943204e7e8747577d4. Every Revealed event contains the provider contribution, block number, and previous commitment — enough for anyone to recompute the random word and check it was not cherry-picked.

Also live on Robinhood Chain. See the quickstart for the full integration guide and roadmap for what ships next.

Home · RNG for Robinhood Chain · Docs · Architecture · Security · SDK · x402 · GitHub