Skip to content

essential-contributions/void-toolkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

59 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VOID Toolkit

A framework for building Verifiable, Opinionated, Interoperable, and Decentralized (VOID) applications that run sovereignly across multiple blockchain ecosystems.

Overview

The VOID Toolkit provides developers with the tools needed to build sovereign, multi-chain applications that offer the benefits of app-specific chains while maintaining access to users and liquidity across multiple blockchain ecosystems.

VOID solves the fundamental trade-off that apps face today: choosing between deploying on general-purpose chains (losing sovereignty but gaining access to users) or launching app-specific chains (gaining sovereignty but losing distribution).

Key Features

Multi-Chain Support

  • Accept transactions from multiple blockchains simultaneously (Ethereum, Solana, Base, etc.).
  • Users interact with your app using their existing wallets on their preferred chains.
  • No onboarding friction.

Customizable Execution

  • Define your own fee models and transaction ordering logic.
  • Choose your execution environment or virtual machine.
  • Implement specialized logic for gaming, DeFi, social apps, and more.

MEV Internalization

  • Control and optimize your app’s transaction ordering.
  • Capture, internalize or minimize all MEV generated by your application.

Sovereign Blockspace

  • Full control over your application's infrastructure.
  • No dependence on general-purpose chain roadmaps or politics.
  • Credible neutrality without ecosystem lock-in.

High Performance

  • Support for low latency, high throughput use cases.
  • Efficient state management and proof generation.
  • Optimized for real-time applications.

Architecture

VOID applications consist of three main components:

  1. VOID Oracle - Aggregates events from interface contracts across multiple blockchains
  2. VOID Node - Executes your app's state transition function with custom ordering logic
  3. VOID Prove - Generates cryptographic proofs of state correctness
graph BT
    subgraph BC ["Blockchains"]
        D[Ethereum]
        E[Optimism]
        F[Base]
        G[...]
    end

    subgraph "VOID Application"
        A[VOID Oracle<br/>
          • Multi-chain event aggregation<br/>
          • Proof of events]
        B[VOID Node<br/>
          • Custom state transitions<br/>
          • Transaction ordering<br/>
          • Execution environment]
        C[VOID Prove<br/>
          • ZK proofs<br/>
          • TEE attestations<br/>
          • Optimistic proofs<br/>
          • Configurable models]
    end

    BC --> A

    A --> B
    B --> C

    classDef default text-align:center;
Loading

Quick Start

Installation

Add the VOID Toolkit to your Cargo.toml:

[dependencies]
void-toolkit = { version = "0.1", features = ["run", "oracle", "load-config"] }

Basic Usage

use std::convert::Infallible;

use futures::TryStreamExt;
use void_toolkit::{
    app::UpdateLatestBlock,
    load_config::load_config,
    oracle::{oracle, Db},
    oracle_types::config::Config,
    run::run_node,
    types::{Block, Lock},
};

pub struct State(pub u64);

impl UpdateLatestBlock for State {
    type Error = Infallible;

    fn update_latest_block(&mut self, _height: u64, _hash: [u8; 32]) -> Result<(), Self::Error> {
        todo!()
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration
    let config: Config = load_config("config.yaml")?;

    // Start oracle to watch for cross-chain events
    let blocks = oracle(config, Db::memory(), 0).map_err(|e| anyhow::anyhow!(e));

    // Define your app's state and transition logic
    let state_transition = |block: &Block, _state: &mut State| -> Result<(), Infallible> {
        // Process block and update state
        for _event in &block.events {
            // Handle cross-chain events
            println!(
                "Processing {} events in block {}",
                block.events.len(),
                block.height
            );
        }
        Ok(())
    };
    let state = Lock::new(State(0));

    // Run your VOID node
    run_node(blocks, state, state_transition).await?;

    Ok(())
}

Oracle Modes

VOID provides different oracle modes for various deployment scenarios:

use void_toolkit::{
    load_config::load_config,
    oracle::{observer_oracle, oracle, publisher_oracle, relay_oracle, Db},
    oracle_types::config::{Config, OracleBlocksConfig},
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config: Config = load_config("config.yaml")?;

    // Basic oracle - watches events and produces blocks locally
    let _blocks = oracle(config.clone(), Db::memory(), 0);

    // Publisher oracle - produces blocks and serves them over HTTP/SSE
    let _blocks = publisher_oracle(
        config.clone(),
        Db::memory(),
        0,
        "127.0.0.1:8080".parse().unwrap(),
        100,
        None,
    );

    // Observer oracle - connects to existing producer, consumes blocks
    let _blocks = observer_oracle(
        OracleBlocksConfig {
            endpoint: "http://127.0.0.1:8080".to_string(),
            height: 0,
            public_key: None,
        },
        Db::memory(),
    );

    // Relay oracle - connects to producer and also serves blocks to others
    let _blocks = relay_oracle(
        OracleBlocksConfig {
            endpoint: "http://127.0.0.1:8080".to_string(),
            height: 0,
            public_key: None,
        },
        Db::memory(),
        "127.0.0.1:8081".parse().unwrap(),
        100,
    );

    Ok(())
}

Configuration

Create a config.yaml file to specify which chains and events to monitor:

# Example configuration for VOID Toolkit
# Uses public testnet endpoints - replace with your own for production

query:
  stream_config:
    - !ChainContractLogs
      rpc_url: !Ws "wss://ethereum-sepolia.publicnode.com"
      contract_addresses: ["0xA0b86a33E6417d7C1b1E4C2e75b9b0e2D6b2d8a0"] # Example contract
      event_signatures: ["Transfer(address,address,uint256)"]
    - !ChainContractLogs
      rpc_url: !Ws "wss://base-sepolia.publicnode.com"
      contract_addresses: ["0xB1c86a33E6417d7C1b1E4C2e75b9b0e2D6b2d8a1"] # Example contract
      event_signatures: ["TokenTransfer(address,address,uint256)"]

block:
  max_block_size: 1000000
  block_duration_ms: 5000

Crates Overview

The VOID Toolkit consists of several specialized crates:

void-toolkit

Core toolkit with runtime utilities, oracle integration, and configuration loading. Re-exports the other crates when relevant features are enabled.

void-merkle

Sparse Merkle tree implementations for efficient data verification with cryptographic proofs.

void-proof

Zero-knowledge proof generation using RISC Zero for state transition verification.

void-sign

ECDSA signature utilities compatible with Ethereum's cryptographic standards.

void-network-channel

Network communication primitives for distributed replication and synchronization.

void-oracle-decoder

Macro library for generating Ethereum event decoders for cross-chain event processing.

Advanced Features

Zero-Knowledge Proof Generation

VOID provides cryptographic proof generation using RISC Zero:

use void_toolkit::proof::host::prove;
use void_toolkit::types::Block;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Example block data (in practice this would come from your oracle)
    let block = Block {
        height: 0,
        parent_hash: [0; 32],
        events: vec![],
    };

    // Example witness data (application-specific state transition data)
    let witness_data = vec![]; // Placeholder - would contain actual witness data

    // Example circuit ELF (compiled RISC Zero program)
    let circuit_elf = &[]; // Placeholder - would contain actual circuit binary

    // Generate a ZK proof for a block with witness data
    let proof_bytes = prove(&block, witness_data, circuit_elf)?;

    println!("Generated proof of {} bytes", proof_bytes.len());

    // The proof can be verified independently and transmitted to other parties
    println!("Proof generation complete");

    Ok(())
}

Multi-Chain Event Processing

Use the event decoder to handle events from different chains:

use alloy::sol;
use futures::TryStreamExt;
use void_toolkit::{
    load_config::load_config, oracle::oracle, oracle::Db, oracle_decoder::decode_events,
    oracle_types::config::Config,
};

// Define the events we want to decode
sol! {
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Deposit(address indexed user, uint256 amount);
}

// Generate the decoder for these events
decode_events! {
    Transfer,
    Deposit,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load configuration
    let config: Config = load_config("config.yaml")?;

    // Start oracle to watch for cross-chain events
    let blocks = oracle(config, Db::memory(), 0);

    // Process decoded events in your state transition function
    blocks
        .try_for_each(|block| async move {
            println!("Processing block with {} events", block.events.len());

            for event in &block.events {
                // Try to decode each event
                if let Ok(decoded_event) = decode_input(event) {
                    match decoded_event {
                        AppEvent::Transfer(transfer) => {
                            println!(
                                "Transfer: {} -> {} (amount: {})",
                                transfer.from, transfer.to, transfer.amount
                            );
                        }
                        AppEvent::Deposit(deposit) => {
                            println!("Deposit: {} deposited {}", deposit.user, deposit.amount);
                        }
                    }
                } else {
                    println!("Unknown event: {} bytes", event.len());
                }
            }
            Ok(())
        })
        .await?;

    Ok(())
}

Use Cases

VOID is ideal for applications that need high performance, custom logic execution, and seamless cross-chain integration, such as:

  • DeFi Protocols: DEXs, lending platforms, derivatives with cross-chain liquidity
  • Gaming Applications: Real-time games requiring low latency and custom logic
  • Social Applications: Decentralized social networks with specialized features
  • Enterprise: Private or consortium applications with specific compliance needs

About

Toolkit for building VOID apps

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors