Skip to main content

Randomness

The randomness-solidity library provides a minimal, plug-and-play interface for requesting secure, verifiable randomness from the dcipher network. It is ideal for evm-compatible smart contracts that require unpredictable randomness, such as raffles, games, randomized NFT drops, or fair selections.

The core of this library is a base contract, RandomnessReceiverBase, which abstracts away all low-level request/response logic using a threshold signature scheme from the dcipher network. Developers simply inherit from it and override a callback to use the random result.

πŸš€ This Quickstart Walks You Through:

  1. Setting up a new Hardhat project
  2. Installing the randomness-solidity & writing a basic randomness consumer contract
  3. Deploying it to Base Sepolia with a known RandomnessSender
  4. Requesting and consuming randomness
  5. Interacting with the contract to retrieve the result

🧰 Prerequisites​

Before you begin, ensure you have the following:

  • Node.js & npm
  • Basic familiarity with Solidity and smart contract development

1. Set Up a New Hardhat Project​

mkdir my-randomness-app && cd my-randomness-app
npm init -y
npm install --save-dev hardhat
npx hardhat init

When prompted, choose β€œCreate a TypeScript project” and follow the instructions to finish the init process.

note

πŸ’‘ Hardhat provides a full Ethereum development environment and is one of the most widely used frameworks for writing, testing, and deploying smart contracts. Besides Hardhat, you can also choose other popular frameworks to create the smart contract project, such as Foundry.

2. Install the randomness-solidity Library​

To extend the library from randomness-solidity, we first need to install the library into your project.

npm install randomness-solidity

This package includes the RandomnessReceiverBase contract and supporting utilities.

3. Create a Randomness Consumer Contract​

Create a new solidity file under the /contract folder: /MyRandomConsumer.sol. This smart contract will inherit RandomnessReceiverBase and implement the logic to request and consume the randomness.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { RandomnessReceiverBase } from "randomness-solidity/src/RandomnessReceiverBase.sol";

contract MyRandomConsumer is RandomnessReceiverBase {
uint256 public requestId;
bytes32 public randomValue;

event RandomnessRequested(uint256 indexed requestId);
event RandomnessFulfilled(uint256 indexed requestId, bytes32 randomValue);

constructor(address randomnessSender) RandomnessReceiverBase(randomnessSender) {}

/// @notice Called by user to request randomness
function getRandomness() external {
requestId = requestRandomness();
emit RandomnessRequested(requestId);
}

/// @notice Called by the randomnessSender to fulfill the request
function onRandomnessReceived(uint256 requestID, bytes32 _randomness) internal override {
require(requestId == requestID, "Request ID mismatch");
randomValue = _randomness;

emit RandomnessFulfilled(requestID, _randomness);
// You can add any logic to consume randomness value here.
}
}

🧠 Explanation

CodePurpose
RandomnessReceiverBaseBase contract handles the request/response logic with the randomness provider.
constructor(address sender)Requires the deployed RandomnessSender contract address.
getRandomness()Initiates the randomness request.
onRandomnessReceived(...)Override this function with your project logic consuming randomness. It will be invoked automatically once the random value is received from the dcipher network.

4. Deploy the Contract​

We will use Hardhat Ignition to manage smart contract deployments. Let’s create a file ignition/modules/MyRandomConsumer.js with the following code to deploy MyRandomConsumer.

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

const randomnessSenderAddress = "0xRandomnessSenderAddressOnBase";

const RandomnessModule = buildModule("RandomnessModule", (m) => {
const lock = m.contract("MyRandomConsumer", [randomnessSenderAddress]);

return { lock };
});

export default RandomnessModule;

Then we should the add desired network into hardhat.config.js - in this example we are using Base Sepolia Testnet. Add your private key for the deployer wallet with test token funded. We advise using a .env file to manager your secrets to avoid leaking them.

module.exports = {
solidity: "0.8.28",
networks: {
baseSepolia: {
url: "https://sepolia.base.org/",
chainId: 84532,
accounts: [PRIVATE_KEY]
}
}
}

Deploy using:

npx hardhat ignition deploy ./ignition/modules/MyRandomConsumer.ts --network baseSepolia
note

Use a network where RandomnessSender is deployed (e.g., Filecoin Calibration, Base, etc.). Check Networks page for deployed addresses.

5. Interact with the Contract​

Once deployed:

  1. Call getRandomness() on your contract.
  2. The dcipher network monitors the chain for requests, generates the randomness with a threshold signature and calls back to the RandomnessSender contract.
  3. The network delivers randomness to onRandomnessReceived().

πŸ§ͺ A. Use Hardhat Console​

npx hardhat console --network <your-network>
const consumerAddress = "0xContractAddressEncodedAsHex";
const MyRandomConsumer = await ethers.getContractFactory("MyRandomConsumer");
const consumer = await MyRandomConsumer.attach(consumerAddress);

// Request randomness
await consumer.getRandomness();

Wait ~1–2 minutes for fulfillment, then:

await consumer.randomValue();

βœ… Example Output​

> await consumer.requestRandomness()
// [Tx submitted]

> await consumer.randomValue()
// '0x0000000000000000000000000000000000000000000000000000000000000000'

...wait 1–2 minutes...

> await consumer.randomValue()
'0x9ec2573095983f37e7ed3d3cd73251e6cc6c44567dbcf231675ea22ccef8c898'

πŸ§ͺ B. Use Frontend or Script​

const consumer = new ethers.Contract(consumerAddress, consumerAbi, signer);
await consumer.getRandomness();

πŸ’‘ The event emitted in onRandomnessReceived() can also be listened for via frontend code.


🧠 Summary​

StepPurpose
inherit RandomnessReceiverBaseConnect your contract to the randomness flow
Deploy with sender addressMust point to deployed RandomnessSender
Call getRandomness()Kicks off a randomness request from randomnessSender
Override onRandomnessReceived()Handle the randomness callback when fulfilled.

By following this quickstart, you've built a simple Solidity project that can securely request and consume verifiable randomness from the dcipher network using the randomness-solidity library. This foundational setup allows you to easily extend your contract logic, whether you're building games, lotteries, randomized NFT minting, or any application that requires verifiable randomness..

For advanced testing, callback simulations, or extending contract logic, refer to the full documentation and source.