Decentralized Document Notary
- Contract
- Solidity
- Frontend
- React
- Backend
- Node.js · Supabase · Cloudflare R2
Overview
Blockchain-based document notarization app (Solidity, React, Node.js, Supabase, Cloudflare R2) — deployed on Sepolia, Render & Vercel.
Problem
Proving a document existed in a specific, unaltered state at a specific time — without trusting a single company's database not to quietly change that record later. A timestamp in a normal database is only as trustworthy as whoever controls that database.
Architecture
The document itself never touches the blockchain. The backend hashes the uploaded file and writes only that hash to a smart contract on Sepolia. The actual file lives in Cloudflare R2; Supabase manages user accounts and the mapping between a user, a file, and its on-chain hash. The chain's only job is answering one question: did a hash matching this exact document exist at this block?
Technical Decisions
- Splitting the system across three platforms deliberately — Vercel for the frontend, Render for backend services, Sepolia for the actual notarization logic — kept 'serve the UI,' 'handle app logic,' and 'provide immutability' as separate concerns, easier to reason about and swap out independently.
- Hashing the upload in one place, on the backend, so a single code path produces the hash that goes on-chain, while the Verify page hashes files in the browser, so anyone can check a document without uploading it.
Challenges
The interesting engineering problem wasn't the smart contract itself — verifying a hash match is genuinely simple Solidity. The real work was everything around it: keeping the actual file, the hash, and the on-chain record correctly linked across three different platforms without any single point where the record could be quietly altered.
What I Learned
A public blockchain isn't free — gas costs money (even fake testnet money has real friction) and a public chain means the hash is technically visible to anyone, even though the document isn't. For most use cases a signed database record with an audit log is genuinely fine. This project exists for the narrower slice of cases where that isn't good enough, and building it was a good way to actually feel that trade-off rather than just read about it.
Links
Related Reading & Listening
- Why I built a blockchain notary instead of another CRUD app →
- Defensive Engineering of the FundMe Contract: Reentrancy, Access Control, and Price Feed Safety (podcast) →
- Foundry vs Hardhat: Which Ethereum Development Framework Should You Learn? (podcast) →
- How Foundry Testing Works: Forge, Anvil and Smart Contract Testing Explained (podcast) →
Need something similar?
Building or debugging a Solidity project?
Tell me about the contract or the problem you're running into.