Nethereum.AppChain.Anchoring 7.1.0-preview

Prefix Reserved
This is a prerelease version of Nethereum.AppChain.Anchoring.
dotnet add package Nethereum.AppChain.Anchoring --version 7.1.0-preview
                    
NuGet\Install-Package Nethereum.AppChain.Anchoring -Version 7.1.0-preview
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Nethereum.AppChain.Anchoring" Version="7.1.0-preview" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Nethereum.AppChain.Anchoring" Version="7.1.0-preview" />
                    
Directory.Packages.props
<PackageReference Include="Nethereum.AppChain.Anchoring" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Nethereum.AppChain.Anchoring --version 7.1.0-preview
                    
#r "nuget: Nethereum.AppChain.Anchoring, 7.1.0-preview"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Nethereum.AppChain.Anchoring@7.1.0-preview
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Nethereum.AppChain.Anchoring&version=7.1.0-preview&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Nethereum.AppChain.Anchoring&version=7.1.0-preview&prerelease
                    
Install as a Cake Tool

Nethereum.AppChain.Anchoring

PREVIEW — APIs may change between releases.

Anchors AppChain state to any EVM chain (L1 or L2). Commits state roots, block hashes, and optionally compressed block data or ZK proofs to an on-chain anchor contract.

System Architecture

┌─────────────────────────────────────────────────────────────────────────┐
│                           YOUR APPCHAIN                                │
│  DevChain / CoreChain produces blocks with state roots                 │
└────────────┬────────────────────────────────────────────────────────────┘
             │ eth_getBlockByNumber (standard RPC)
             ▼
┌─────────────────────────┐     ┌──────────────────────────┐
│  IChainAnchorable       │     │  IAnchorSubmissionStrategy │
│  (RpcChainAnchorable)   │     │  7 strategies (DA × Proof) │
│  reads blocks via RPC   │     │  builds proof bytes        │
└────────────┬────────────┘     └────────────┬─────────────┘
             │                               │
             ▼                               ▼
┌─────────────────────────────────────────────────────────────────────────┐
│  AnchorWorker (IHostedService)                                         │
│  Timer-based: every AnchorCadence blocks, fetches block, calls         │
│  strategy.BuildPayload(), submits via IAnchorService                   │
└────────────┬────────────────────────────────────────────────────────────┘
             │ submitAnchor(AggregatedAnchor, bytes proof)
             ▼
┌─────────────────────────────────────────────────────────────────────────┐
│  AppChainAnchor.sol (on anchor chain — L1 or L2)                       │
│  Validates: chain registered, proof system tier, block continuity      │
│  Stores: endBlock, endBlockHash, postStateRoot, blockHashesRoot        │
│  Emits: AnchorSubmitted event                                          │
└────────────┬────────────────────────────────────────────────────────────┘
             │ events
             ▼
┌──────────────────────┐    ┌──────────────────────────┐
│  Anchor Indexer      │    │  Explorer UI             │
│  indexes events      │───▶│  Nethereum.Explorer.     │
│  to Postgres         │    │  Anchoring (Razor CL)    │
└──────────────────────┘    └──────────────────────────┘

Two Orthogonal Dimensions

Anchoring is configured via two independent enums:

Data Availability — what block data is published

public enum AnchoringDataAvailability : byte
{
    None = 0,          // anchor struct only, no block data in proof bytes
    Calldata = 1,      // brotli-compressed block RLP in proof bytes
    BlobReference = 2  // blob versioned hash in proof bytes (data in EIP-4844 blobs)
}

Proof Mode — how execution is verified

public enum AnchoringProofMode : byte
{
    None = 0,          // trust operator (commitment only)
    StarkHash = 1,     // STARK proof hash on-chain, proof in blobs, off-chain verification
    SnarkOnChain = 2   // SNARK proof on-chain, IVerifier.verify() called by contract
}

On-Chain Proof System — maps to Solidity enum

// C# (mirrors Solidity ProofSystem enum exactly)
public enum AnchoringOnChainProofSystem : byte
{
    NoProof = 0,           // commitment only
    StarkHashOffChain = 1, // STARK hash, off-chain verification
    SnarkOnChain = 2       // SNARK, on-chain verification
}
// Solidity (source of truth)
enum ProofSystem {
    NoProof,           // 0
    StarkHashOffChain, // 1
    SnarkOnChain       // 2
}

Same names, same values. The C# enum byte IS the contract's proofSystem field.

7 Anchoring Strategies

Each strategy = DA mode × Proof mode. One class per combination, names tell you everything:

Strategy class DA Proof What it does
AnchoringStrategy_NoDA_NoProof_CommitmentOnly None None Just the anchor struct. Cheapest.
AnchoringStrategy_Calldata_NoProof_SyncOnly Calldata None Compressed blocks for node sync. No proof.
AnchoringStrategy_NoDA_StarkHash_OffChainVerifiable None StarkHash 32-byte STARK hash. Proof in blobs.
AnchoringStrategy_Calldata_StarkHash_SyncAndOffChainVerifiable Calldata StarkHash Sync data + STARK hash combined.
AnchoringStrategy_NoDA_SnarkOnChain_TrustlessVerification None SnarkOnChain SNARK proof verified on-chain. Trustless.
AnchoringStrategy_Calldata_SnarkOnChain_SyncAndTrustlessVerification Calldata SnarkOnChain Sync data + SNARK proof.
AnchoringStrategy_BlobRef_SnarkOnChain_TrustlessVerificationWithBlobDA BlobRef SnarkOnChain Blob DA + SNARK proof.

Factory

var strategy = AnchoringStrategyFactory.Create(
    AnchoringDataAvailability.Calldata,
    AnchoringProofMode.StarkHash);
// Returns: AnchoringStrategy_Calldata_StarkHash_SyncAndOffChainVerifiable

Invalid combinations are rejected at creation time:

  • BlobReference + None → error (blob DA without proof is pointless)
  • BlobReference + StarkHash → error (STARK proof is already in blobs)

Quick Start

Minimal — commitment only

var config = new AnchorConfig
{
    Enabled = true,
    ChainId = 420420,
    TargetChainId = 10,  // Optimism
    TargetRpcUrl = "https://mainnet.optimism.io",
    AnchorContractAddress = "0xYourAnchorContract",
    SequencerPrivateKey = operatorKey,
    AnchorCadence = 100,
    AnchorIntervalMs = 60000,
    DataAvailability = AnchoringDataAvailability.None,
    ProofMode = AnchoringProofMode.None
};

var anchorService = new AppChainAnchorBatchService(config, web3, appChainId, genesisHash);
var chainAnchorable = new RpcChainAnchorable(appchainWeb3);
var worker = new AnchorWorker(chainAnchorable, anchorService, config);
await worker.StartAsync(cancellationToken);

With compressed calldata for sync

config.DataAvailability = AnchoringDataAvailability.Calldata;
// Strategy auto-selected: AnchoringStrategy_Calldata_NoProof_SyncOnly

With STARK proof hash

config.DataAvailability = AnchoringDataAvailability.None;
config.ProofMode = AnchoringProofMode.StarkHash;
// Strategy auto-selected: AnchoringStrategy_NoDA_StarkHash_OffChainVerifiable

Configuration

Property Type Default Description
Enabled bool true Enable/disable the anchor worker
ChainId BigInteger 1337 AppChain's chain ID
TargetChainId BigInteger — Chain ID of the anchor target
TargetRpcUrl string — RPC endpoint of the anchor chain
AnchorContractAddress string — Deployed AppChainAnchor contract
SequencerPrivateKey string — Operator key for signing
AnchorCadence int 100 Anchor every N blocks
AnchorIntervalMs int 60000 Timer poll interval (ms)
MaxRetries int 3 Retry attempts per anchor
RetryDelayMs int 5000 Base retry delay (exponential backoff)
DataAvailability enum None DA mode (None, Calldata, BlobReference)
ProofMode enum None Proof mode (None, StarkHash, SnarkOnChain)

On-Chain Contract

AggregatedAnchor struct

struct AggregatedAnchor {
    uint64  chainId;
    bytes32 genesisHash;
    uint64  startBlock;
    uint64  endBlock;
    uint8   anchorVersion;
    uint8   proofSystem;        // ProofSystem enum (0, 1, or 2)
    bytes32 endBlockHash;
    bytes32 previousAnchorHash; // chain continuity link
    bytes32 blockHashesRoot;    // Merkle root of block hashes
    bytes32 postStateRoot;
    bytes32 manifestHash;
}

Contract validation (every anchor must pass all of these)

proof.length <= 4096 bytes
chain is registered
authority.canSubmitAnchor(chainId, msg.sender)
genesisHash matches registration
proofSystem >= chain's minimumProofSystem
anchorVersion >= chain's minimumAnchorVersion
schema exists for anchorVersion
startBlock == previousAnchor.endBlock + 1 (no gaps)
previousAnchorHash == previousAnchor.endBlockHash (chain continuity)
endBlock >= startBlock (non-empty range)
if requiresProof: IVerifier.verify(proof, publicInputs)

Verifier contracts (one per proof system)

ProofSystem Verifier requiresProof Validates
0 (NoProof) address(0) false Nothing
1 (StarkHashOffChain) StarkBlobCommitmentVerifier false Hash format
2 (SnarkOnChain) a deployment-supplied IVerifier (e.g. ZiskVerifierAdapter) true Cryptographic proof

ZiskVerifierAdapter accepts a proof only for exactly 11 public inputs and 64 Zisk public values (8 bytes each). The first eight Zisk public values, 32-bit words each held in a 64-bit public, must hold keccak256(abi.encodePacked(publicInputs)) (a proof without that commitment is refused), and the inputs must name the block the proof executed (block number, pre-state root, state root, parent hash and block hash). A wrong input count, a wrong public-values length or an input that is not the executed block reverts. ZiskVerifier (Zisk 1.3.1 PLONK, Nethereum.AppChain.Anchoring.ZiskVerifier.ZiskVerifierService) takes bytes32 verification keys in verifySnarkProof; the adapter constructor still takes uint64[4] keys.

Additional format verifiers for DA: CalldataFormatVerifier, PipelinePayloadVerifier, CalldataStarkVerifier.

Compression

Block data uses brotli compression via CompressedEnvelope:

var envelope = CompressedEnvelope.Wrap(blockRlp, CompressionAlgo.Brotli);
var original = CompressedEnvelope.Unwrap(envelope);

Envelope format: [version:1][compression_algo:1][compressed_data]

Restart Recovery

AppChainAnchorBatchService.InitializeAsync() reads getLatestAnchor(chainId) from the contract on startup. Recovers _lastEndBlock and _lastEndBlockHash so the first anchor after restart has correct previousAnchorHash. The contract enforces previousAnchorHash == prev.endBlockHash — without recovery, restart would fail.

Component Projects

Project Purpose
Nethereum.AppChain.Anchoring Core: strategies, worker, batch service, config
Nethereum.AppChain.Anchoring.Postgres Indexer: EF entities, repositories, event processing
Nethereum.Explorer.Anchoring UI: Razor Class Library with Blazor pages (pluggable)
Nethereum.AppChain.Contracts Solidity: AppChainAnchor, verifiers, foundry tests

Pluggable Explorer UI

Nethereum.Explorer.Anchoring is a Razor Class Library. The explorer references it via AddAdditionalAssemblies:

app.MapRazorComponents<App>()
    .AddAdditionalAssemblies(
        typeof(IAnchorExplorerService).Assembly);

Same pattern for future modules: Messaging, Proving, Admin.

Aspire Integration

// AppHost — anchor service with strategy configured via environment
var anchoring = builder.AddProject("anchoring")
    .WithReference(mainchain)
    .WithReference(appchain)
    .WithEnvironment("Anchoring__DataAvailability", "Calldata")
    .WithEnvironment("Anchoring__ProofMode", "None");

Status endpoint GET /:

{
  "service": "Nethereum.AppChain.Anchoring",
  "anchorContract": "0xe7f1...",
  "cadence": 10,
  "intervalMs": 30000,
  "dataAvailability": "Calldata",
  "proofMode": "None"
}

Cost Guide

Scenario Anchor target DA Proof Monthly cost (1 block/s)
Development — None None $0
Private consortium L2 None None ~$0.03
Enterprise sync L2 Calldata None ~$0.10
Enterprise verifiable L1 None StarkHash ~$10 + $0.15/proof
Financial (trustless) L2 None SnarkOnChain ~$52
Full DA + proof L2 Calldata StarkHash ~$0.15

Ad-Hoc Proofs

Proofs can also be submitted per-block independently of anchoring, via AppChainProofManager:

  • submitBlockProof(chainId, blockNumber, proof, proofSystem) — operator or authorized prover
  • requestBlockProof{value: bond}(chainId, blockNumber) — anyone posts bond
  • fulfillBlockProof(chainId, blockNumber, proof) — prover earns bond

These are separate from anchor strategies — an AppChain can anchor with CommitmentOnly and still accept ad-hoc proofs for individual blocks.

  • Nethereum.CoreChain — Block headers, state management, compression, DA pipeline
  • Nethereum.Web3 — RPC interaction with anchor chain
  • Nethereum.Contracts — Smart contract encoding for AppChainAnchor
  • Nethereum.Explorer — Base explorer framework
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on Nethereum.AppChain.Anchoring:

Package Downloads
Nethereum.AppChain.Sequencer

Nethereum AppChain Sequencer - Block production, transaction ordering, and consensus-driven sequencing for AppChain nodes

Nethereum.AppChain.Sync

Nethereum AppChain Sync - Block synchronization, batch file format, state snapshots, and follower sync services

Nethereum.AppChain.Anchoring.Postgres

Nethereum AppChain Anchoring Postgres - EF Core Postgres persistence for the message indexer and block progress tracking

Nethereum.AppChain.Server.Core

Nethereum AppChain Server core — the reusable composition (storage, chain, sequencer, sync, DevP2P serve) consumed by the AppChain.Server CLI and Aspire hosts.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
7.1.0-preview 45 11/10/2026