A simple blockchain implementation in Python with a REST API built using Flask. This project demonstrates core blockchain concepts including proof-of-work, consensus algorithms, and distributed network communication.
Adapted from Learn Blockchains by Building One by Daniel Van Flymen
- Proof of Work: Mining algorithm that requires finding a hash with 4 leading zeros
- Transaction Management: Create and store transactions in blocks
- Distributed Network: Register multiple nodes and synchronize chains
- Consensus Algorithm: Resolves conflicts by adopting the longest valid chain
- REST API: Full HTTP interface for interacting with the blockchain
blockchain/
├── blockchain.py # Main blockchain implementation and Flask API
├── requirements.txt # Python dependencies
├── README.md # This file
└── .gitignore # Git ignore rules
- Python 3.7 or higher
- pip (Python package installer)
-
Clone the repository (if you haven't already):
git clone <your-repo-url> cd blockchain
-
Create a virtual environment:
# On macOS/Linux python3 -m venv venv # On Windows python -m venv venv
-
Activate the virtual environment:
# On macOS/Linux source venv/bin/activate # On Windows venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
Start a single blockchain node on the default port (5000):
python blockchain.pyOr specify a custom port:
python blockchain.py -p 5001To test the consensus algorithm and node registration, run multiple instances in separate terminal windows:
Terminal 1 - Node on port 5000:
python blockchain.py -p 5000Terminal 2 - Node on port 5001:
python blockchain.py -p 5001Mines a new block by running the proof-of-work algorithm.
Endpoint: GET /mine
Example (curl):
curl http://localhost:5000/mineExample (Postman):
- Method:
GET - URL:
http://localhost:5000/mine
Response:
{
"message": "New Block Forged",
"index": 2,
"transactions": [
{
"sender": "0",
"recipient": "node_identifier",
"amount": 1
}
],
"proof": 35293,
"previous_hash": "abc123..."
}Creates a new transaction to be included in the next mined block.
Endpoint: POST /transactions/new
Example (curl):
curl -X POST \
http://localhost:5000/transactions/new \
-H 'Content-Type: application/json' \
-d '{
"sender": "address1",
"recipient": "address2",
"amount": 5
}'Example (Postman):
- Method:
POST - URL:
http://localhost:5000/transactions/new - Headers:
Content-Type: application/json - Body (raw JSON):
{ "sender": "address1", "recipient": "address2", "amount": 5 }
Response:
{
"message": "Transaction will be added to Block 2"
}Returns the complete blockchain and its length.
Endpoint: GET /chain
Example (curl):
curl http://localhost:5000/chainExample (Postman):
- Method:
GET - URL:
http://localhost:5000/chain
Response:
{
"chain": [
{
"index": 1,
"timestamp": 1234567890.123,
"transactions": [],
"proof": 100,
"previous_hash": 1
},
{
"index": 2,
"timestamp": 1234567900.456,
"transactions": [...],
"proof": 35293,
"previous_hash": "abc123..."
}
],
"length": 2
}Registers one or more nodes in the network.
Endpoint: POST /nodes/register
Example (curl):
curl -X POST \
http://localhost:5000/nodes/register \
-H 'Content-Type: application/json' \
-d '{
"nodes": ["http://127.0.0.1:5001", "http://127.0.0.1:5002"]
}'Example (Postman):
- Method:
POST - URL:
http://localhost:5000/nodes/register - Headers:
Content-Type: application/json - Body (raw JSON):
{ "nodes": ["http://127.0.0.1:5001", "http://127.0.0.1:5002"] }
Response:
{
"message": "New nodes have been added",
"total_nodes": ["127.0.0.1:5001", "127.0.0.1:5002"]
}Implements the consensus algorithm by checking all registered nodes and replacing the chain with the longest valid chain in the network.
Endpoint: GET /nodes/resolve
Example (curl):
curl http://localhost:5000/nodes/resolveExample (Postman):
- Method:
GET - URL:
http://localhost:5000/nodes/resolve
Response (chain replaced):
{
"message": "Our chain was replaced",
"new_chain": [...]
}Response (chain authoritative):
{
"message": "Our chain is authoritative",
"chain": [...]
}Follow these steps to test the consensus algorithm:
-
Start two nodes:
# Terminal 1 python blockchain.py -p 5000 # Terminal 2 python blockchain.py -p 5001
-
Register node 5001 with node 5000:
curl -X POST \ http://localhost:5000/nodes/register \ -H 'Content-Type: application/json' \ -d '{"nodes": ["http://127.0.0.1:5001"]}'
-
Mine some blocks on node 5001 to make its chain longer:
curl http://localhost:5001/mine curl http://localhost:5001/mine curl http://localhost:5001/mine
-
Check the chain on node 5000:
curl http://localhost:5000/chain
-
Trigger consensus on node 5000:
curl http://localhost:5000/nodes/resolve
-
Verify that node 5000's chain was replaced:
curl http://localhost:5000/chain
Each block contains:
index: Position in the chaintimestamp: When the block was createdtransactions: List of transactions in the blockproof: The proof-of-work valueprevious_hash: Hash of the previous block
The mining algorithm finds a number (proof) such that when combined with the previous block's proof and hashed with SHA-256, the resulting hash contains 4 leading zeros. This computational work secures the blockchain.
When conflicts arise (different nodes have different chains), the network resolves them by:
- Requesting chains from all registered nodes
- Validating each chain
- Adopting the longest valid chain
This ensures all nodes eventually agree on the same blockchain state.
- Flask 2.0.3: Web framework for the REST API
- requests: HTTP library for node-to-node communication
- Werkzeug: WSGI utility library
- See requirements.txt for complete list
To deactivate the virtual environment when done:
deactivateThis is an educational project demonstrating blockchain concepts.
- Blockchain class - Core blockchain implementation
- Flask routes - API endpoint definitions