Observation Commitment Protocol (OCP) v1.0.0

Observation Commitment Protocol (OCP) v1.0.0

A minimal primitive for committing arbitrary data digests to a public ledger


Summary

This post introduces the Observation Commitment Protocol (OCP) — a minimal, ledger-relative primitive for:

  • Committing a cryptographic digest of arbitrary data to a public ledger
  • Producing a portable proof of that commitment
  • Verifying that proof under explicit assumptions

OCP isolates the smallest possible interface for:

data → digest → ledger → verification

It deliberately avoids introducing assumptions about storage, identity, data availability, or application-layer semantics.


Motivation

There is no widely adopted primitive for:

  • Committing arbitrary data digests to a ledger
  • Producing portable, independently verifiable proofs of those commitments
  • Verifying such proofs without reliance on trusted infrastructure

Existing approaches are typically:

  • Application-specific
  • Coupled to storage or data availability layers (e.g., IPFS, DA systems)
  • Bundled with identity or signature schemes
  • Dependent on canonical encoding formats

OCP separates these concerns and defines only what is strictly necessary for verifiable inclusion of a digest in a ledger.


Core Idea

OCP defines the following invariant:

A proof is accepted if and only if:

  • H = hash(observation)
  • H ∈ R(tx) where tx is the transaction referenced by the proof

No additional meaning is implied.


Model

Parties

  • Prover — constructs commitments and produces proofs
  • Verifier — evaluates proofs relative to a verification context

Verification Context

Verification is defined relative to:

  • A ledger view L
  • A hash function hash
  • An encoding and extraction rule R

Proofs are not self-describing; correctness depends on agreement on this context.

In particular, the verifier must apply the same rule R used to produce the commitment.


Proof Structure

A proof is defined as:

P = (observation, H, tx_ref)

Where:

  • H = hash(observation)
  • tx_ref identifies a transaction in L

Verification Function

Verify(P, L, hash, R) → {0,1}

Verification succeeds if and only if:

  1. hash(observation) = H
  2. tx_ref resolves to a transaction tx ∈ L
  3. H ∈ R(tx)

This defines a minimal, deterministic, stateless verification procedure.


Security Intuition

An adversary succeeds if it produces a proof P* such that:

  • observation* ≠ observation
  • Verify(P*, L, hash, R) = 1

This requires either:

  • Breaking collision or preimage resistance of the hash function, or
  • Causing the verifier to accept an incorrect ledger view

Properties

  • Minimal commitment primitive
  • Explicit verification assumptions
  • Ledger-relative correctness
  • No trusted intermediaries
  • Offline verifiability (given access to L)
  • Composable with higher-level systems

Non-Goals

OCP does not define:

  • Data availability
  • Identity or authorship
  • Signature schemes
  • Canonical encoding standards
  • Application-layer semantics

Why This Might Matter

OCP can be viewed as a missing primitive:

A standardized way to bind arbitrary data to a ledger and verify that binding independently.

Potential applications include:

  • AI and data provenance
  • Scientific logging
  • Sensor networks
  • Media authenticity
  • Cross-system audit trails
  • Dispute evidence systems

Adversarial Framing

The protocol is intentionally falsifiable.

Given a valid (observation, proof) pair:

  • Modify the observation in any way
  • Attempt to produce a proof that still verifies

If this succeeds under the same (L, hash, R) context, the protocol is broken.


Repository

Includes:

  • Canonical specification (v1.0.0)
  • Reference implementation
  • Example proofs and verification flows
  • End-to-end submission and verification tooling

Specification


Request for Feedback

Looking for feedback on:

  • Whether this primitive already exists in a cleaner or more standard form
  • Ambiguities in the definition of R (encoding and extraction rule)
  • Ledger model assumptions (e.g., reorgs, weak subjectivity)
  • Whether this abstraction belongs at the protocol layer or application layer
  • Any overlooked attack surfaces

Closing Thought

OCP makes a narrow claim:

It does not establish what data means.
It establishes that a specific digest was included in a ledger.

OCP — Example + Clarification

This section provides a concrete example to clarify how OCP operates in practice.


Example

Let:

  • observation = "hello world"
  • H = hash(observation)

A transaction tx is constructed such that:

  • H is included in the transaction (e.g., calldata or event log)

Define an encoding and extraction rule R such that:

  • R(tx) returns a set of extracted 32-byte values from the transaction

A proof is then:

P = (observation, H, tx_ref)


Verification

A verifier performs:

  1. Compute:
    H' = hash(observation)

  2. Check:
    H' == H

  3. Resolve:
    tx from tx_ref

  4. Extract:
    S = R(tx)

  5. Check:
    H ∈ S

If all checks pass → Verify = 1


Important Clarification

OCP does not prove:

  • Who created the data
  • When the data was created in real-world time
  • That the data is true, valid, or meaningful

OCP proves only:

  • That a specific digest H was included in a ledger

What is Actually Being Proven?

Not:

“this file is authentic”

But:

“this exact byte sequence hashes to H, and H exists in the ledger”


Why This Matters

Even the smallest change to observation:

  • produces a completely different hash H*
  • which will not match the committed H

Therefore:

  • verification must fail

This is the core integrity guarantee.


Minimal Mental Model

OCP is:

  • Not storage
  • Not identity
  • Not truth

It is:

A binding between bytes and a ledger

Observation Commitment Protocol (OCP) — Break This

I’ve implemented a minimal version of the Observation Commitment Protocol (OCP) and would like to invite adversarial testing.

Live Implementation

Repository


What the system does

At its core:

File → Hash → Ethereum → Proof → Verify anywhere

More concretely:

  1. A file is hashed locally → H = hash(observation)
  2. H is committed on-chain (calldata / event)
  3. A proof is formed: (observation, H, tx_ref)
  4. Anyone can verify:
    • recompute H
    • resolve tx_ref
    • check H ∈ R(tx)

The Challenge

Take a valid (file, proof) pair and:

Modify the file in any way — even a single byte — and attempt to produce a proof that still verifies under the same assumptions.

If you can produce:

observation* ≠ observation
Verify(P*, L, hash, R) = 1

then the system is broken.


What would count as a break?

  • A modified file that still verifies against the original proof
  • A forged proof that passes verification without the original commitment
  • Any ambiguity in extraction rule R(tx) that allows false positives
  • Any mismatch between on-chain data and verification logic

What this is NOT testing

  • Identity / authorship
  • Data availability
  • Off-chain storage assumptions

This is strictly testing the minimal invariant:

A specific digest is bound to the ledger and cannot be altered without detection.


Why I’m posting this

This pattern (hash → inclusion → verification) appears everywhere in Ethereum, but is rarely isolated and tested as a standalone primitive.

This implementation is an attempt to make that primitive explicit — and falsifiable.


Ask

If you can break it, I want to understand how.

If you think this is trivial or already well-covered, I’d also appreciate pointers to existing abstractions that fully capture this pattern.

Case Study: Synchronous Composability and the Need for a Commitment Layer

Reference Problem

Recent research proposes enabling synchronous composability between rollups via realtime proving:

The design introduces a powerful capability:

  • atomic execution across L1 and multiple L2s within a single slot
  • execution tables capturing all cross-domain state transitions
  • validity proofs ensuring correctness of the entire execution bundle
  • shared sequencing to guarantee all-or-nothing state transitions

This represents a major step toward unified multi-chain execution.


System Model

At a high level, the system operates as follows:

  1. A shared builder/sequencer constructs:

    • an L1 block
    • multiple L2 blocks
  2. It simulates all cross-domain calls and produces:

    • an execution table representing ordered state transitions
  3. A validity proof is generated for the entire bundle

  4. The execution table (or its effects) is submitted to L1 proxies

    • allowing nodes to replay the state transition
    • without direct access to all underlying L2 states

This yields atomic composability:

all transitions succeed together or none do


Observed Constraints

While the design is robust, it introduces several tightly coupled constraints:

1. Slot-Bound Validity

  • Proofs are valid only for a specific L1 slot and pre-state
  • Execution correctness is tied to a narrow temporal window

2. Cross-Domain Synchronization

  • Nodes may require access to multiple rollups
  • or must trust the correctness of bundled execution

3. Atomicity via Infrastructure

  • Guarantees depend on:
    • shared sequencer behavior
    • correctness of the proving system

4. Ephemeral Execution Artifacts

  • The execution table exists primarily as:
    • an intermediate structure
    • consumed by the proving system
  • It is not treated as a persistent, referenceable object

Underlying Gap

These constraints point to a deeper architectural question:

What is the canonical, independently verifiable reference for the resulting state?

In the current model:

  • truth is defined by the validity proof

However, the system lacks:

a persistent, system-independent commitment to the resulting state itself


OCP Perspective: Commitment to Observed State

The execution table already represents:

a complete, ordered record of observed state transitions across domains

The Observation Commitment Protocol (OCP) suggests elevating this artifact:

  • compute a digest of the execution table (or its root)
  • anchor that digest on-chain at the relevant slot
  • treat it as a first-class, referenceable object

This introduces a minimal invariant:

a specific state artifact existed at time t and can be independently verified


Separation of Concerns

This enables a clean architectural split:

Function Mechanism
Prove correctness zk validity proof
Anchor result observation commitment
Reference state committed digest
Verify integrity hash + inclusion + event

Implications for the Case

Slot Dependence → Slot-Anchored State

  • Proofs remain slot-specific
  • Commitments provide a persistent reference tied to that slot

Cross-Rollup Sync

  • Nodes can verify against:
    • a shared committed state root
  • without reconstructing all execution dependencies

Atomicity

  • Not only enforced by execution
  • but reflected in:
    • a single committed state artifact

Execution Table Lifecycle

  • Transitions from:
    • ephemeral proof input
  • to:
    • portable, verifiable object

Key Insight

Synchronous composability solves:

how to execute atomically across domains

But it leaves open:

what is the canonical object representing the result of that execution?


OCP as a Complementary Layer

OCP does not replace:

  • shared sequencing
  • realtime proving
  • zk validity systems

Instead, it introduces:

a neutral commitment layer for observed state

This allows execution artifacts (like execution tables) to be:

  • anchored
  • referenced
  • verified independently

Takeaway

Execution and proof establish correctness.

But large-scale composability systems also require:

a stable, portable reference to the resulting state

Treating execution artifacts as commitment objects provides that reference.

This suggests a broader architectural pattern:

execution → proof → commitment

Where commitment acts as the bridge between:

  • computation
  • verification
  • and independent observation

Update: Proof Envelope, EVM Reference Implementation, and Cross-Chain Direction

Since the original post and adversarial challenge, OCP has moved from a single-chain prototype toward a cross-chain primitive. This post summarizes what has been built, what is now locked, and where the protocol is heading.


The problem this update addresses

The original post left the extraction rule R implementation-defined — correct for a minimal spec, but insufficient for a portable verifier. Two implementations using different extraction rules can both claim spec compliance while being mutually incompatible. The work since has been to close that gap without compromising the narrowness of the primitive.


What has been built

Proof Envelope Schema v1.0.0

The proof structure P = (observation, H, tx_ref) is now formalized as a self-describing, chain-agnostic JSON artifact. The critical design constraint:

A valid OCP proof envelope must be verifiable against raw ledger data — no SDK, no RPC provider, no indexer required.

Key fields:

  • chain.id — CAIP-2 chain identifier (eip155:1, eip155:84532, etc.)
  • chain.namespace — ledger architecture family (evm, solana, cosmos, bitcoin)
  • commitment.serialization — explicit (raw-bytes only in v1.0) — eliminates silent verification failures from encoding mismatches
  • ledger_ref — transaction ID, block height, block hash, finality depth
  • extraction.rule_id — namespaced rule identifier (evm/event-log, solana/instruction-data)

Spec: docs/spec/ocp-proof-envelope-v1.0.0.md

EVM Extraction Rule: evm/event-log

R is now formally specified for EVM chains against raw RLP-decoded receipt structure — not SDK calls:

R(receipt) = { topic[1] : log ∈ receipt.logs,
                           log.topics[0] = keccak256("Recorded(bytes32,address)"),
                           len(log.topics) >= 2 }

Reference contract deployed to Base Sepolia 0x0963Fd33DF80c94360F2DC22e5c09517AeE7ED5c:

contract ObservationCommitment {
    event Recorded(bytes32 indexed digest, address indexed recorder);
    function record(bytes32 digest) external {
        emit Recorded(digest, msg.sender);
    }
}

Spec: docs/spec/appendix-evm-r.md

Zero-dependency reference verifier

The reference verifier performs live on-chain verification using Node.js stdlib only — no ethers.js, no web3, no axios. Raw HTTPS JSON-RPC call to eth_getTransactionReceipt, log topic parsing, digest confirmation.

Live output against a real Base Sepolia transaction:

  hash      MATCH  14cca453684a18c1ef3e1c0b9a7744cfa06942660719bba373ef5fc36208bf73
  chain     eip155:84532
  rpc       https://sepolia.base.org
  tx        0xf2e1f6c085768b4e3d60463717d52bb2a338803a74a4cfd48aea5738d2595ddd
  logs      found 1 Recorded event(s)
  digest    MATCH  14cca453684a18c1ef3e1c0b9a7744cfa06942660719bba373ef5fc36208bf73

VALID

This closes the original falsification challenge: the verification procedure is now explicit enough that anyone can implement a verifier from the spec alone, with no dependency on any named tool or provider.


Cross-chain coordination — what is locked

OCP has been referenced in the ERC-8004 (Universal AI Inference Verification Registry) thread on Ethereum Magicians. The architecture converging there maps directly onto OCP as a primitive:

trust layer       →  inputSources + sanitize()
provenance layer  →  verifyInputProvenance()
OCP primitive     →  digest → commitment → verify inclusion
proof layer       →  verify(modelHash, inputHash, outputHash, proof)
registry          →  coordinates interoperability

OCP sits at layer 3. Its boundary stays narrow — it does not touch sanitization semantics, pipeline specs, or provenance policy. The moment OCP standardizes those concerns it stops being a primitive and starts being an application.

Through that coordination, the following has been confirmed between two independent implementations:

Identity pipeline sentinel hash — a canonical fixed hash for the “no sanitization” case, confirmed independently by two implementations using sorted-key SHA-256:

spec:  {"controlCharExclusions":null,"controlCharRanges":null,"maxLength":null,
        "patternFlags":null,"patterns":[],"provenanceLabel":null,
        "replacementToken":null,"sourceType":"identity",
        "specVersion":"erc-8004-security/identity","transformation":"none"}

hash:  8116eec29078e8f57c07077d5e8080a35bde73036581df3abb93755d1b1a16ea

Two independent implementations, same result. This is how standards get made.


Connection to the synchronous composability case study

The case study in the previous post identified a gap: synchronous composability solves how to execute atomically across domains, but leaves open what the canonical object representing the result of that execution is.

The proof envelope makes this concrete. An execution table root committed via OCP produces a portable, self-describing proof artifact that:

  • identifies which chain the commitment was made on
  • specifies exactly how to extract the digest from the raw transaction
  • records finality depth at commitment time
  • is verifiable from raw block data with no infrastructure dependency

The pattern from the case study holds:

execution → proof → commitment

The envelope is what the commitment layer produces. It is the portable reference.


What is next

Phase 3 is the Solana appendix — defining R for the account/instruction model. Solana’s transaction structure is fundamentally different from EVM: no logs, no topics, instruction data instead of calldata, different finality semantics. If the proof envelope format holds without modification across EVM and Solana, the abstraction is genuinely chain-agnostic. If it requires changes, the seam will be visible and the spec can be updated before the design locks.

That test is the difference between a protocol that claims to be chain-agnostic and one that proves it.

Repository: GitHub - damonzwicker/observation-commitment-protocol: A minimal protocol for independently verifying that a specific byte sequence was committed to a public ledger. · GitHub

Gate 3 complete.

The same observation is now committed on two fundamentally different ledger architectures:

EVM (Base Sepolia) — via event log

tx: 0xf2e1f6c085768b4e3d60463717d52bb2a338803a74a4cfd48aea5738d2595ddd
digest: 14cca453684a18c1ef3e1c0b9a7744cfa06942660719bba373ef5fc36208bf73

Solana (devnet) — via instruction data

tx: 43B5qatkYp5VZpaxrSCSe4jEHG2NgFpPGi6RdGABD9v3YbBcoCt5faKbrAgxFt4N4QzT69Z5vcnL81jaasRaUcfq
digest: 14cca453684a18c1ef3e1c0b9a7744cfa06942660719bba373ef5fc36208bf73
program: GCXRKzreL2fdYBpnfmKzFqTxE46eGmwQuErMw4uZ1DUL
discriminator: 49f0c95bf2609126

Same digest. Same proof envelope format. Different chains. The abstraction held without structural modification.

The proof envelope schema required no changes for Solana. All existing fields accommodate the Solana values. One additive extension field (commitment) was added to ledger_ref.finality to carry the Solana-native commitment level — this does not break EVM envelope compatibility.

OCP’s cross-chain claim is now proven in practice, not just in spec.

1 Like

Been running OCP in production at gateway . ensub . org since the AI inference attestation appendix merged — the recompute → compare → confirm inclusion invariant holds cleanly across all the live executions.

The chain-agnostic abstraction has been load-bearing in practice. We’re using OCP as the L3 trustless floor in a four-layer AI agent trust stack alongside ERC-8004 (agent identity), WYRIWE (input provenance), and EIP-712 gateway attestations (L4 infrastructure notary). The stack was validated end-to-end in a cross-chain setup — ERC-8004 registry on Ethereum mainnet, BountySettlement on Base Sepolia.

ERC-8274 (AI Inference Proof Verification, PR #1771) formally references OCP as the unifying verification primitive across ZK, multisig, TEE, and opML backends. A Composition Note co-authored with Damon and Vincent Wu documenting exactly how ERC-8263 + OCP + ERC-8004 + WYRIWE compose is publishing on ethresear.ch shortly.

The deliberate minimalism of OCP — no identity, no data availability, no application semantics — is exactly what makes it composable with everything above it.

Good work Damon.

Tiago Merlini (dinamic.eth / @TMerlini)

1 Like

Tiago — welcome to ethresear.ch, and thank you for this.

Having the production context documented here — on the original thread, by the builder who’s been running it — is exactly the kind of independent record that matters. The four-layer stack you described, the BountySettlement validation, the composability with ERC-8004 and WYRIWE — all of it is now part of the permanent public record of OCP.

The Composition Note will be posted here shortly. Glad to have you on the thread.

— Damon (@DamonZwicker)

1 Like