📌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
The user deploys and connects their Ethereum wallet to the contract.
The user calls
requestRandomness(minNumber, maxNumber)
, which:Generates a requestId.
Emits an event for an off-chain oracle to listen to.
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)
.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
User requests randomness: Calls
requestRandomness(minNumber, maxNumber)
, which returns arequestId
.Backend processes request: Listens for the
RandomnessRequested
event and generates a random number.Oracle fulfills request: Calls
fulfillRandomness(requestId, randomNumber)
to store the generated random number.User retrieves result: Calls
getRandomNumber(requestId)
to obtain the generated random number.