PixelOracle
ZK Technology Architecture
Architecture Overview

TECHNICAL DEEP DIVE

PixelOracle combines five distinct technology layers into a unified ZK oracle infrastructure on Solana. Every query passes through privacy-preserving circuits, cryptographic proof generation, compressed on-chain storage, programmatic verification, and cross-chain bridge resolution.

01
Privacy Layer

ZK circuits with input masking, commitment hashing via SHA-256, and selective disclosure flags. Query intent is hidden; results remain publicly verifiable through Groth16 proofs on BN254.

02
Proof Engine

Groth16 proof generation with 192-byte constant-size proofs. Poseidon hashing for field-native operations. 300-500ms prove time. Single pairing check verification consuming approximately 200K compute units on Solana.

03
Compression Layer

Light Protocol ZK Compression with depth-26 Merkle trees supporting 67M compressed accounts per tree. Per-record storage cost reduced from 0.07 SOL to 0.00007 SOL. Photon indexer for inclusion proofs.

04
Oracle Program

Anchor v0.30+ on-chain program managing the full query lifecycle: submission, proof verification, compressed storage, fee distribution, token burns, and node operator reward payouts via six core instructions.

05
Bridge Adapters

Chain-specific adapters for Ethereum, BSC, Arbitrum, and Polygon. Merkle Patricia Trie storage proofs verified against source chain block headers. Normalized results wrapped in composed ZK proofs stored on Solana.

Ancient scroll depicting oracle technology
Deep Dive

ZK Compression and State Reduction

Light Protocol introduces ZK Compression to Solana by replacing individual account storage with concurrent Merkle trees. In traditional Solana architecture, each account occupies its own entry in the accounts database, incurring a minimum rent-exempt balance of roughly 0.07 SOL. For an oracle that stores millions of query results, this cost structure is prohibitive. ZK Compression sidesteps the problem by encoding each oracle result as a leaf in a depth-26 Poseidon Merkle tree. A single on-chain account holds the tree root, while the full leaf data is maintained off-chain by the Photon indexer. The result is a 1000x reduction in per-record storage cost without sacrificing verifiability.

Each compressed account leaf contains a Poseidon hash of the oracle result payload: the 64-bit result value, the 32-byte proof hash, the 32-byte commitment hash, the Unix timestamp, and the set of node operator signatures that attested to the result. To read a compressed account, a consumer requests a Merkle inclusion proof from the Photon indexer. This proof consists of 26 sibling hashes (one per tree level) and the leaf index. The consumer then walks the proof path from leaf to root, recomputing each intermediate hash with Poseidon, and asserts that the final computed root matches the on-chain state root stored in the tree account.

PixelOracle writes to the state tree through Cross-Program Invocations from the Anchor oracle program. When verify_and_store executes successfully, it invokes the Light Protocol system program to append a new leaf. The tree uses a changelog buffer to support concurrent writes from multiple transactions in the same slot, preventing contention issues that would otherwise serialize oracle updates. The changelog tracks recent root transitions so that inclusion proofs generated against a slightly stale root remain valid for a configurable window of 256 slots (approximately two minutes).

types/compressed_oracle_proof.rs
// ZK Compressed Oracle Proof Structure
// Light Protocol State Tree Integration
// ──────────────────────────────────────

struct CompressedOracleProof {
  // Merkle inclusion path (depth 26)
  siblings:       [[u8; 32]; 26],
  leaf_index:     u64,

  // Poseidon hash of compressed account data
  leaf_hash:      [u8; 32],

  // Public inputs to Groth16 verifier
  state_root:     [u8; 32],       // current Merkle root
  commitment:     [u8; 32],       // SHA-256(asset || chain || type || nonce)
  result_value:   u64,            // oracle output
  timestamp:      i64,            // Clock::get()

  // Groth16 proof (BN254 curve, 192 bytes)
  proof: {
    pi_a:         [u8; 64],       // G1 point
    pi_b:         [u8; 128],      // G2 point
    pi_c:         [u8; 64],       // G1 point
  },

  // Compressed account envelope
  compressed_account: {
    tree_pubkey:  Pubkey,          // state Merkle tree address
    owner:        Pubkey,          // program ID
    lamports:     u64,             // rent-exempt minimum
    data_hash:    [u8; 32],        // Poseidon(result || proof_hash || ts)
    slot_created: u64,
  },

  // Node consensus attestation
  attestation: {
    threshold:    u8,              // required: 3
    signers:      u8,              // provided: 5
    signatures:   [Ed25519Sig; 5], // node operator sigs
    aggregated:   BLS12_381Sig,    // aggregated BLS signature
  }
}

// Verification flow:
// 1. Recompute leaf_hash = Poseidon(compressed_account.data_hash)
// 2. Walk siblings[] from leaf to root
// 3. Assert computed_root == state_root
// 4. Verify Groth16 proof against verification key
// 5. Verify BLS aggregate signature
// 6. Store result in compressed account via CPI
On-Chain Logic

Anchor Oracle Program

The core on-chain program is built with Anchor v0.30 and deployed on Solana mainnet. It orchestrates the entire oracle query lifecycle through six instructions. The first, submit_query, allows any wallet to submit a 32-byte commitment hash along with a fee payment in $PXCL tokens. The commitment is a SHA-256 digest of the concatenated query parameters: asset address, chain ID, data type identifier, and a random 32-byte nonce generated client-side. This design ensures that the query intent is never revealed on-chain.

Once oracle nodes have fetched the requested data and generated a Groth16 proof off-chain, the second instruction verify_and_store is called. This instruction loads the on-chain verification key (a BN254 G1/G2 point set derived from the trusted setup), deserializes the 192-byte proof, and performs the pairing check. If the proof is valid, the instruction simultaneously stores the result in a Light Protocol compressed account via CPI, burns 50 percent of the query fee, and distributes the remaining 50 percent to the oracle node operators who contributed valid attestations.

The remaining four instructions handle peripheral concerns. claim_rewards allows node operators to withdraw accumulated rewards. update_tier lets the governance multisig adjust fee tiers and burn ratios. rotate_vk is a governance-gated instruction for rotating the Groth16 verification key when circuit upgrades are deployed. Finally, emergency_pause requires a 3-of-5 multisig signature to halt all oracle operations in the event of a detected exploit or critical vulnerability. All state transitions emit Anchor events that off-chain indexers consume for dashboard analytics and monitoring.

Multi-Chain

Cross-Chain Bridge Adapters

PixelOracle supports oracle queries against state on Ethereum mainnet, Binance Smart Chain, Arbitrum One, and Polygon PoS. Each chain is served by a dedicated bridge adapter that implements a common interface: fetchData for raw state retrieval, constructStorageProof for building a cryptographic proof against the source chain, verifyStorageProof for local validation, and normalizeResult for converting chain-specific data formats into the standard OracleResult structure consumed by the proof engine.

For EVM-compatible chains, the adapter calls eth_getProof on a trusted RPC endpoint to retrieve a Merkle Patricia Trie inclusion proof for the target storage slot. This proof contains an account proof (trie path from state root to the account node) and a storage proof (trie path from the account storage root to the specific slot). Both proofs are verified locally against the block header state root before the data is passed to the ZK circuit. The block header itself is validated against a light client or header relay contract, ensuring that the oracle cannot be fed data from a forked or fabricated chain state.

Once verified, the adapter normalizes the result into a chain-agnostic format and hands it to the proof engine. The engine wraps the cross-chain data alongside the original commitment hash into a composed Groth16 proof that attests to both the correctness of the source chain retrieval and the integrity of the oracle computation. This composed proof is what ultimately gets verified on Solana and stored in the compressed state tree.

Cross-chain Bridge Architecture
EthereumMerkle Patricia Trie
BSCMerkle Patricia Trie
ArbitrumAnyTrust + Nitro Proofs
PolygonHeimdall Checkpoints
Oracle obelisk monument
Privacy Engine

Privacy-Preserving Query Architecture

COMMITMENT PRIVACY

All query parameters are hashed into a 32-byte SHA-256 commitment before any data leaves the client. The commitment is the only artifact transmitted to oracle nodes and recorded on-chain. The original inputs -- asset address, chain identifier, data type, and nonce -- remain exclusively on the querier's device. Even if an attacker observes every transaction on the Solana network, they cannot reverse-engineer the query from the commitment due to the preimage resistance of SHA-256. The nonce adds 256 bits of entropy, preventing dictionary attacks against common query patterns.

PROOF PRIVACY

The Groth16 zero-knowledge proof demonstrates that the oracle computation was performed correctly without revealing intermediate values. The proof attests that the commitment was honestly constructed, that the data was retrieved from a valid source, and that the result falls within expected bounds. None of the private witness data (the actual query parameters or raw fetched values) is exposed in the proof or its public inputs.

STORAGE PRIVACY

Compressed accounts in the state Merkle tree provide aggregation privacy. Individual query results are leaves among millions of entries. Observing the tree root change reveals that some update occurred but not which leaf was modified or what data it contains. Future work includes selective disclosure proofs allowing queriers to reveal specific input components when partial transparency is desired.