A perfect beginner-friendly blockchain project for school/college
π Project Overview
Create a web application that allows users to prove they had a document at a specific point in time without revealing the document's contents. This is like a digital notary service on the blockchain.
π― Why This Project?
- Teaches core blockchain concepts: Hashing, transactions, immutability
- No smart contracts needed: Can work with simple blockchain interactions
- Practical real-world use: Useful for copyright, patents, legal documents
- Visually demonstrable: Easy to show in presentations
π οΈ Tech Stack Suggestions
| Component | Technology Options |
|---|---|
| Blockchain | Ethereum (testnet), Polygon, Binance Smart Chain testnet |
| Smart Contracts | None required (can use blockchain's native transactions) |
| Backend | Node.js, Python (Flask), or PHP |
| Frontend | HTML/CSS, JavaScript, React (optional) |
| Storage | IPFS (optional for file storage) |
| Wallet Connection | MetaMask, Web3.js, or Ethers.js |
π Step-by-Step Implementation Guide
Step 1: Understanding the Core Concept
When you timestamp a document:
- User selects a file
- App calculates the file's cryptographic hash (unique fingerprint)
- Hash is sent to the blockchain in a transaction
- Blockchain records the time permanently
- Later, anyone can verify by comparing hashes
Step 2: Basic Architecture
User Uploads File β Calculate SHA-256 Hash β Send Hash to Blockchain (small transaction) β Get Transaction Receipt with Timestamp β Store Receipt Hash for Verification
Step 3: Code Structure
A. Hash Generator (Python Example)
import hashlib
import datetime
def calculate_file_hash(filename):
"""Calculate SHA-256 hash of a file"""
sha256_hash = hashlib.sha256()
with open(filename, "rb") as f:
# Read file in chunks to handle large files
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
# Example usage
file_hash = calculate_file_hash("my_document.pdf")
print(f"Document Fingerprint: {file_hash}")
print(f"Timestamp: {datetime.datetime.now()}")
B. Simple Blockchain Interaction (Using Web3.js)
// Connect to Ethereum testnet
const Web3 = require('web3');
const web3 = new Web3('https://goerli.infura.io/v3/YOUR_PROJECT_ID');
async function timestampOnBlockchain(documentHash) {
// Get user account (via MetaMask)
const accounts = await web3.eth.requestAccounts();
const fromAddress = accounts[0];
// Create a simple transaction with the hash in data field
const tx = {
from: fromAddress,
to: '0x0000000000000000000000000000000000000000', // Null address
data: web3.utils.toHex(documentHash),
gas: 21000
};
// Send transaction
const receipt = await web3.eth.sendTransaction(tx);
console.log('Transaction Hash:', receipt.transactionHash);
console.log('Block Timestamp:', receipt.timestamp);
return receipt;
}
C. Verification Function
async function verifyDocument(originalFile, transactionHash) {
// 1. Calculate hash of current file
const currentHash = calculateFileHash(originalFile);
// 2. Get the original hash from blockchain
const tx = await web3.eth.getTransaction(transactionHash);
const originalHash = web3.utils.hexToAscii(tx.input);
// 3. Compare
if (currentHash === originalHash) {
return {
verified: true,
message: "Document is authentic!",
timestamp: tx.timestamp
};
} else {
return {
verified: false,
message: "Document has been modified!"
};
}
}
Step 4: Simple Web Interface
HTML (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Blockchain Timestamp Service</title>
<style>
body { font-family: Arial; max-width: 600px; margin: 50px auto; }
.box { border: 2px solid #333; padding: 20px; margin: 20px 0; border-radius: 10px; }
button { background: #4CAF50; color: white; padding: 10px 20px; border: none; cursor: pointer; }
#result { margin-top: 20px; padding: 10px; background: #f0f0f0; }
</style>
</head>
<body>
<h1>π Blockchain Timestamp Service</h1>
<p>Prove you had a document at a specific time - without revealing it!</p>
<div class="box">
<h2>1. Timestamp a Document</h2>
<input type="file" id="fileInput">
<button onclick="timestampDocument()">Stamp on Blockchain</button>
</div>
<div class="box">
<h2>2. Verify a Document</h2>
<input type="file" id="verifyFile">
<input type="text" id="txHash" placeholder="Enter transaction hash">
<button onclick="verifyDocument()">Verify Authenticity</button>
</div>
<div id="result"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/web3.min.js"></script>
<script src="app.js"></script>
</body>
</html>
JavaScript (app.js):
let web3;
if (window.ethereum) {
web3 = new Web3(window.ethereum);
}
async function timestampDocument() {
const file = document.getElementById('fileInput').files[0];
if (!file) {
alert('Please select a file');
return;
}
// Read file and calculate hash
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
document.getElementById('result').innerHTML = 'β³ Sending to blockchain...';
try {
// Request account access
await window.ethereum.request({ method: 'eth_requestAccounts' });
const accounts = await web3.eth.getAccounts();
// Send transaction
const tx = await web3.eth.sendTransaction({
from: accounts[0],
to: '0x0000000000000000000000000000000000000000',
data: web3.utils.toHex(hashHex),
gas: 21000
});
document.getElementById('result').innerHTML = `
β
Document stamped successfully!<br>
Transaction Hash: ${tx.transactionHash}<br>
Block: ${tx.blockNumber}<br>
Timestamp: ${new Date().toLocaleString()}
`;
} catch (error) {
document.getElementById('result').innerHTML = 'β Error: ' + error.message;
}
}
async function verifyDocument() {
const file = document.getElementById('verifyFile').files[0];
const txHash = document.getElementById('txHash').value;
if (!file || !txHash) {
alert('Please select file and enter transaction hash');
return;
}
// Calculate current file hash
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const currentHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
// Get original hash from blockchain
const tx = await web3.eth.getTransaction(txHash);
const originalHash = web3.utils.hexToAscii(tx.input).replace(/\0/g, '');
if (currentHash === originalHash) {
document.getElementById('result').innerHTML = `
β
VERIFIED: Document is authentic!<br>
Original timestamp: ${new Date(tx.timestamp * 1000).toLocaleString()}
`;
} else {
document.getElementById('result').innerHTML = `
β FAILED: Document has been modified!
`;
}
}
π Learning Outcomes
By building this project, you'll learn:
- Cryptographic Hashing: How SHA-256 creates unique fingerprints
- Blockchain Transactions: How data is stored permanently
- Web3 Integration: Connecting web apps to blockchain
- Immutability: Why blockchain data can't be changed
- Gas and Fees: Understanding transaction costs (even on testnets)
π§ Simplification Options
- Use a testnet faucet to get free test ETH
- Skip MetaMask by using a centralized API (less secure but simpler)
- Use Python only and store hashes in a simple blockchain simulation
- Focus on theory and create a working prototype without real blockchain
π Presentation Tips
- Show before/after: Modify a file and demonstrate failed verification
- Explain the "hash" concept with a simple analogy (fingerprint)
- Show the blockchain explorer to prove the timestamp exists
- Discuss real-world applications: Copyright, patents, legal evidence
π Possible Extensions
- Add IPFS storage for the actual files
- Create a receipt PDF with QR code
- Build a mobile app version
- Add email notifications
- Create a public verification page
β οΈ Common Pitfalls to Avoid
- Don't store actual files on blockchain (too expensive)
- Always use testnets first (real ETH costs money)
- Handle large files properly (stream reading)
- Clear error messages for users without MetaMask
π‘ Real-World Example
Imagine you wrote a song and want to prove you wrote it first:
- Upload your MP3 file
- Get a timestamp proof on blockchain
- Later if someone claims they wrote it, you can prove your file existed earlier
Next Steps:
- Set up MetaMask
- Get free test ETH from a faucet
- Start coding the hash calculator
- Test with small text files first
Would you like me to elaborate on any specific part or provide the complete code for a different tech stack (like Python-only version)?