Proof & Anchoring

Every Verification produces a Proof — the mathematical receipt that lets anyone (not just SourceVerify) verify the result independently.

The proof tuple

(contentHash, CID, verdict, modelVersion, timestamp)
Field Source Purpose
contentHash SHA-256 of the artifact bytes Lets a third party re-compute and compare.
CID IPFS Content Identifier of the verification record JSON Pins the full evidence (model outputs, metadata) on a decentralized store.
verdict authentic / manipulated / synthetic / unknown The classification result.
modelVersion Semver string of the inference model used Lets future audits reproduce the exact pipeline.
timestamp UTC unix timestamp at anchor time Block-anchored, not just server-side.

On-chain anchor

The tuple is anchored on an EVM L2 by calling the Anchor smart contract via viem. After anchoring, the Proof row gets txHash and blockNumber.

import { createPublicClient, http } from 'viem'

const client = createPublicClient({
  transport: http(process.env.CHAIN_RPC_URL),
})

const tx = await client.getTransaction({ hash: proof.txHash })

IPFS pin

The verification record JSON (model outputs, intermediate features, metadata) is uploaded to IPFS via Pinata. The CID lives on Verification.ipfsCid and Proof.ipfsCid.

Fetch the record by CID through any IPFS gateway:

https://ipfs.io/ipfs/<cid>

Independent verification

Anyone can verify a SourceVerify proof without trusting our servers:

  1. Take the artifact bytes, compute SHA-256 → contentHash'.
  2. Query the on-chain Anchor contract with contentHash'. If a tuple exists, you've matched the registered Verification.
  3. Pull the IPFS CID from the on-chain tuple, fetch the record, and inspect the verdict + model version.
  4. Compare timestamp and blockNumber against your acceptable window.

That's the core "mathematical certainty, not human opinion" property: the chain doesn't lie, and the hash either matches or it doesn't.