Yosh Zcash fam, it’s Abdel again from StarkWare.
So a few weeks ago I stumbled upon this tweet from Zooko:
“What I want for Christmas: every time I take a screenshot, take a photo, or make a git commit, it gets timestamped into the Zcash blockchain and proof-of-time embedded into the shot/photo/commit.” — @zooko
And I thought… ok why not? Let’s build it.
What is zOpenTimestamps?
zOpenTimestamps is a Zcash blockchain timestamping tool inspired by OpenTimestamps on Bitcoin. It lets you create cryptographic proof that some data existed at a specific point in time by anchoring a hash to the Zcash blockchain.
Bitcoin whitepaper timestamped on Zcash testnet, because why not.
How it works
The flow is pretty simple:
- Hash your file (SHA-256)
- Encode that hash into a shielded transaction memo field
- Broadcast a self-send transaction (shielded, so privacy preserved)
- Confirm — once mined, the block timestamp is your proof
- Save a
.zotsproof file containing the attestation
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 1. Hash │───▶│ 2. Memo │───▶│ 3. Broadcast│───▶│ 4. Confirm │
│ │ │ │ │ │ │ │
│ SHA-256 of │ │ Encode hash │ │ Self-send │ │ Block time │
│ your file │ │ in tx memo │ │ shielded tx │ │ = timestamp │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
The key difference from OpenTimestamps on Bitcoin: the memo is encrypted. Only someone with the viewing keys can decrypt it and verify the timestamp.
The privacy angle
This is actually pretty interesting and something you can’t really do with Bitcoin.
With OpenTimestamps on Bitcoin, the hash is visible on-chain. Everyone can see what was timestamped. With zOpenTimestamps using shielded transactions, only the stamper (or anyone with the viewing keys) can verify the proof.
In the current implementation I reused the wallet’s viewing keys for convenience, but you could imagine a different setup where you generate dedicated viewing keys per timestamp or share them selectively. The point is: you can timestamp while preserving privacy.
Trade-offs vs OpenTimestamps
OpenTimestamps has a clever aggregation model — they batch many timestamps into a Merkle tree and settle the root on-chain periodically. One Bitcoin transaction can anchor thousands of timestamps.
zOpenTimestamps (in this MVP) creates one transaction per timestamp. No aggregation. That’s obviously less efficient.
But technically, you could still build an aggregation layer on top — collect individual proofs, build a Merkle tree, settle the root in an encrypted memo. The individual proofs wouldn’t need to go on-chain. Just pointing out the architecture allows for it, I just didn’t build that part.
Embeddable compact format
Per Zooko’s wish, I created a compact encoding format so you can actually embed timestamp proofs into files:
zots1o2d2ZXJzaW9uAWRoYXNoeEBhYmNkZWYxMjM0NTY3ODkw...
It’s CBOR + Base64url with a zots1 prefix. Small enough for:
- EXIF/XMP metadata in photos and screenshots
- Git commit message trailers
- QR codes
- Document metadata
Example git commit:
feat: implement new feature
Timestamp: zots1o2d2ZXJzaW9uAWRoYXNoeEBhYmNkZWYxMjM0NTY3ODkw...
Use cases
Some things this could be useful for:
- Proof of creation — prove you had a document/photo/code at a certain time
- IP protection — timestamped evidence of prior art
- Journalism — verifiable photo/video capture times
- Legal — notarization without a notary
- Git commits — cryptographic proof of when code existed
- Private timestamping — when you need proof but don’t want the world to know what you’re proving
Try it (testnet only!)
Warning: This is experimental, unaudited code. Testnet only. Do not use with real funds.
git clone https://github.com/AbdelStark/zopentimestamps
cd zopentimestamps
cargo build --release
# Set up your seed phrase and get testnet ZEC from faucet
# https://faucet.zecpages.com/
./target/release/zots wallet sync
./target/release/zots stamp document.pdf
./target/release/zots verify document.pdf.zots
There’s also a TUI if you prefer interactive:
./target/release/zots tui
What’s next?
This was a small project for fun. Some ideas if anyone wants to contribute:
- Aggregation layer (Merkle tree batching)
- Watcher wallet mode (verify without spending keys)
- Browser extension for screenshot timestamping
- Git hook for automatic commit timestamping
- Mobile app integration
Or just use it, break it, tell me what’s wrong.
Feedback welcome. And Zooko — partial Christmas wish fulfilled? ![]()
— Abdel



