📌Random Number Contract

Introduction

The Random Number Oracle Contract is a decentralized smart contract designed to generate and provide random numbers securely. By utilizing an off-chain randomness provider, this contract allows users to request and retrieve random numbers in a transparent and tamper-proof manner.

How It Works

  1. The user deploys and connects their Ethereum wallet to the contract.

  2. The user calls requestRandomness(minNumber, maxNumber), which:

    • Generates a requestId.

    • Emits an event for an off-chain oracle to listen to.

  3. The off-chain oracle listens for the event, generates a random number within the given range, and fulfils the request by calling fulfillRandomness(requestId, randomNumber).

  4. The user can then retrieve their random number by calling getRandomNumber(requestId).

Smart Contract Implementation

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";

contract Randomness is Ownable {
    uint256 private requestIdCounter;
    
    /**
     * @dev Emitted when a request for randomness is raised.
     */
    event RandomnessRequested(
        uint256 indexed requestId,
        uint256 indexed minNumber,
        uint256 indexed maxNumber,
        address requestedAddress,
        uint256 timestamp
    );

    mapping(uint256 => bool) private requestUsed;
    mapping(uint256 => address) private requestOwner;
    mapping(uint256 => uint256) private requestToRandomNumber;
    mapping(uint256 => bool) private randomnessFulfilled;

    modifier validRequest(uint256 requestId) {
        require(requestIdCounter != 0, "No requests have been made yet");
        require(requestId <= requestIdCounter, "Invalid requestId");
        require(!requestUsed[requestId], "Request ID already used");
        _;
    }

    constructor() {
        requestIdCounter = 0;
    }

    /**
     * @dev Requests a random number within a specified range.
     * @param minNumber Minimum range value.
     * @param maxNumber Maximum range value.
     * @return requestId Unique ID associated with the randomness request.
     */
    function requestRandomness(uint256 minNumber, uint256 maxNumber) public returns (uint256 requestId) {
        requestIdCounter++;
        requestId = requestIdCounter;
        requestOwner[requestId] = msg.sender;
        emit RandomnessRequested(requestId, minNumber, maxNumber, msg.sender, block.timestamp);
    }

    /**
     * @dev Retrieves the random number for a given requestId.
     * @param requestId The unique ID of the randomness request.
     * @return The generated random number.
     */
    function getRandomNumber(uint256 requestId) public view validRequest(requestId) returns (uint256) {
        require(requestOwner[requestId] == msg.sender, "Only the request owner can retrieve the random number");
        require(randomnessFulfilled[requestId], "Random number not yet fulfilled");
        return requestToRandomNumber[requestId];
    }

    /**
     * @dev Fulfills the randomness request by providing a generated random number.
     * Only the contract owner can call this function.
     * @param requestId The unique ID of the randomness request.
     * @param randomNumber The generated random number.
     * @return success Boolean indicating the fulfillment status.
     */
    function fulfillRandomness(uint256 requestId, uint256 randomNumber) public onlyOwner validRequest(requestId) returns (bool success) {
        requestToRandomNumber[requestId] = randomNumber;
        randomnessFulfilled[requestId] = true;
        return true;
    }
}

Contract Functions

1. Constructor

constructor()
  • Initializes the contract and sets requestIdCounter to 0.

2. Request Random Number

function requestRandomness(uint256 minNumber, uint256 maxNumber) public returns (uint256 requestId)
  • Allows users to request a random number within a specified range.

  • Returns a unique requestId associated with the request.

3. Retrieve Random Number

function getRandomNumber(uint256 requestId) public view returns (uint256)
  • Retrieves the random number for a given requestId.

  • Only the request owner can access their random number.

4. Fulfill Randomness Request

function fulfillRandomness(uint256 requestId, uint256 randomNumber) public onlyOwner returns (bool success)
  • Allows the contract owner (off-chain oracle) to provide the generated random number.

  • Marks the request as fulfilled.

Process Flow

  1. User requests randomness: Calls requestRandomness(minNumber, maxNumber), which returns a requestId.

  2. Backend processes request: Listens for the RandomnessRequested event and generates a random number.

  3. Oracle fulfills request: Calls fulfillRandomness(requestId, randomNumber) to store the generated random number.

  4. User retrieves result: Calls getRandomNumber(requestId) to obtain the generated random number.

Last updated