Let’s create a simplified Python demo to illustrate how a private key generates a public key, how that public key is hashed into an address, and how a transaction might be simulated in a blockchain-like system. For simplicity, we’ll use a very short private key (“12345”) and simplified cryptographic functions (not real-world secure ones like ECDSA, but enough to show the concept). We’ll also simulate a “worker” recording the transaction.
Notes:
- In real blockchains (e.g., Bitcoin), private keys are large random numbers, public keys are generated using elliptic curve cryptography (ECC), and addresses are hashes (e.g., SHA-256 + RIPEMD-160). Here, we’ll use basic math and hashing for clarity.
- The “worker” will be a simple function simulating a blockchain node/miner.
Here’s the Python code with step-by-step output:
python
import hashlib
# Step 1: Define a very simple private key (in reality, this would be a large random number)
private_key = "12345"
print(f"Step 1: Private Key Generated\nPrivate Key: {private_key}\n")
# Step 2: Generate a public key from the private key
# In real systems, this uses elliptic curve cryptography (ECC).
# For simplicity, we'll just multiply the private key by 2 (pretend multiplier).
public_key = str(int(private_key) * 2)
print(f"Step 2: Public Key Generated from Private Key\nPublic Key: {public_key}\n")
# Step 3: Create a public address by hashing the public key
# In Bitcoin, this would be SHA-256 then RIPEMD-160. Here, we'll use SHA-256 only.
public_key_bytes = public_key.encode('utf-8')
address = hashlib.sha256(public_key_bytes).hexdigest()[:10] # Shortened for readability
print(f"Step 3: Public Address (Hash of Public Key) Generated\nAddress: {address}\n")
# Step 4: Simulate creating a transaction
# Alice (me) sends coins to Bob's address
bob_address = "bob123hash" # Pretend this is Bob's address
transaction = f"Send 10 coins from {address} to {bob_address}"
print(f"Step 4: Transaction Created\nTransaction: {transaction}\n")
# Step 5: Sign the transaction with the private key
# In reality, this uses ECDSA. Here, we'll just append a simple "signature".
signature = hashlib.md5((transaction + private_key).encode('utf-8')).hexdigest()[:10]
signed_transaction = {"tx": transaction, "signature": signature, "public_key": public_key}
print(f"Step 5: Transaction Signed with Private Key\nSigned Transaction: {signed_transaction}\n")
# Step 6: Simulate a worker (node/miner) verifying and recording the transaction
def worker_verify_and_record(tx_data):
tx = tx_data["tx"]
sig = tx_data["signature"]
pub_key = tx_data["public_key"]
# Extract sender's address from the transaction
sender_address = tx.split("from ")[1].split(" to ")[0]
# Verify the public key hashes to the sender's address
computed_address = hashlib.sha256(pub_key.encode('utf-8')).hexdigest()[:10]
if computed_address != sender_address:
return "Verification Failed: Address mismatch"
# Verify the signature (simplified check)
expected_sig = hashlib.md5((tx + private_key).encode('utf-8')).hexdigest()[:10]
if sig != expected_sig:
return "Verification Failed: Invalid signature"
# If all checks pass, "record" the transaction
return f"Transaction Verified and Recorded by Worker\nFrom: {sender_address}\nTo: {bob_address}\nAmount: 10 coins"
# Simulate the worker processing the transaction
result = worker_verify_and_record(signed_transaction)
print(f"Step 6: Worker Verifies and Records\n{result}")
Output Explanation
When you run this code, here’s what happens at each step, as shown in the output:
- Private Key Generated:
We start with a simple private key, “12345”.
Output: Private Key: 12345 - Public Key Generated:
We “derive” a public key by multiplying the private key by 2 (in reality, this would use ECC).
Output: Public Key: 24690 - Public Address Generated:
We hash the public key using SHA-256 and take the first 10 characters for brevity.
Output: Address: 01a33b8e4e (this will vary based on the hash function output) - Transaction Created:
A transaction is formed, sending 10 coins from our address to Bob’s pretend address.
Output: Transaction: Send 10 coins from 01a33b8e4e to bob123hash - Transaction Signed:
We create a simple signature by hashing the transaction with the private key (simplified, not secure).
Output: Signed Transaction: {‘tx’: ‘Send 10 coins from 01a33b8e4e to bob123hash’, ‘signature’: ‘d41d8cd98f’, ‘public_key’: ‘24690’} - Worker Verifies and Records:
The “worker” checks:- The public key hashes to the sender’s address.
- The signature is valid (matches what the private key would produce).
If all checks pass, it “records” the transaction.
Output: Transaction Verified and Recorded by Worker\nFrom: 01a33b8e4e\nTo: bob123hash\nAmount: 10 coins
Who Responds to Record?
- In this demo, the worker_verify_and_record function simulates a blockchain node or miner. In a real blockchain, multiple nodes (workers) verify transactions independently and reach consensus (e.g., via proof-of-work or proof-of-stake) before adding them to the blockchain ledger.
Caveats
- This is a toy example! Real systems use secure cryptography (e.g., ECDSA for signatures, larger keys, and complex hashing).
- The private key “12345” is trivial and insecure—real private keys are 256-bit numbers (huge).
- The worker here has access to the private key for simplicity; in reality, it only sees the public key and signature.
Who record the transaction?
Here’s the revised code with a simple BlockchainNode class to simulate storing the transaction on a node:
python
import hashlib
# Step 1: Define a very simple private key
private_key = "12345"
print(f"Step 1: Private Key Generated\nPrivate Key: {private_key}\n")
# Step 2: Generate a public key from the private key
public_key = str(int(private_key) * 2) # Simplified derivation
print(f"Step 2: Public Key Generated from Private Key\nPublic Key: {public_key}\n")
# Step 3: Create a public address by hashing the public key
public_key_bytes = public_key.encode('utf-8')
address = hashlib.sha256(public_key_bytes).hexdigest()[:10] # Shortened hash
print(f"Step 3: Public Address (Hash of Public Key) Generated\nAddress: {address}\n")
# Step 4: Simulate creating a transaction
bob_address = "bob123hash"
transaction = f"Send 10 coins from {address} to {bob_address}"
print(f"Step 4: Transaction Created\nTransaction: {transaction}\n")
# Step 5: Sign the transaction with the private key
signature = hashlib.md5((transaction + private_key).encode('utf-8')).hexdigest()[:10]
signed_transaction = {"tx": transaction, "signature": signature, "public_key": public_key}
print(f"Step 5: Transaction Signed with Private Key\nSigned Transaction: {signed_transaction}\n")
# Step 6: Simulate a blockchain node storing the transaction
class BlockchainNode:
def __init__(self, node_id):
self.node_id = node_id
self.ledger = [] # This is where transactions are stored
def verify_and_store(self, tx_data):
tx = tx_data["tx"]
sig = tx_data["signature"]
pub_key = tx_data["public_key"]
# Extract sender's address
sender_address = tx.split("from ")[1].split(" to ")[0]
# Verify the public key hashes to the sender's address
computed_address = hashlib.sha256(pub_key.encode('utf-8')).hexdigest()[:10]
if computed_address != sender_address:
return "Verification Failed: Address mismatch"
# Verify the signature
expected_sig = hashlib.md5((tx + private_key).encode('utf-8')).hexdigest()[:10]
if sig != expected_sig:
return "Verification Failed: Invalid signature"
# If verified, store the transaction in the ledger
self.ledger.append(tx_data)
return (f"Transaction Verified and Stored by Node {self.node_id}\n"
f"From: {sender_address}\nTo: {bob_address}\nAmount: 10 coins\n"
f"Ledger Size: {len(self.ledger)} transactions")
# Create a node and process the transaction
node = BlockchainNode("Node_001")
result = node.verify_and_store(signed_transaction)
print(f"Step 6: Node Verifies and Stores\n{result}\n")
# Step 7: Show the stored ledger
print(f"Step 7: Ledger Contents on Node {node.node_id}\nLedger: {node.ledger}")
What’s New?
- BlockchainNode Class:
- Represents a node in the blockchain network (e.g., a miner or validator).
- Has a ledger (list) to store verified transactions.
- Verifies the transaction (signature and address) and, if valid, stores it.
- Who Stores It?:
- The BlockchainNode (e.g., “Node_001”) is responsible for storing the transaction. In a real blockchain, many nodes would do this redundantly after consensus.
- How It’s Stored:
- The transaction is appended to the node’s ledger, a simple list here. In reality, this would be a block in a chain of blocks, cryptographically linked.
Sample Output
Step 1: Private Key Generated
Private Key: 12345
Step 2: Public Key Generated from Private Key
Public Key: 24690
Step 3: Public Address (Hash of Public Key) Generated
Address: 01a33b8e4e
Step 4: Transaction Created
Transaction: Send 10 coins from 01a33b8e4e to bob123hash
Step 5: Transaction Signed with Private Key
Signed Transaction: {'tx': 'Send 10 coins from 01a33b8e4e to bob123hash', 'signature': 'd41d8cd98f', 'public_key': '24690'}
Step 6: Node Verifies and Stores
Transaction Verified and Stored by Node Node_001
From: 01a33b8e4e
To: bob123hash
Amount: 10 coins
Ledger Size: 1 transactions
Step 7: Ledger Contents on Node Node_001
Ledger: [{'tx': 'Send 10 coins from 01a33b8e4e to bob123hash', 'signature': 'd41