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 bydataHash, custom errors (ProofAlreadyExists,EmptyHash),ProofCreatedevent, 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
windowaccess in a theme hook — fixed with mount-synced state. - npm peer conflicts between Hardhat 2 and the viem plugin — solved with a committed
.npmrcso 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
Log in or sign up for Devpost to join the conversation.