Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Guides

How to Architect Stateless Blockchain Clients

A technical guide to designing and implementing stateless blockchain clients, covering architecture patterns, witness generation, and verification logic for developers.
Chainscore © 2026
introduction
DESIGN PATTERNS

How to Architect Stateless Blockchain Clients

A guide to designing blockchain clients that verify state without storing it, using cryptographic proofs for scalability and decentralization.

A stateless blockchain client is a node that validates new blocks and transactions without maintaining a full copy of the global state (account balances, smart contract storage). Instead, it relies on cryptographic proofs—specifically Merkle proofs or Verkle proofs—to verify that the state transitions proposed in a block are correct. This architectural shift, central to Ethereum's statelessness roadmap, addresses the critical scaling bottleneck of ever-growing state size, which currently requires validators to manage hundreds of gigabytes of data. The core principle is that block producers provide proofs alongside blocks, and verifiers check them against a small, constant-sized state root.

Architecting such a client involves several key components. First, you need a proof system. For Ethereum, this is a Verkle Trie, which uses vector commitments to create proofs that are much smaller (~200 bytes) than traditional Merkle proofs. The client must implement logic to verify these proofs against the known state root. Second, a witness management layer is required. The block producer must gather all the necessary proofs (the "witness") for the state accessed by the block's transactions and attach it. The client's job is to validate this witness, ensuring each piece of referenced state has a valid proof linking it to the root.

The client's validation workflow changes fundamentally. Instead of reading state from a local database, it receives a block and its associated witness. For each transaction, it uses the provided proofs to compute the expected post-state root. If the computed root matches the one in the block header, the block is valid. This requires implementing new state transition functions that are proof-aware. Developers can experiment with this today using Ethereum's experimental Verkle implementations in clients like Geth or Nethermind, or by studying the Capec specifications for stateless execution.

A major design challenge is witness size minimization. Even with Verkle proofs, the witness for a complex block can be large. Techniques like witness compression (e.g., using polynomial commitments) and bandwidth-efficient protocols are active areas of research. Furthermore, the architecture must decide on a trust model: will the client always fetch a full witness from the network, or can it use a state expiry model where older state is removed and must be provided by the transaction sender? Ethereum's proposed EIP-4444 (history expiry) complements stateless design by limiting historical data liability.

For practical implementation, start with a light client foundation. A stateless client is, in essence, a supercharged light client. Use libraries like @ethereumjs/verkle for proof verification. Structure your client to separate the consensus layer (block validity) from the execution layer (state transition with proofs). The architecture should expose a clean API for submitting a (block, witness) pair and returning a validation result. This design is crucial for future rollup clients, which can be fully stateless verifiers of L2 state roots, achieving maximum scalability and minimal hardware requirements.

prerequisites
ARCHITECTURE

Prerequisites for Building a Stateless Client

Stateless clients aim to verify blockchain state without storing it locally. This guide outlines the core concepts and technical requirements needed to architect one.

A stateless client is a node that validates new blocks without maintaining a full copy of the blockchain's state (e.g., account balances, smart contract storage). Instead, it relies on cryptographic proofs, primarily Merkle proofs, to verify that the state transitions proposed in a block are correct. This architecture drastically reduces storage and hardware requirements, enabling lightweight clients to participate in consensus. The core challenge is designing a system where block producers provide all necessary data for verification within the block itself or through a separate data availability layer.

The fundamental prerequisite is a commitment scheme that can efficiently prove state membership and non-membership. The Verkle tree, proposed for Ethereum, is a key evolution from Merkle Patricia Tries. It uses vector commitments and polynomial commitments to create much smaller proofs, which is critical for keeping block witness sizes manageable. You must understand cryptographic primitives like KZG commitments or IPA (Inner Product Argument) schemes, which underpin these structures. Familiarity with concepts like witness data (the set of Merkle/Verkle branches needed to verify a block) is essential.

You need a deep understanding of your target blockchain's state model. For an Ethereum-like chain, this includes the World State (a mapping of addresses to account objects), storage tries for each contract, and the transaction trie. The client's architecture must define precisely which parts of this state are accessed by a given block. Tools like block witnesses or state proofs must be serialized and transmitted efficiently. Projects like Ethereum's Portal Network or Celestia's data availability sampling are exploring solutions for distributing this data.

Implementation requires strong cryptography and systems programming skills. You'll be working with libraries for pairing-based cryptography (e.g., for KZG) or advanced elliptic curve operations. The client must have a robust proof verification pipeline that can check the validity of potentially thousands of proofs per block with minimal latency. Performance optimization is critical, as the verification logic must be faster than simply executing the transactions against a full state. Languages like Rust, C++, or Go are typical choices for this performance-sensitive layer.

Finally, you must integrate with the network's consensus and execution layers. The stateless client must understand the block structure, receive blocks and their associated witnesses from the peer-to-peer network, and interface with an execution client (like an EVM). It verifies that the post-state root in the block header matches the result of applying the transactions to the pre-state, using only the provided proofs. Testing against existing testnets (e.g., Ethereum's Holesky) and using formal verification for critical cryptographic components are non-negotiable steps for ensuring security.

key-concepts-text
CORE CONCEPTS OF STATELESS VERIFICATION

How to Architect Stateless Blockchain Clients

Stateless clients shift the burden of state storage from nodes to users, enabling radical scalability. This guide explains the architectural principles for building them.

A stateless client does not store the entire blockchain state (account balances, contract storage). Instead, it verifies new blocks using cryptographic proofs, known as witnesses, provided alongside the block data. The core architectural shift is moving from a state-holding to a state-verifying model. This drastically reduces the hardware requirements for nodes, as they only need to store a small, constant-sized state root (like a Merkle root), not gigabytes of state data. The canonical goal, exemplified by Ethereum's Verkle tree roadmap, is to enable lightweight validation without sacrificing security.

The architecture relies on two key data structures: the authenticated state tree and the witness. The state tree (a Merkle or Verkle tree) commits to all state data in its root hash. A witness is a compact proof that contains the specific tree nodes needed to verify a transaction's preconditions (e.g., account nonce, balance) and compute the new post-transaction state root. The client receives a block header and a bundle of witnesses; it uses the witnesses to recompute state transitions locally. If the resulting state root matches the one in the header, the block is valid.

Implementing this requires changes across the stack. At the networking layer, protocols like Ethereum's Portal Network are designed to serve witnesses on-demand. The consensus layer must enforce rules that blocks are only valid with correct witnesses. For developers, the execution client (e.g., Geth, Erigon) must integrate a proof verification engine. A critical design pattern is witness gas, which accounts for the bandwidth and verification cost of witnesses, preventing spam. Architectures often separate the block proposer (which must be stateful) from the block validator (which can be stateless).

The primary challenge is witness size. A traditional Merkle proof for an Ethereum transaction can be ~1 KB. For a block with 200 transactions, this balloons to ~200 KB of witness data per block, per client—a bandwidth impossibility. This is why Verkle trees are essential; they use vector commitments to create constant-sized proofs (~150 bytes) regardless of tree depth. Another challenge is witness availability: a stateless client must be able to fetch the correct witness for any historical transaction it wishes to verify, necessitating a robust peer-to-peer witness distribution network.

To start architecting, first choose your proof system and tree structure. For new chains, Verkle trees with polynomial commitments are the modern standard. For Ethereum compatibility, follow the EIPs for Ethereum Statelessness. Your client's core loop will: 1) Receive block header and witness, 2) Extract the transactions, 3) For each transaction, use the witness to fetch and verify the pre-state, 4) Execute the transaction, 5) Update the in-memory tree with the witness data, 6) Recompute the root and compare. Libraries like rust-verkle provide the cryptographic primitives. The end goal is a client that syncs in hours, not days, using minimal disk space.

IMPLEMENTATION MODELS

Stateless Client Architecture Comparison

Comparison of the primary architectural approaches for building stateless blockchain clients, focusing on trade-offs between state management, performance, and complexity.

Architecture FeatureFull State (Baseline)Stateless w/ WitnessesState Network (Portal Network)

State Data Storage

Full chain state on disk

Witnesses (~1-10 MB per block)

Distributed network of state providers

Initial Sync Time

Hours to days (TB scale)

Minutes (headers + latest witness)

Minutes (light client bootstrap)

Bandwidth per Block

Low (headers only)

High (witnesses required)

Medium (query network as needed)

CPU/Memory Overhead

High (state execution)

Low (verification only)

Very Low (request/response)

Network Requirements

Standard p2p (eth/66)

Witness provider dependency

Portal network protocol (discv5)

Implementation Complexity

Mature (Geth, Erigon)

High (witness generation logic)

Emerging (Trin, Fluffy)

Security Model

Self-validating (full security)

Trusted witness or committee

Cryptoeconomic incentives + light client

Ethereum Mainnet Readiness

Production (current clients)

Research (EIP-4444, Verkle)

Active development (EIP-4844 companion)

architecture-steps
GUIDE

How to Architect Stateless Blockchain Clients

Stateless clients reduce node resource requirements by verifying blocks without storing the full state. This guide outlines the architectural components and data flow for building one.

A stateless client is a blockchain node that validates new blocks without maintaining a persistent copy of the entire world state (account balances, contract storage). Instead, it relies on cryptographic proofs, typically Merkle proofs or Verkle proofs, provided alongside the block data. The core architectural shift is moving from state storage to state proof verification. This design is critical for scaling light clients and enabling extremely low-resource nodes, as seen in Ethereum's roadmap with EIP-4444 and the transition to Verkle trees.

The architecture centers on two key data structures: the block header and the witness. The block header contains the state root (e.g., a Merkle or Verkle root), which commits to the entire state. The witness is a compact cryptographic proof that contains all the state data accessed by the transactions in that block, along with the necessary sibling nodes to verify the data against the state root. Your client's primary job is to receive a block and its witness, then use the witness to recompute the state root and check it matches the one in the header.

Your client's verification pipeline follows these steps: 1) Proof Decoding: Parse the serialized witness to extract accessed account data and Merkle/Verkle proof paths. 2) State Root Reconstruction: Use the provided data and proofs to hash up the tree, recalculating the root. 3) Root Validation: Compare your computed root to the stateRoot field in the block header. 4) Transaction Execution: Replay the block's transactions in a sandbox, using only the data from the witness to update state. If any transaction tries to access state not included in the witness, execution fails, invalidating the block.

Implementing this requires a stateless execution engine. Unlike a full node's EVM, which queries a local database, your engine must trap all SLOAD, BALANCE, and EXTCODECOPY operations. These operations are redirected to check the witness data. Libraries like trin (Ethereum) or reth demonstrate this pattern. The critical code path involves a proof verifier module and a modified VM. For development, you can test against existing test vectors from Ethereum's stateless Ethereum tests or use a local devnet configured for stateless validation.

The major challenge is witness size management. For Merkle trees, witnesses can be large (tens of kilobytes per block). Verkle trees, which use vector commitments and polynomial commitments, drastically reduce witness size and are the target for future stateless architectures. Your design should abstract the proof system to allow swapping from Merkle to Verkle. Another consideration is witness distribution, which may require a separate P2P sub-network or retrieval from dedicated servers, as standard block propagation does not include this data.

To start building, use a framework like Lighthouse or Nimbus for Ethereum, which have early stateless client research branches. Focus on integrating a proof verification library (e.g., rust-verkle for Verkle proofs) and modifying the execution client to be witness-driven. The end goal is a client that can sync and validate the chain by downloading blocks and corresponding witnesses, storing only the chain of headers, thereby achieving near-constant storage overhead regardless of chain activity.

ARCHITECTURE COMPARISON

Implementation by Blockchain Platform

Ethereum's Stateless Client Path

Ethereum's roadmap to statelessness is centered on Verkle Trees and EIP-6800. The current hexary Patricia Merkle tree is being replaced with a Verkle tree, which uses vector commitments to create much smaller proofs (a few KB vs. MBs). This enables nodes to validate blocks using only a witness (proof) rather than the full state.

Key components for client architects:

  • State Expiry (EIP-4444): Prunes historical state, reducing storage burden.
  • Portal Network: A decentralized peer-to-peer network for serving historical data and state witnesses.
  • Execution Clients: Geth, Nethermind, and others will implement stateless block validation, where the block proposer provides the necessary witness.

Architecture shift: Full nodes become stateless validators, relying on proposers or the portal network for proofs, while archive nodes and the portal network serve as data availability layers.

STATELESS CLIENTS

Common Implementation Mistakes and Pitfalls

Stateless clients verify blockchain state without storing it, but architectural oversights can lead to high latency, sync failures, and security vulnerabilities. This guide addresses frequent developer errors.

High latency often stems from inefficient witness (proof) fetching and validation. A common mistake is requesting full block witnesses for every new block, which saturates network bandwidth.

Key issues:

  • Sequential fetching: Fetching witnesses for block N+1 only after fully validating block N creates a bottleneck.
  • No peer scoring: Not prioritizing peers with low-latency, high-availability witness data.
  • Large witness size: Not leveraging witness compression (e.g., using binary Merkle trees over hexary) or bandwidth-saving protocols like EIP-4444.

Solution: Implement parallel witness retrieval. Request witnesses for future blocks speculatively while validating the current one. Use a peer manager to track and select the best data providers.

IMPLEMENTATION

Code Examples and Snippets

Fetching and Verifying State with Proofs

This example uses Ethers.js to fetch an account's balance and storage proof from a provider supporting the eth_getProof RPC call (e.g., Erigon, Geth in archive mode).

javascript
const { ethers } = require('ethers');
const { MerkleTree } = require('merkletreejs');
const keccak256 = require('keccak256');

// Connect to a node supporting eth_getProof
const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL');
const address = '0x...'; // Account to query
const blockTag = 'latest'; // Or a specific block number

// 1. Get the block header to obtain the trusted state root
const block = await provider.getBlock(blockTag);
const stateRoot = block.stateRoot;

// 2. Request the account proof
const proof = await provider.send('eth_getProof', [
  address,
  [], // Array of storage keys (empty for just account proof)
  ethers.toQuantity(block.number)
]);

// 3. Verify the account proof (simplified conceptual step)
// In practice, you would reconstruct the trie path and verify each hash.
// This pseudo-step checks if the derived root matches the block's stateRoot.
console.log('State Root from Block:', stateRoot);
console.log('Account Proof Received:', proof.accountProof.length, 'nodes');
// Verification logic would go here using a library like merkle-patricia-tree

This demonstrates the client-side request pattern. Full verification requires implementing the Ethereum trie structure.

STATELESS CLIENTS

Frequently Asked Questions

Common questions and technical clarifications for developers implementing or researching stateless blockchain client architecture.

A stateful client (like a standard Ethereum full node) maintains the entire world state—the aggregate of all account balances, contract code, and storage—locally on disk. It updates this state with each new block.

A stateless client does not store the world state. Instead, it relies on cryptographic proofs to verify state transitions. For every transaction in a block, it receives a witness (a Merkle proof) that contains the specific state data needed to execute and validate that transaction. The block's validity is proven without needing the full state tree.

This shift reduces storage requirements from terabytes to kilobytes for verification, enabling lighter nodes to participate in consensus.

conclusion
ARCHITECTURAL SUMMARY

Conclusion and Next Steps

Stateless clients represent a fundamental shift in blockchain node design, moving state validation from persistent storage to cryptographic proofs. This guide has outlined the core principles, trade-offs, and implementation patterns for this architecture.

The primary benefit of a stateless client is its minimal resource footprint. By relying on witnesses—Merkle proofs for state data—instead of storing the entire state trie, nodes can sync nearly instantly and operate on devices with limited storage, such as mobile phones or IoT devices. This is enabled by a state expiry or history accumulation scheme, where only recent state is actively proven, while older state is archived. The trade-off is increased bandwidth, as each transaction must be accompanied by the witness data needed to validate it.

To build a functional stateless client, you must implement several key components. First, a witness provider (often a full node) must generate and serve compact Merkle proofs for accounts and storage slots. Your client needs a proof verification engine to check these proofs against a known state root, typically using a library like @ethereumjs/statemanager. You'll also need a cache, often called a witness cache, to temporarily store recently verified proofs to avoid redundant network requests. Finally, integrating with a light client protocol, such as Ethereum's Portal Network or Helios, handles the peer-to-peer discovery and exchange of this data.

Looking forward, several developments will shape stateless client architecture. Verkle Trees, planned for Ethereum's upcoming upgrades, are designed specifically for statelessness, offering much smaller and more efficient proofs than Merkle-Patricia Tries. ZK-proof aggregation could further compress witness data. For next steps, developers should experiment with existing frameworks: run a Erigon archive node with the --stateless flag to generate witnesses, or build a simple client using the Trin client software to join the Portal Network. The ultimate goal is a network where users can verify chain validity with cryptographic certainty, without the burden of terabytes of data.