ERC-8004 Validation Registry · Base Sepolia · testnet demo

The contract accepts only proven verdicts.

A verdict is written to this Ethereum contract only when its cryptographic proof verifies on-chain. Flip the verdict and the same proof no longer matches, so the write reverts. There is no owner, no admin, and no validator key that can write a verdict any other way.

This deployment is on the Base Sepolia testnet, published so anyone can reproduce it. It is separate from Markovian's registered agent 59270 on the ERC-8004 Identity Registry on Base mainnet; the validator contracts here are not deployed to mainnet.

sm·G + sr·H = R + e·C BN128 Pedersen + Schnorr, checked in the contract via the ecAdd / ecMul precompiles. e = keccak(requestHash, inputCommit, response, responseHash), so a proof is bound to one exact verdict and cannot be replayed onto another.
validator 0xef4d…A6a5 verifier 0xd6cD…d1A0 agent #7816 tag markovian.resolve.v1
The test

The same proof was submitted twice — once honest, once tampered.

The same commitment and proof were submitted twice. Once for the verdict it actually attests, and once for a flipped verdict. The contract accepted the first and reverted the second. Both transactions are permanent on Base Sepolia.

write accepted · status 1

The proof verified. The verdict was recorded.

recordResolution ran, the on-chain equation held, an entry was appended, and the ERC-8004 registry now returns this verdict.

verdict FAIL (0) · block parity odd
write reverted · status 0

The verdict was flipped. The proof no longer matched.

The response was changed 0 → 100 with the same proof. The bound challenge e changed, the equation failed, and the write reverted with ProofInvalid().

revert 0x7fcdd1f4
Why it holds

A verdict changes only when a new proof verifies.

01

Authorization by proof

recordResolution reverts unless the Pedersen–Schnorr opening verifies against the exact verdict tuple. Anyone can recompute the authorization, and no key holder can substitute for it.

02

Verdicts change only by proof

The record is append-only and hash-linked. A verdict can be superseded, but only by a new valid proof. Nothing is overwritten by an owner, a multisig, or a governance vote.

03

The history anchors to Bitcoin

The head of the append-only log is committed to Bitcoin. A silent rewrite of how a verdict reached its current state becomes detectable against an anchor no one controls.

Reproduced from public data only

Every claim on this page recomputes from public data.

A standalone verifier reads the contract over a public RPC, the evidence over HTTPS, and the block hashes it resolves against, then recomputes every claim on the page. Output, verbatim:

python3 verify.py
[PASS] H reproduced from seed 'MarkovianPedersenH/v1' matches on-chain verifier Hx/Hy
[PASS] entry0: responseHash == SHA256(canonical evidence)
[PASS] entry0: verdict reproducible from Base Sepolia block 43939918 (low byte 23 → odd → 0)
[PASS] entry0: Schnorr equation s_m·G + s_r·H == R + e·C HOLDS
[PASS] entry1: responseHash == SHA256(canonical evidence)
[PASS] entry1: verdict reproducible from Base Sepolia block 43939919 (low byte 66 → even → 100)
[PASS] entry1: Schnorr equation s_m·G + s_r·H == R + e·C HOLDS
[PASS] registry getValidationStatus == latest entry (verdict moved to newest)
[PASS] tampered (flip verdict, same proof): equation FAILS → why the write reverted
[PASS] on-chain revert selector == keccak(ProofInvalid())[:4] = 0x7fcdd1f4
RESULT: ALL CHECKS PASS — proof-gated verdicts are independently reproducible; no operator trusted.
Check it yourself

Reproduce everything on this page.

Reproduce in three steps

  • 1Clone the reference implementation and read the three contracts and verify.py.
  • 2Run the verifier. It pulls the verdict from the contract, the block hashes it resolves against, and rechecks the Schnorr equation for every entry.
  • 3Open the transactions on BaseScan. Watch the tampered write revert with ProofInvalid().
$ git clone github.com/MarkovianProtocol/erc8004-resolution-validator
$ python3 live-demo-v2/verify.py

The claim is a pure function of public data. Point to where it breaks.

Read the contracts →