Store SHA-256 file hashes on the Stellar blockchain. Prove any file existed at a specific point in time — immutably.
proof-of-existence/
├── contracts/
│ └── proof-of-existence/
│ ├── Cargo.toml # Rust dependencies (soroban-sdk)
│ └── src/
│ └── lib.rs # Soroban smart contract
├── frontend/
│ ├── index.html # Main UI
│ ├── styles.css # Premium dark theme
│ └── app.js # SHA-256 hashing + Stellar SDK integration
└── README.md
-
Rust + Soroban target
# Install Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Add WASM target rustup target add wasm32-unknown-unknown
-
Stellar CLI
# Install via cargo cargo install stellar-cli --locked # Or on macOS brew install stellar-cli
cd contracts/proof-of-existence
# Build to WASM
stellar contract buildThe compiled WASM will be at:
target/wasm32-unknown-unknown/release/proof_of_existence.wasm
# Generate a new identity for testnet
stellar keys generate --global deployer --network testnet
# Fund it from friendbot
stellar keys fund deployer --network testnet
# Verify the address
stellar keys address deployer# Deploy the WASM to testnet
stellar contract deploy \
--wasm target/wasm32-unknown-unknown/release/proof_of_existence.wasm \
--source deployer \
--network testnetSave the returned Contract ID! You'll need it for the frontend (e.g., CABC...XYZ).
# Store a hash (32 bytes hex)
stellar contract invoke \
--id CCNUSX5OS43RFKZDMO4KQJASQS55ZPH3DX5BLWRUMUHUDPVB2AGO66DM \
--source deployer \
--network testnet \
-- \
store_hash \
--registrar $(stellar keys address deployer) \
--hash 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20
# Verify the hash
stellar contract invoke \
--id CCNUSX5OS43RFKZDMO4KQJASQS55ZPH3DX5BLWRUMUHUDPVB2AGO66DM \
--source deployer \
--network testnet \
-- \
verify_hash \
--hash 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20cd frontend
# Option 1: Python
python -m http.server 8080
# Option 2: Node.js
npx serve .
# Option 3: VS Code Live Server extensionThen open http://localhost:8080 in your browser.
- Open the Network Configuration panel
- Enter your Contract ID (from deploy step)
- Enter your Testnet Secret Key (
S...) - RPC URL and passphrase are pre-filled for testnet
- Stores a SHA-256 hash on-chain
- Requires
registrarauthorization - Panics if hash is already registered (no duplicates)
- Records: registrar address + ledger timestamp
- Returns
Some(HashRecord)if the hash exists - Returns
Noneif not found - Read-only — no signing required for simulation
| Field | Type | Description |
|---|---|---|
registrar |
Address |
The account that registered the hash |
timestamp |
u64 |
Ledger timestamp at registration |
| Decision | Rationale |
|---|---|
BytesN<32> as key |
SHA-256 produces exactly 32 bytes — perfect fit |
| Persistent storage | Data should survive across ledgers |
| TTL extension (~30 days) | Prevents accidental archival |
| Duplicate rejection | Ensures first-registrant wins |
| Read-only verify via simulation | No gas cost for verification queries |
cd contracts/proof-of-existence
cargo testExpected output:
test test::test_store_and_verify ... ok
test test::test_duplicate_hash_rejected ... ok
- Never use mainnet keys in the frontend — this is a testnet demo
- Files never leave the browser — only the SHA-256 hash is transmitted
- For production, integrate a wallet like Freighter instead of raw secret keys
- Smart Contract: Rust + Soroban SDK
- Frontend: HTML + CSS + Vanilla JS
- Hashing: Web Crypto API (SHA-256)
- Blockchain: Stellar Network (Soroban)
- SDK: @stellar/stellar-sdk (CDN)