A comprehensive implementation of a Verifiable Random Function (VRF) system providing ultra-low-latency, cryptographically verified random numbers for blockchain applications.
This project consists of:
- Smart Contracts (Solidity): Core contracts for requesting and verifying random numbers
- Backend Service (Rust): High-performance service that generates random numbers with cryptographic proofs
The system is designed to provide millisecond-level latency for random number generation using Rise Chain's Shreds API, while maintaining strong cryptographic verification through ECDSA signatures.
- Smart Contracts: Solidity, Foundry (testing & deployment)
- Backend: Rust, ethers-rs, tokio
- Infrastructure: Fly.io
sequenceDiagram
participant UserContract
participant VRFCoordinator (Solidity)
participant RustBackend (Fly.io)
participant EthereumL2
UserContract->>VRFCoordinator: requestRandomNumbers(numNumbers, clientSeed)
VRFCoordinator-->>RustBackend: RequestRaised(id, sender,…)
Note right of RustBackend: 1) Generate random numbers<br>2) Create ECDSA signature over<br>(requestId, clientSeed, randomNumbers)
RustBackend->>VRFCoordinator: fulfillRequest(id, randomNumbers, ecdsaProof)
Note right of VRFCoordinator: Verify ECDSA signature<br>ensuring the backend signed<br>the exact data submitted
VRFCoordinator->>UserContract: callback(id, randomNumbers)
graph TD
A[User Contract] -->|Request| B[VRF Coordinator]
B -->|Event| C[Rust Backend]
C -->|Shreds API| G[Rise Chain]
C -->|Fulfill| B
B -->|Callback| A
The backend system consists of multiple components organized in a modular architecture.
- Ultra-Low Latency: Uses Rise Chain's Shreds API to process transactions in milliseconds
- Cryptographic Verification: Generates ECDSA signatures for on-chain verification
- Resilience: Includes missed request recovery and dynamic gas price adjustment
- Monitoring: Real-time metrics for system health and performance
fast-vrf/
└── backend/ # Main VRF backend service
├── src/ # Source code
│ ├── bin/ # Executable entry points
│ ├── vrf/ # Core VRF functionality
│ └── lib.rs # Library exports
├── Cargo.toml # Dependencies
└── .env.example # Environment variable template
-
Set up environment variables:
cp .env.example .env
Edit the
.envfile with the following required variables:# Required configuration PRIVATE_KEY=0xyour_private_key_here VRF_ADDRESS=0xyour_vrf_coordinator_proxy_address DICE_GAME_ADDRESS=0xyour_dice_game_address RPC_URL=https://testnet.riselabs.xyz INDEXING_RPC=wss://testnet.riselabs.xyz/ws # For deployment (derived from PRIVATE_KEY via `cast wallet address`) INITIAL_OWNER_ADDRESS=0xyour_deployer_address INITIAL_BACKEND_ADDRESS=0xyour_backend_signer_address # Optional configuration PORT=8080 # For health check server MONITORING_URL=https://your-monitoring-service.com/metrics RUST_LOG=info # Log level (debug, info, warn, error) -
Build the project:
make build
-
Run the backend:
Shred backend (ultra-low latency, recommended):
make run-shred-staging
Standard backend:
make run-backend
-
Install the Fly.io CLI:
curl -L https://fly.io/install.sh | sh -
Login to Fly.io:
fly auth login
-
Set up environment secrets:
cd fast-vrf/backend ./setup-fly-secrets.shOr manually:
fly secrets set PRIVATE_KEY=your_private_key fly secrets set RPC_URL=your_rpc_url fly secrets set INDEXING_RPC=your_indexing_rpc_ws_url
-
Deploy the shred backend:
fly deploy -c fly.shred.toml
-
Monitor deployment:
fly logs fly status
The smart contract system consists of the VRF Coordinator contract and example consumer contracts.
-
VRFCoordinatorV2.sol:
- UUPS upgradeable VRF coordinator (deployed behind an ERC1967Proxy)
- Verifies ECDSA signatures to ensure backend accountability
- Maintains registry of requests and fulfillment status
- Configurable
maxGasPerFulfillmentand owner-based access control
-
VRFCoordinator.sol:
- Original non-upgradeable coordinator (V1)
-
DiceGame.sol:
- Example consumer contract showing integration with the VRF system
- Implements the
IVRFConsumercallback interface
smartcontracts/
└── contracts/
├── foundry.toml # Foundry configuration
├── src/ # Contract source code
│ ├── VRFCoordinator.sol
│ ├── VRFCoordinatorV2.sol
│ └── DiceGame.sol
├── script/ # Deployment and interaction scripts
└── test/ # Test files
-
Setup environment:
cd smartcontracts/contracts -
Deploy the VRF Coordinator (UUPS Proxy):
Ensure
INITIAL_OWNER_ADDRESSandINITIAL_BACKEND_ADDRESSare set in.env, then:make deploy-vrf-proxy
Or directly:
forge script script/DeployVRFCoordinatorV2Proxy.s.sol:DeployVRFCoordinatorV2Proxy \ --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast --via-ir
-
Testing the deployment:
# Request a random number forge script script/RequestRandomNumber.s.sol:RequestRandomNumberScript \ --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast --via-ir # Check fulfillment status forge script script/CheckVRFFulfillment.s.sol:CheckVRFFulfillmentScript \ --rpc-url $RPC_URL -vv
-
End-to-end testing:
forge script script/EndToEndTest.s.sol:EndToEndTestScript \ --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast
-
Import the VRF interface:
import {IVRFConsumer} from "./VRFCoordinatorV2.sol";
-
Implement the required interface:
contract MyGame is IVRFConsumer { // Required callback function function rawFulfillRandomNumbers(uint256 requestId, uint256[] calldata randomNumbers) external { // Process random numbers here } }
-
Request random numbers:
function requestRandom(uint256 numNumbers, uint256 clientSeed) external { vrfCoordinator.requestRandomNumbers(numNumbers, clientSeed); }
- Basic VRF implementation with event listening and fulfillment
- Add cryptographic proof verification (ECDSA signatures)
- End-to-end testing and integration
- Implement missed request handling for system resilience
- Improve latency using Rise Chain's Shreds API for millisecond responses
- Implement monitoring service with real-time metrics reporting
- Enhanced nonce management to prevent transaction collisions
- Implement subscription model for gas payment
The project includes a comprehensive Makefile with commands for all operations:
# Build everything
make build
# Build only contracts
make build-contracts
# Build only backend
make build-backend
# Deploy contracts (UUPS proxy)
make deploy-vrf-proxy# Run the low-latency Shred API backend (recommended)
make run-shred-staging
# Run the traditional main backend service
make run-backend
# Run the missed request processor (with optional arguments)
make index-missed ARGS="--start-block 1000 --end-block 2000"
# Check if a specific request needs fulfillment
make check-request REQUEST_ID=123
# Process recent blocks in dry-run mode
make catch-up
# Process and fulfill missed requests
make catch-up-fulfill
# Run stress test to validate performance
make stress-test# Run contract tests
make test
# Request a random number for testing
make request
# Manually fulfill a request
make fulfill REQUEST_ID=123
# Run end-to-end test script
make e2e-script# Start a local blockchain
make start-anvil
# Deploy to local blockchain and set up environment
make local-setupThe system includes a robust mechanism for handling missed requests through the index_missed_requests.rs utility:
-
Block Range Scanning
- Scans specified block ranges or defaults to the last 1000 blocks
- Processes blocks in chunks to avoid RPC limitations
-
Request Validation
- Checks if requests are still valid using the contract's
isRequestValidmethod - Verifies against
RequestFulfilledevents to prevent duplicate processing
- Checks if requests are still valid using the contract's
-
Selective Processing
- Can target specific request IDs for validation and fulfillment
- Supports dry-run mode to check without submitting transactions
# Check recent blocks for missed requests (dry run)
make catch-up
# Process and fulfill any missed requests
make catch-up-fulfill
# Check a specific request ID
make check-request REQUEST_ID=123
# Process a specific block range with custom arguments
make index-missed ARGS="--start-block 1000000 --end-block 1001000 --dry-run"The VRF system integrates with Rise Chain's Shreds API for ultra-low-latency randomness:
Shreds are pre-confirmation transaction data that allow applications to react to blockchain events in milliseconds rather than waiting for block confirmations.
- WebSocket Connection: Maintains a persistent WebSocket connection to the Shreds API
- Pre-confirmation Processing: Processes VRF requests as soon as they appear in the mempool
- Latency Improvement: Reduces response time from seconds to milliseconds (~99% improvement)
- Transaction Monitoring: Tracks transaction status from submission to confirmation
- Resilient Connection: Automatically reconnects if the WebSocket connection is lost
Run the Shreds-enabled backend with:
make run-shred-stagingThe backend will:
- Connect to the Shreds API WebSocket
- Listen for VRF-related transactions in the mempool
- Process requests as soon as they're detected, before block confirmation
- Submit fulfillment transactions with optimized gas settings
The backend includes built-in monitoring and metrics reporting:
-
Real-time Metrics: Tracks and reports VRF request processing metrics
-
Latency Measurement: Records detailed latency at each step of the request lifecycle:
- Request detected → Fulfillment sent
- Fulfillment sent → Request confirmed
- Total request processing time
-
Performance Statistics: Generates aggregated performance metrics every 15 seconds
-
Error Tracking: Monitors and reports errors with detailed context
-
Health Checks: Provides system status including nonce management health
The system includes a three-tier nonce management system:
- UltraFast: Lock-free atomic nonce tracking for maximum throughput
- Fast: Atomic operations with background chain synchronization
- Legacy: Mutex-based with pending transaction tracking
These tiers ensure reliable transaction submission even under high load, preventing nonce collisions and automatically recovering from nonce errors.
- Implement full cryptographic verifiability with additional on-chain verification
- Implement EIP-6702 or Chainlink-style ECC for VRF proof verification
- Include cryptographic proofs that demonstrate the randomness was fairly generated
- Implement subscription-based model for gas payment
- Add credit map with
topUp()functionality for users - Implement gas refund mechanism for leftover gas
- Add load balancing and redundancy for higher availability
- Add support for batching multiple requests in a single transaction to optimize gas usage
- Rust toolchain (1.70+)
- Foundry for Solidity development
-
Set up environment variables in
.envfilecp .env.example .env # Edit .env with your configuration -
Build the project
make build -
Deploy contracts (to testnet or local chain)
make deploy-vrf-proxy -
Run the backend
make run-shred-staging
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.