About the project

The problem

During a hackathon, I kept thinking about how easy it is to lose trust in an image once it starts getting shared. A photo gets forwarded, screenshot, edited, cropped, or re saved, and after a while nobody can confidently say which version is the original. Even if you trust the person, you cannot trust the file.

I wanted a tiny, practical tool that does one thing well which is creating a stable fingerprint for an image, then let you check any later copy against that fingerprint.

What Proof Butler does

Proof Butler is a Flutter app powered by a Serverpod backend that creates and verifies tamper checks for images.

It has three flows:

Create Proof

  • Pick an image from your device
  • Enter a required title (so you can recognize it later)
  • The app computes a SHA-256 hash locally from the image bytes
  • The app generates a small thumbnail preview
  • It saves a proof record to the backend:
    • title
    • SHA-256 hash
    • createdAt timestamp
    • thumbnail bytes
  • You can copy the Proof ID and details for sharing

My Proofs

  • Lists saved proofs with thumbnail + title
  • Shows ID, createdAt, and a short hash preview
  • One tap copy to share proof details

Verify Proof

  • Select a stored proof record
  • Pick an image file you want to check
  • The app computes SHA-256 for that file and asks the backend to compare it
  • Result is clear:
    • MATCH (same bytes)
    • MISMATCH (file differs)

This is not an image similarity detector but a strict integrity check. If the bytes changed even slightly, the hash changes.

How I built it

  • Flutter (Material 3) for the UI
  • file_picker to pick images
  • crypto to compute SHA-256 on device
  • image package to decode and create a compact JPEG thumbnail
  • Serverpod backend with simple endpoints:
    • createEvidenceRecord (save title, hash, thumbnail)
    • listEvidenceRecords (load proofs)
    • verifyEvidence (compare stored hash with computed hash)
  • PostgreSQL via Serverpod for persistence

The phone computes the hash and the server stores and compares.

Challenges

  • Async mistakes early on (missing await caused UI to update before the server response came back)
  • Handling bytes cleanly across PlatformFile, Uint8List, and ByteData

What I am proud of

  • End to end workflow that is easy to demo: create, list, verify match, verify mismatch
  • Titles + thumbnails make old records recognizable without storing the original image
  • Serverpod made it fast to go from models to a working typed client

What’s next

  • Verify by Proof ID (paste or scan) so someone can verify without browsing your list
  • Share links or QR codes for Proof IDs
  • User accounts or access controls if this becomes multi user
  • Optional metadata like tags or capture context

Built With

+ 8 more
Share this project:

Updates