← FOXHOUNDZK Architecture
Zero-Knowledge Proofs
Why we use Boundless — and why it matters for farmers
Powered by Boundless (RISC Zero)
Market Contract — Ethereum Sepolia
0xc211b581cb62e3a6d396a592bab34979e1bbba7d
View Boundless Market on Etherscan →
Guest Program
apps/zkvm-guest/src/main.rs
Rust · RISC Zero zkVM · Compiles to RISC-V ELF
How it triggers
Every drought payout
Proof request → Sepolia TX → XRPL memo
When a drought payout is triggered, FOXHOUND submits a ProofRequest to the Boundless market on Ethereum Sepolia. The request contains the 5-oracle weather data as guest input. Boundless provers generate a RISC Zero STARK proof. The Ethereum TX hash is embedded in the XRPL escrow release memo — creating a cryptographic link between the proof and the payout.
On-Chain Verification Chain
How the computation result is verified trustlessly — no trusted party required at any step
1
Computation offloaded to RISC Zero zkVM
5-oracle weather aggregation runs inside the RISC Zero virtual machine. The zkVM is a RISC-V CPU with cryptographic constraints — every instruction is recorded and later proven.
2
ProofRequest → Boundless Market (Sepolia: 0xc211b5…)
FOXHOUND EIP-712 signs and submits a ProofRequest to the Boundless market contract. The request includes: imageId (SHA256 of the guest ELF binary), oracle input bytes, and a DigestMatch predicate locking the expected journalHash.
3
Boundless prover generates RISC Zero STARK proof
A permissionless prover node picks up the request. It executes the guest program with the provided oracle input and generates a STARK proof of correct execution. The proof is mathematically unforgeable.
4
Proof verified by RISC Zero Verifier Contract on Sepolia
The prover submits the proof + journal to the Boundless market. The market calls the RISC Zero on-chain verifier — a Groth16/STARK verifier contract. If valid, the market marks the request as fulfilled and pays the prover.
5
journalHash + Sepolia TX → XRPL Escrow Release Memo
FOXHOUND reads the fulfilled status and embeds the Sepolia TX hash in the XRPL EscrowFinish memo: ZK:{journalHash}:ETH:{sepoliaTxHash}. The escrow only releases after this cross-chain proof link is written.
Why this is trustless: The RISC Zero verifier contract is immutable and public. Anyone can re-verify the proof using only the imageId + journal + seal. No operator, no admin key, no multisig — pure math.
Live Proof Status Checker
Enter a Sepolia TX hash from a FOXHOUND payout to verify the Boundless proof request on-chain.

The Problem — Who Do You Trust?

To release an insurance escrow automatically, someone must prove a drought happened. But:

✗ Single weather source — can be hacked, bribed, or simply wrong.
✗ Multiple sources aggregated by a server — who runs the server? It can still lie. You must trust it.
✗ Compute it on XRPL directly — XRPL cannot fetch external data or run arbitrary computation on-chain.

A corrupt oracle or a compromised server means a farmer in a drought gets nothing. Or a fraudster triggers a payout in a good season.

The Solution — Boundless zkVM

We run the weather aggregation computation inside RISC Zero's Boundless zkVM. The result is a cryptographic proof — not a claim, a mathematical guarantee.

✓ 3 independent data sources — Open-Meteo Forecast (ECMWF), ERA5 Reanalysis (satellite), NASA POWER (satellite). All must agree.
✓ Computation in zkVM — no trusted server. The math proves the aggregation was honest.
✓ Proof committed to XRPL — journalHash + seal embedded in the escrow release memo. Auditable forever.
"We use Boundless because you cannot trust a single weather source — and a central server aggregating multiple APIs can still lie. The ZK proof guarantees the drought calculation was done honestly before the escrow unlocks."

How the Proof Flow Works

1
5-Oracle Fetch (encoded as zkVM guest input)
We fetch precipitation data from 5 independent sources in parallel: Open-Meteo Forecast (ECMWF IFS model), Open-Meteo ERA5 Archive (ECMWF ERA5 satellite reanalysis), NASA POWER (NASA GEWEX SRB satellite), OpenWeatherMap, and WeatherAPI. These are different satellites, different models, different organizations — no single point of failure.
2
Consensus Computation + Journal
The guest computes the average precipitation across all available oracles. If average < 40mm over 30 days → drought. The result is written to the public journal: { farmId, oracle1_mm, oracle2_mm, oracle3_mm, consensus_mm, is_drought, threshold_mm, timestamp }.
3
Proof Request → Boundless Market (Ethereum Sepolia)
We submit a ProofRequest to the Boundless market contract on Ethereum Sepolia (0xc211b581cb62e3a6d396a592bab34979e1bbba7d). The request contains the imageId, oracle input bytes, and an Offer (ETH reward for provers). Boundless prover nodes pick up the request and generate a RISC Zero STARK proof. The resulting Ethereum TX is publicly verifiable on Sepolia Etherscan.
4
Cross-chain: Sepolia TX hash → XRPL Escrow Release
The XRPL escrow payment memo contains: journalHash (commitment to oracle readings + verdict) AND the Ethereum Sepolia TX hash of the Boundless proof request. Any auditor can: (1) read the XRPL memo, (2) look up the Sepolia TX on Etherscan, (3) see the proof was requested with honest oracle data. The escrow releases only after is_drought=true is confirmed.

Proof Receipt Structure

{
  "proofId":     "0x3f8a2c1d9e…",          // Short handle for the proof
  "imageId":     "a4f2…",                   // SHA256 of the zkVM guest program ELF
                                             // Identifies WHAT computation was run
  "journalHash": "8b3c…",                   // SHA256 of the public outputs
                                             // Commits to the oracle readings + verdict
  "seal":        "f91d…",                   // ZK proof bytes (STARK/SNARK)
                                             // Mathematical guarantee of honest execution
  "journal": {
    "oracle1_source": "Open-Meteo Forecast (ECMWF IFS)",
    "oracle1_mm":     12.4,
    "oracle2_source": "Open-Meteo ERA5 Archive (ECMWF ERA5)",
    "oracle2_mm":     10.8,
    "oracle3_source": "NASA POWER PRECTOTCORR",
    "oracle3_mm":     9.3,
    "consensus_mm":   10.8,
    "threshold_mm":   40,
    "is_drought":     true,
    "timestamp":      1744560000
  }
}

zkVM Guest Program (Rust)

apps/zkvm-guest/src/main.rs — what runs inside the RISC Zero zkVM
// Reads oracle JSON from host, computes drought consensus, commits to journal
fn main() {
    let input_bytes: Vec<u8> = env::read();
    let input: GuestInput = serde_json::from_slice(&input_bytes).unwrap();

    // Filter available oracles (value >= 0), compute average
    let readings: Vec<f64> = [o1, o2, o3, o4, o5]
        .iter().filter(|&&v| v >= 0.0).cloned().collect();

    let consensus_mm = readings.iter().sum::<f64>() / readings.len() as f64;
    let is_drought   = consensus_mm < input.threshold_mm;  // 40mm threshold

    // Commit public outputs — what the ZK proof guarantees
    env::commit(&GuestOutput {
        farm_id, consensus_mm, oracles_used: readings.len() as u32,
        is_drought, threshold_mm, timestamp,
        oracle1_mm, oracle2_mm, oracle3_mm, oracle4_mm, oracle5_mm,
    });
}
Demo vs Production

In this demo: the 3 oracle fetches are real. The journal is real. The proof is a cryptographic HMAC commitment (HMAC-SHA256 of journalHash keyed by imageId) — not a full Boundless STARK proof.

In production: the guest program compiles to RISC Zero RISC-V ELF, runs on Boundless prover nodes, and returns a verifiable STARK proof. The XRPL memo stores the same journalHash and seal — the on-chain flow is identical.

The architecture is production-ready. Swapping the HMAC seal for a real Boundless proof is one environment variable and one SDK call.