A full-stack blockchain explorer built with Next.js and FastAPI. Explore blocks, transactions, and balances in a custom blockchain implementation featuring Proof-of-Work consensus and probabilistic mining rewards.
- Blockchain Explorer: Browse blocks, transactions, and chain history
- Proof-of-Work Mining: SHA-256 hashing with difficulty target (hash starting with "0000")
- Transaction System: Send and receive Coco tokens between addresses
- Ed25519 Authentication: Challenge-response login system with session management
- Cryptographic Signatures: Ed25519 signatures for transaction authorization (Stellar-compatible)
- Zero-Knowledge Proofs: Optional ZK proofs for transaction privacy
- Probabilistic Mining Rewards: Dynamic reward distribution system
- 55% chance: 0.1-0.5 Coco
- 25% chance: 0.6-0.7 Coco
- 10% chance: 0.8-0.9 Coco
- 10% chance: 1.0-1.4 Coco
- Balance Tracking: Real-time balance calculation for any address
- Dev User System: Pre-configured test accounts (cody, ezzy) with keypair management
- Modern UI: Built with Tailwind CSS and responsive design
- Next.js 16 - React framework with App Router
- React 18 - UI library
- TypeScript - Type safety
- Tailwind CSS - Styling
- FastAPI - High-performance Python web framework
- Pydantic - Data validation
- Uvicorn - ASGI server
- PyNaCl - Ed25519 cryptographic operations (Stellar-compatible)
- Custom Implementation - Proof-of-Work consensus
- SHA-256 - Cryptographic hashing
- Ed25519 - Digital signatures and authentication
- Transaction Pool - Pending transaction management
codychain/
โโโ blockchain/ # Python backend
โ โโโ __init__.py
โ โโโ blockchain.py # Core blockchain implementation
โ โโโ main.py # FastAPI application
โ โโโ models.py # Pydantic models
โ โโโ auth.py # Authentication system
โ โโโ crypto.py # Ed25519 cryptographic operations
โ โโโ zk_proof.py # Zero-knowledge proof implementation
โโโ src/ # Next.js frontend
โ โโโ app/ # App Router pages
โ โ โโโ explorer/ # Block explorer page
โ โ โโโ balances/ # Balance viewer
โ โ โโโ send/ # Send transactions
โ โ โโโ mine/ # Mining interface
โ โ โโโ block/ # Individual block view
โ โโโ components/ # React components
โ โ โโโ LoginModal.tsx # Authentication modal
โ โ โโโ Navbar.tsx # Navigation bar
โ โ โโโ BlockCard.tsx # Block display
โ โ โโโ TxCard.tsx # Transaction display
โ โโโ lib/ # API client utilities
โ โโโ api.ts # API client functions
โ โโโ auth.ts # Frontend auth utilities
โโโ scripts/ # Utility scripts
โ โโโ generate_keys.py # Generate Ed25519 keypairs
โโโ data/ # Data storage
โ โโโ blockchain.json # Blockchain persistence
โ โโโ keys/ # User keypairs (cody, ezzy)
โโโ docs/ # Documentation
โโโ package.json # Node.js dependencies
โโโ requirements.txt # Python dependencies
โโโ run.py # Backend server entry point
- Node.js 18+ and npm
- Python 3.8+
- pip (Python package manager)
-
Clone the repository
git clone https://github.com/yourusername/codychain.git cd codychain
-
Install Python dependencies
pip install -r requirements.txt -
Install Node.js dependencies
npm install
-
Generate cryptographic keypairs (for authentication)
python scripts/generate_keys.pyThis creates Ed25519 keypairs for users
codyandezzyindata/keys/.
-
Start the backend server (Terminal 1)
python run.py
The API will be available at
http://localhost:8000 -
Start the frontend development server (Terminal 2)
npm run dev
The app will be available at
http://localhost:3000 -
Open your browser Navigate to
http://localhost:3000to view the Codychain Explorer
Create a new transaction and add it to the pending pool. REQUIRES AUTHENTICATION - must provide valid session token in Authorization: Bearer <token> header.
The sender must match the logged-in user's address.
Request Headers:
Authorization: Bearer <session_token>
Request Body:
{
"sender": "A1B2",
"receiver": "C3D4",
"amount": 1.5,
"signature": "optional_ed25519_signature_hex",
"zk_proof": {},
"timestamp": "optional_iso_timestamp"
}Response:
{
"message": "Transaction added to pending pool",
"transaction": {
"sender": "A1B2",
"receiver": "C3D4",
"amount": 1.5,
"signature": "...",
"timestamp": "2024-01-01T12:00:00"
}
}Mine a new block with all pending transactions. REQUIRES AUTHENTICATION - must provide valid session token in Authorization: Bearer <token> header.
The miner address must belong to the logged-in user. If not provided, uses the logged-in user's address.
Request Headers:
Authorization: Bearer <session_token>
Query Parameters:
miner_address(optional): Address to receive mining reward (must match logged-in user)
Response:
{
"message": "Block mined successfully",
"block": {
"index": 1,
"timestamp": "2024-01-01T12:00:00",
"transactions": [...],
"previous_hash": "...",
"hash": "0000...",
"nonce": 12345
}
}Get the full blockchain.
Response:
{
"length": 5,
"chain": [...]
}Get the Coco token balance for a given address.
Response:
{
"address": "A1B2",
"balance": 10.5
}Get all pre-configured dev user accounts.
Response:
{
"users": {
"A1B2": "cody",
"C3D4": "ezzy"
}
}Get the address for a given username.
Response:
{
"username": "cody",
"address": "A1B2"
}Generate a challenge token for authentication. Username must be cody or ezzy.
Query Parameters:
username: Username (cody or ezzy)
Response:
{
"challenge_token": "hex_token",
"challenge_message": "codychain_login_cody_<random>"
}Login with a signed challenge. Sign the challenge_message from /auth/challenge using your private key.
Request Body:
{
"challenge_token": "hex_token_from_challenge",
"signature": "ed25519_signature_hex"
}Response:
{
"session_token": "hex_session_token",
"username": "cody"
}Logout by invalidating session token. REQUIRES AUTHENTICATION.
Request Headers:
Authorization: Bearer <session_token>
Response:
{
"message": "Logged out successfully"
}Verify if a session token is valid. REQUIRES AUTHENTICATION.
Request Headers:
Authorization: Bearer <session_token>
Response:
{
"username": "cody",
"authenticated": true
}When the backend is running, visit:
- Swagger UI:
http://localhost:8000/docs - ReDoc:
http://localhost:8000/redoc
- Navigate to any page that requires authentication (Send, Mine)
- A login modal will appear
- Select your username (cody or ezzy)
- The app will generate a challenge and sign it with your private key
- You'll be logged in with a session token (stored in localStorage)
Note: Private keys are stored in data/keys/{username}_private.pem. The frontend loads these keys to sign challenges and transactions.
- Log in first (see Authentication above)
- Navigate to the Send page
- Enter receiver address and amount (sender is automatically set to your address)
- Optionally sign the transaction with your private key
- Submit the transaction
- The transaction is added to the pending pool
- Log in first (see Authentication above)
- Navigate to the Mine page
- Click "Mine Block"
- The block is mined with all pending transactions
- Mining rewards are automatically sent to your address
- Navigate to the Explorer page
- Browse all blocks in the chain (latest first)
- Click on a block to view details
- Navigate to the Balances page
- Enter an address
- View the current Coco token balance
Frontend:
npm run build
npm startBackend: The backend runs with auto-reload in development. For production, use:
uvicorn blockchain.main:app --host 0.0.0.0 --port 8000Generate new Ed25519 keypairs for users:
python scripts/generate_keys.pyKeys are stored in data/keys/:
{username}_private.pem- Private key (hex format){username}_public.pem- Public key (hex format)
Security: Keep private keys secure. Never share or commit them to version control.
- Python: Follow PEP 8 conventions
- TypeScript/React: Use TypeScript strict mode, functional components with hooks
This is a development/educational blockchain implementation. It is not suitable for production use. Key limitations:
- Ed25519 signatures are implemented but transaction validation may not enforce them in all cases
- No network consensus (single node)
- Limited persistence (JSON file storage)
- Simplified Proof-of-Work (educational difficulty - hash starting with "0000")
- Private keys stored in plaintext files (for development only)
- Session tokens stored in localStorage (not httpOnly cookies)
- Zero-knowledge proofs are simplified/educational implementations
Important: Never commit private keys to version control. The data/keys/ directory should be in .gitignore.
This project is open source and available under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.
Cody Cordova(cocopuff)
- Music Producer/DJ
- Junior Developer building Stellar dApps
โญ If you find this project interesting, please give it a star!