The solidity-vrf
package is a comprehensive suite of tools and smart contracts designed to enable secure and transparent generation of random numbers using a commit-reveal scheme in Solidity. This suite includes a core smart contract, an Express.js middleware, and some utilities for testing.
- Solidity VRF (Verifiable Random Function)
- Table of Contents
- Usage
- Installation
- Test Server
- Smart Contract
- Express.js Middleware
- License
To use the solidity-vrf
package, follow these steps:
-
Install the
solidity-vrf
package in your project. For more information, seeInstallation
. -
Use the
CommitRevealVRF
smart contract for random number generation by creating a child smart contract. Detailed usage instructions are available in theSmart Contract Usage
section. -
Integrate the
Express.js Middleware
into your application for secure random seed commitments and reveals. Configuration details can be found in theExpress.js Middleware Usage
section.
To install the solidity-vrf
package, you can use the following command:
npm install --save-dev solidity-vrf
To start a test server with the Express.js Middleware
and explore its capabilities in a controlled environment, use the following command:
npx vrf-api
The CommitRevealVRF
smart contract provides a foundation for implementing a commit-reveal based Verifiable Random Function (VRF) in Solidity. It allows developers to create a function that users can call to invoke the commit
function, and operators can trigger the reveal
function at a later time, subsequently enabling the validation of the revealed seed's authenticity.
The contract is designed to be extendable, allowing developers to build specific applications on top of it. This README provides an overview of the contract, its key features, and how to use it.
To use the CommitRevealVRF
smart contract, follow these steps:
-
Import the
CommitRevealVRF
contract into your Solidity contract:// Import the `CommitRevealVRF` contract import { CommitRevealVRF } from "solidity-vrf/contracts/CommitRevealVRF.sol";
-
Create a child contract that extends the
CommitRevealVRF
contract:contract Example CommitRevealVRF {}
-
Implement a function to initiate commitments and the commit-reveal process. You can wrap or override the
commit
function as needed:// Function for a user to make a commitment and initiate the commit-reveal process function makeCommitment(bytes32 userSeed, bytes32 operatorSeedHash, uint256 expiration, bytes memory signature) external { // Call the `commit` function to initiate the commit-reveal process bytes32 commitId = commit(userSeed, operatorSeedHash, expiration, signature); // Perform any additional actions after making the commitment }
-
Customize the handling of revealed random seeds by overriding the
revealCallback
function in your child contract:// Override the `revealCallback` function for custom logic function revealCallback(bytes32 commitId, bytes32 randomSeed) internal override { // Implement your custom logic here to handle the random seed }
Here's the complete example of how to use the CommitRevealVRF
smart contract.
pragma solidity ^0.8.18;
// Import the `CommitRevealVRF` contract
import { CommitRevealVRF } from "solidity-vrf/contracts/CommitRevealVRF.sol";
contract Example is CommitRevealVRF {
// Constructor to deploy the contract
constructor(address operator, uint8 confirmations) CommitRevealVRF(operator, confirmations) {}
// Function for a user to make a commitment and initiate the commit-reveal process
function makeCommitment(bytes32 userSeed, bytes32 operatorSeedHash, uint256 expiration, bytes memory signature) external {
// Call the `commit` function to initiate the commit-reveal process
bytes32 commitId = commit(userSeed, operatorSeedHash, expiration, signature);
// Perform any additional actions after making the commitment
}
// Override the `revealCallback` function for custom logic
function revealCallback(bytes32 commitId, bytes32 randomSeed) internal override {
// Implement your custom logic here to handle the random seed
}
}
This code demonstrates how to use the CommitRevealVRF
smart contract in your Solidity contract. After installing the solidity-vrf
package, you can import the CommitRevealVRF
contract and create a child contract that extends it. This child contract allows users to make commitments using the makeCommitment
function, which internally invokes the commit
function for secure commitment processing. Additionally, it provides an opportunity to customize the handling of revealed random seeds in the revealCallback
function.
Make sure to adapt the code according to your specific use case and requirements.
function commit(bytes32 userSeed, bytes32 operatorSeedHash, uint256 expiration, bytes memory signature) internal returns (bytes32)
Commits the necessary data to initiate the commit-reveal process for obtaining a random seed.
Name | Type | Description |
---|---|---|
userSeed |
bytes32 |
User's seed being committed. |
operatorSeedHash |
bytes32 |
Hash of the operator's seed. |
expiration |
uint256 |
The expiration timestamp for the operator's signed seed hash. |
signature |
bytes memory |
Operator's signature on the data. |
Name | Type | Description |
---|---|---|
commitId |
bytes32 |
The commit identifier in hash form. |
function reveal(bytes32 commitId, bytes32 operatorSeed) external
External function for operators to reveal a random seed based on a commitment.
Name | Type | Description |
---|---|---|
commitId |
bytes32 |
The unique identifier of the commitment. |
operatorSeed |
bytes32 |
The operator's seed used for revealing. |
function multiReveal(Reveal[] calldata reveals) external
External function for operators to reveal random seeds based on multiple commitments.
Name | Type | Description |
---|---|---|
reveals |
Reveal[] calldata |
An array of Reveal structs containing the commitment id and the operator's seed for each commitment. |
function revealCallback(bytes32 commitId, bytes32 randomSeed) internal virtual
Callback function intended to be overridden in child contracts to handle the revealed random seed.
Name | Type | Description |
---|---|---|
commitId |
bytes32 |
The unique identifier of the commitment. |
randomSeed |
bytes32 |
The verifiable random seed. |
This Express.js Middleware
provides an API for committing to random seeds and retrieving revealed seeds.
To use the Express.js Middleware
, follow these steps:
-
Import the
router
middleware from thesolidity-vrf
package:// Import the `router` middleware const { router } = require("solidity-vrf");
-
Include the
router
middleware in your Express.js application:const express = require("express"); const app = express(); // Include the `router` middleware app.use("/", router({ redisUrl: "redis://<REDIS_HOST>:<REDIS_PORT>", jsonRpcUrl: "<JSON_RPC_URL>", privateKey: "<PRIVATE_KEY>", vrfAddress: "<CONTRACT_ADDRESS>", expiration: 900, confirmations: 3 }));
-
Start your Express.js server:
// Start your Express.js server app.listen(8080, () => { console.log("VRF API listening at http://127.0.0.1:8080/"); });
For additional details on endpoints and responses, refer to the Endpoints
section.
Here's the complete example of how to use the middleware in your Express.js application, including the required configurations.
const express = require("express");
const app = express();
// Import the `router` middleware
const { router } = require("solidity-vrf");
// Include the `router` middleware
app.use("/", router({
redisUrl: "redis://<REDIS_HOST>:<REDIS_PORT>",
jsonRpcUrl: "<JSON_RPC_URL>",
privateKey: "<PRIVATE_KEY>",
vrfAddress: "<CONTRACT_ADDRESS>",
expiration: 900,
confirmations: 3
}));
// Start your Express.js server
app.listen(8080, () => {
console.log("VRF API listening at http://127.0.0.1:8080/");
});
Customize the code as needed for your specific use case.
You can commit to a random seed by sending a POST request to the /commit
endpoint.
Name | Type | Description |
---|---|---|
address |
Hexadecimal string |
The Ethereum address of the user for whom the seed is being committed. |
hash |
Hexadecimal string |
The hash of the user's seed to be committed. |
Upon a successful commitment, the middleware will respond with a JSON object containing the following fields:
Name | Type | Description |
---|---|---|
commit_id |
Hexadecimal string |
The unique commit identifier (commit ID). |
seed_hash |
Hexadecimal string |
The hash of the operator seed. |
signature |
Hexadecimal string |
TThe operator's signature. |
expiration |
Number |
The expiration timestamp of the commitment. |
This project is licensed under the MIT License.