Skip to main content

Quickstart

Developer preview

Anyrand is in developer preview. All nodes of the drand network used by Anyrand are currently run by a single operator. This network will eventually be deprecated in favour of the canonical drand network that will be run by the League of Entropy. Contract addresses will change.

Unaudited code

The Anyrand codebase contains some rather unique cryptography and has not been audited. Use at your own risk.

You request verifiable randomness from your contract, and the Anyrand network will deliver you verifiable randomness. Let's get to it!

How to receive randomness

Implement the following interface in your contract that will receive the randomness. The Anyrand network will deliver randomness through the function receiveRandomWords. Note that the length of the randomWords array is currently always 1.

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

interface IRandomiserCallback {
/// @notice Receive random words from a randomiser.
/// @dev Ensure that proper access control is enforced on this function;
/// only the designated randomiser may call this function and the
/// requestId should be as expected from the randomness request.
/// @param requestId The identifier for the original randomness request
/// @param randomWords An arbitrary array of random numbers
function receiveRandomWords(
uint256 requestId,
uint256[] calldata randomWords
) external;
}

warning

Ensure that only the Anyrand contract that you make requests to is allowed to call this function.

How to request randomness

Once we have implemented the IRandomiserCallback interface, we're ready to request randomness from the Anyrand contract. The Anyrand contract implements the IAnyrand interface, which is provided below.

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

interface IAnyrand {
/// @notice Compute the total request price
/// @param callbackGasLimit The callback gas limit that will be used for
/// the randomness request
function getRequestPrice(
uint256 callbackGasLimit
) external view returns (uint256);

/// @notice Request randomness
/// @param deadline Timestamp of when the randomness should be fulfilled. A
/// beacon round closest to this timestamp (rounding up to the nearest
/// future round) will be used as the round from which to derive
/// randomness.
/// @param callbackGasLimit Gas limit for callback
function requestRandomness(
uint256 deadline,
uint256 callbackGasLimit
) external payable returns (uint256);
}

It is necessary to first get a request price using the getRequestPrice function, which will return the price you must pay (in the native currency of the network) when invoking requestRandomness.

tip

requestRandomness returns a uin256 requestId that can be used to correlate your request with the callback.

Example basic consumer

The full request and fulfillment cycle is shown below in an example basic consumer contract. You should be able to use this as a starting point.

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;

import {IRandomiserCallback} from "./IRandomiserCallback.sol";
import {IAnyrand} from "./IAnyrand.sol";

/// @title AnyrandConsumer
contract AnyrandConsumer is IRandomiserCallback {
/// @notice Anyrand instance
address public immutable anyrand;
/// @notice Recorded randomness. A special value of 1 means the request is
/// inflight
mapping(uint256 requestId => uint256) public randomness;

event RandomnessReceived(uint256 randomness);

constructor(address anyrand_) {
anyrand = anyrand_;
}

/// @notice Request a random number, calling back to this contract
function getRandom(
uint256 secondsToWait,
uint256 callbackGasLimit
) external payable {
uint256 requestPrice = IAnyrand(randomiser).getRequestPrice(500_000);
if (address(this).balance < requestPrice) {
revert InsufficientOperationalFunds(
accruedCommunityFees,
requestPrice
);
}
uint256 requestId = IAnyrand(anyrand).requestRandomness{
value: requestPrice
}(block.timestamp + secondsToWait, callbackGasLimit);
randomness[requestId] = 1;
}

/// @notice See {IRandomiserCallback-receiveRandomWords}
function receiveRandomWords(
uint256 requestId,
uint256[] calldata randomWords
) external {
require(msg.sender == anyrand, "Only callable by Anyrand");
require(randomness[requestId] == 1, "Unknown requestId");
randomness[requestId] = randomWords[0];
}
}