CIA/e-voting-system/backend/init_blockchain.py
Alexis Bruneteau 1a42b4d83b feat: Implement blockchain-based election storage with cryptographic security
Elections are now immutably recorded to blockchain with:
- SHA-256 hash chain for integrity (prevents tampering)
- RSA-PSS signatures for authentication
- Candidate verification via SHA-256 hash
- Tamper detection on every verification
- Complete audit trail

Changes:
- backend/blockchain_elections.py: Core blockchain implementation (ElectionBlock, ElectionsBlockchain)
- backend/init_blockchain.py: Startup initialization to sync existing elections
- backend/services.py: ElectionService.create_election() with automatic blockchain recording
- backend/main.py: Added blockchain initialization on startup
- backend/routes/elections.py: Already had /api/elections/blockchain and /{id}/blockchain-verify endpoints
- test_blockchain_election.py: Comprehensive test suite for blockchain integration
- BLOCKCHAIN_ELECTION_INTEGRATION.md: Full technical documentation
- BLOCKCHAIN_QUICK_START.md: Quick reference guide
- BLOCKCHAIN_IMPLEMENTATION_SUMMARY.md: Implementation summary

API Endpoints:
- GET /api/elections/blockchain - Returns complete blockchain
- GET /api/elections/{id}/blockchain-verify - Verifies election integrity

Test:
  python3 test_blockchain_election.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 03:01:11 +01:00

77 lines
2.7 KiB
Python

"""
Initialize blockchain with existing elections from database.
This module ensures that when the backend starts, all elections in the database
are recorded to the blockchain if they aren't already.
"""
from sqlalchemy.orm import Session
from . import models
from .blockchain_elections import elections_blockchain, record_election_to_blockchain
from datetime import datetime
import json
def initialize_elections_blockchain(db: Session) -> None:
"""
Initialize the elections blockchain with all elections from database.
Called on backend startup to ensure all elections are immutably recorded.
Uses the elections_blockchain.blocks to check if an election is already recorded.
Args:
db: Database session
"""
# Get all elections from database
elections = db.query(models.Election).all()
if not elections:
print("No elections to record to blockchain")
return
# Check which elections are already on blockchain
existing_election_ids = {block.election_id for block in elections_blockchain.blocks}
# Record each election that isn't already on blockchain
for election in elections:
if election.id in existing_election_ids:
print(f"Election {election.id} already on blockchain, skipping")
continue
try:
# Get candidates for this election
candidates = db.query(models.Candidate).filter(
models.Candidate.election_id == election.id
).all()
candidates_data = [
{
"id": c.id,
"name": c.name,
"description": c.description or "",
"order": c.order or 0
}
for c in candidates
]
# Record to blockchain
record_election_to_blockchain(
election_id=election.id,
election_name=election.name,
election_description=election.description or "",
candidates=candidates_data,
start_date=election.start_date.isoformat(),
end_date=election.end_date.isoformat(),
is_active=election.is_active,
creator_id=0 # Database creation, no specific admin
)
print(f"✓ Recorded election {election.id} ({election.name}) to blockchain")
except Exception as e:
print(f"✗ Failed to record election {election.id} to blockchain: {e}")
# Verify blockchain integrity
if elections_blockchain.verify_chain_integrity():
print(f"✓ Blockchain integrity verified - {len(elections_blockchain.blocks)} blocks")
else:
print("✗ Blockchain integrity check failed!")