1.0.0-beta.0 • Published 6 months ago

solidity-vrf v1.0.0-beta.0

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

Solidity VRF (Verifiable Random Function)

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.

Table of Contents

Usage

To use the solidity-vrf package, follow these steps:

  1. Install the solidity-vrf package in your project. For more information, see Installation.

  2. Use the CommitRevealVRF smart contract for random number generation by creating a child smart contract. Detailed usage instructions are available in the Smart Contract Usage section.

  3. Integrate the Express.js Middleware into your application for secure random seed commitments and reveals. Configuration details can be found in the Express.js Middleware Usage section.

Installation

To install the solidity-vrf package, you can use the following command:

npm install --save-dev solidity-vrf

Test Server

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

Smart Contract

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.

Usage

To use the CommitRevealVRF smart contract, follow these steps:

  1. Import the CommitRevealVRF contract into your Solidity contract:

    // Import the `CommitRevealVRF` contract
    import { CommitRevealVRF } from "solidity-vrf/contracts/CommitRevealVRF.sol";
  2. Create a child contract that extends the CommitRevealVRF contract:

    contract Example CommitRevealVRF {}
  3. 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
    }
  4. 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
    }

Example

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.

Functions

Function commit

function commit(bytes32 userSeed, bytes32 operatorSeedHash, uint256 expiration, bytes memory signature) internal returns (bytes32)

Description

Commits the necessary data to initiate the commit-reveal process for obtaining a random seed.

Parameters

NameTypeDescription
userSeedbytes32User's seed being committed.
operatorSeedHashbytes32Hash of the operator's seed.
expirationuint256The expiration timestamp for the operator's signed seed hash.
signaturebytes memoryOperator's signature on the data.

Returns

NameTypeDescription
commitIdbytes32The commit identifier in hash form.

Function reveal

function reveal(bytes32 commitId, bytes32 operatorSeed) external

Description

External function for operators to reveal a random seed based on a commitment.

Parameters

NameTypeDescription
commitIdbytes32The unique identifier of the commitment.
operatorSeedbytes32The operator's seed used for revealing.

Function multiReveal

function multiReveal(Reveal[] calldata reveals) external

Description

External function for operators to reveal random seeds based on multiple commitments.

Parameters

NameTypeDescription
revealsReveal[] calldataAn array of Reveal structs containing the commitment id and the operator's seed for each commitment.

Function revealCallback

function revealCallback(bytes32 commitId, bytes32 randomSeed) internal virtual

Description

Callback function intended to be overridden in child contracts to handle the revealed random seed.

Parameters

NameTypeDescription
commitIdbytes32The unique identifier of the commitment.
randomSeedbytes32The verifiable random seed.

Express.js Middleware

This Express.js Middleware provides an API for committing to random seeds and retrieving revealed seeds.

Usage

To use the Express.js Middleware, follow these steps:

  1. Import the router middleware from the solidity-vrf package:

    // Import the `router` middleware
    const { router } = require("solidity-vrf");
  2. 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
    }));
  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.

Example

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.

Endpoints

POST /commit

You can commit to a random seed by sending a POST request to the /commit endpoint.

Request Parameters

NameTypeDescription
addressHexadecimal stringThe Ethereum address of the user for whom the seed is being committed.
hashHexadecimal stringThe hash of the user's seed to be committed.

Response

Upon a successful commitment, the middleware will respond with a JSON object containing the following fields:

NameTypeDescription
commit_idHexadecimal stringThe unique commit identifier (commit ID).
seed_hashHexadecimal stringThe hash of the operator seed.
signatureHexadecimal stringTThe operator's signature.
expirationNumberThe expiration timestamp of the commitment.

License

This project is licensed under the MIT License.