You anchored a contract to the blockchain last month. Today you need to verify it hasn't been modified. The file looks the same, but looks can be deceiving. A single changed byte produces a completely different SHA-256 hash. ProofAnchor anchors SHA-256 hashes of files to the Polygon blockchain, creating an immutable record you can check against.
The tamper detection mechanism
When you anchor a file, you're creating a permanent fingerprint on the blockchain. The original file's SHA-256 hash gets recorded in the proof structure. To detect tampering later, you hash the current file and compare it to what's recorded in the proof. Any difference means the file changed since anchoring.
This works because SHA-256 is deterministic but avalanche-sensitive. The same file always produces the same hash. Change one bit, and you get a completely different 64-character fingerprint. There's no way to modify a file and keep the same hash.
pip install verify-proof
The verify-proof package handles both sides: hashing files and validating them against existing proofs.
Basic tamper check in Python
Here's a script that compares a file's current hash to its anchored proof:
from verify_proof import hash_file, load_proof, verify_proof
import sys
def check_tampering(file_path, proof_path):
"""Check if a file has been tampered with since anchoring."""
# Hash the current file
current_hash = hash_file(file_path)
# Load the anchored proof
proof = load_proof(proof_path)
# Compare current hash to anchored hash
result = verify_proof(current_hash, proof)
if result['verified']:
print(f"✓ File intact: {file_path}")
print(f" Hash matches anchored proof from {result['anchored_at']}")
print(f" Blockchain: {result['blockchain']}")
print(f" Transaction: {result['tx_id']}")
else:
print(f"⚠ File modified: {file_path}")
print(f" Current hash: {result['file_hash']}")
print(f" Anchored hash: {result['proof_hash']}")
print(f" Error: {result.get('error', 'Hash mismatch')}")
return result['verified']
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python tamper_check.py <file> <proof.json>")
sys.exit(1)
file_path = sys.argv[1]
proof_path = sys.argv[2]
is_intact = check_tampering(file_path, proof_path)
sys.exit(0 if is_intact else 1)
Run it with your file and its corresponding proof:
python tamper_check.py contract.pdf contract.pdf.proof.json
The script exits with code 0 if the file is intact, 1 if it's been modified. Perfect for CI pipelines or automated monitoring.
Directory-wide tamper scanning
Real workflows involve multiple files. Here's an enhanced version that scans entire directories for anchored files and flags any changes:
from verify_proof import hash_file, load_proof, verify_proof
import os
import glob
import json
from pathlib import Path
def scan_directory_for_tampering(directory):
"""Scan a directory for .proof.json files and check their corresponding files."""
intact_count = 0
tampered_count = 0
missing_count = 0
# Find all proof files in the directory
proof_pattern = os.path.join(directory, "**/*.proof.json")
proof_files = glob.glob(proof_pattern, recursive=True)
if not proof_files:
print(f"No .proof.json files found in {directory}")
return
print(f"Scanning {len(proof_files)} anchored files...")
print()
for proof_path in proof_files:
# Derive the original file path from the proof filename
file_path = proof_path.replace('.proof.json', '')
if not os.path.exists(file_path):
print(f"⚠ Missing file: {file_path}")
missing_count += 1
continue
# Check for tampering
try:
current_hash = hash_file(file_path)
proof = load_proof(proof_path)
result = verify_proof(current_hash, proof)
if result['verified']:
print(f"✓ {os.path.basename(file_path)}")
intact_count += 1
else:
print(f"⚠ MODIFIED: {file_path}")
print(f" Expected: {result['proof_hash'][:16]}...")
print(f" Current: {result['file_hash'][:16]}...")
tampered_count += 1
except Exception as e:
print(f"✗ Error checking {file_path}: {str(e)}")
tampered_count += 1
print()
print(f"Results: {intact_count} intact, {tampered_count} modified, {missing_count} missing")
return tampered_count == 0 and missing_count == 0
if __name__ == "__main__":
import sys
directory = sys.argv[1] if len(sys.argv) > 1 else "."
all_good = scan_directory_for_tampering(directory)
sys.exit(0 if all_good else 1)
This scanner assumes your proof files follow the .proof.json naming convention (contract.pdf → contract.pdf.proof.json). It recursively searches the directory, checks each anchored file against its proof, and reports a summary.
The hash comparison is immediate and offline. You're not making blockchain calls to verify the proof structure itself. You're just comparing the current file's fingerprint to what was recorded when you anchored it. For full verification that the proof exists on-chain, you'd need to query a Polygon explorer API separately.
What's next
Tamper detection is one piece of file integrity monitoring. You might extend this with file watching (detect changes in real-time), automated re-anchoring (timestamp new versions), or integration with backup systems. The verify-proof package handles the hash comparison mechanics. Check the source on GitHub for additional examples and the full API reference.
Top comments (0)