Inspiration

Every important digital record — a signed contract, a release build, a thesis, an approval — eventually lives in somebody else's database. When it matters months later, you're asked to trust that database: that nobody edited history, backdated a row, or quietly went offline.

We wanted proof that doesn't depend on trust. The key insight: you don't need to put data on a blockchain to prove things about it. A SHA-256 fingerprint is enough — one-way, tamper-evident, and reproducible by anyone holding the original.

What it does

ProofFlow turns any file or text record into an independently verifiable blockchain proof in four steps: Create → Hash → Anchor → Verify.

  • Hashing happens locally in your browser — the file never leaves your device.
  • Only the 32-byte fingerprint (+ a public label, your wallet, a timestamp) is anchored via a minimal Solidity contract.
  • Anyone can open a shareable /verify/[proofId] link, re-hash the original, and get a giant VERIFIED ✓ — or, if even one byte changed, NOT VERIFIED ✕.
  • The demo moment: anchor release-v1.txt, verify it, flip one character, watch verification fail.

How we built it

  • Frontend: Next.js 14 + TypeScript + Tailwind, with wagmi/viem for wallet + contract calls (injected connector, no API keys), Framer Motion micro-interactions, Lucide icons.
  • Hashing: WebCrypto SHA-256, streamed in 4 MB chunks with a progress bar; a pure-TS fallback covered by known-answer tests.
  • Contract: ProofFlow.sol — a single mapping keyed by dataHash, custom errors (ProofAlreadyExists, EmptyHash), ProofCreated event, metadata capped for gas. Tested with Hardhat (7 tests), deployed to a local node and Sepolia-ready via env config.
  • Verification honesty: the app distinguishes transaction confirmed from data verified, labels every demo record DEMO DATA, and never fakes chain state.

Challenges we ran into

  • wagmi's connector barrel dragged in Coinbase's optional x402 modules and broke the production build — fixed by stubbing unused optionals in webpack config.
  • SSR prerendering crashed on window access in a theme hook — fixed with mount-synced state.
  • npm peer conflicts between Hardhat 2 and the viem plugin — solved with a committed .npmrc so clean installs (including Vercel's) just work.
  • Keeping the demo honest: it was tempting to simulate confirmations, but every status in the UI reflects real wallet/chain state or is explicitly labeled demo.

What we learned

That the hardest part of a Web3 product isn't the chain — it's the honesty layer: input validation, precise language ("confirmed" ≠ "verified"), graceful RPC/wallet failure states, and a UX good enough that a judge gets it in 30 seconds.

What's next

EIP-712 signed attestations, L2 deployment, Merkle-root batch anchoring for CI pipelines, and an encrypted off-chain vault with hash-linked retrieval.

Built With

  • ethereum
  • framer-motion
  • hardhat
  • ipfs-concepts
  • metamask
  • nextjs
  • sepolia
  • sha-256
  • solidity
  • tailwind-css
  • typescript
  • vercel
  • viem
  • wagmi
  • webcrypto
Share this project:

Updates

Submission history