Foundations Refresh
Blockchain is ≈ networking + crypto + a replicated state machine. Before we touch a block, make sure TCP, HTTP, and hashing are razor-sharp.
curl to a server.1. The network under everything
Blockchain nodes talk peer-to-peer over TCP/IP. You already know this; the new thing is that there is no server — every node is both client and server.
- TCP gives reliability; UDP is fire-and-forget (some P2P protocols prefer it for discovery).
- HTTP/JSON-RPC is how your backend talks to a node. devp2p/libp2p is how nodes talk to each other.
- TLS = TCP + handshake that derives a shared symmetric key using asymmetric crypto. Same math you'll use to sign transactions.
2. Hashing — the integrity primitive
A hash is a deterministic one-way function: same input → same output; change one bit → output changes completely (avalanche). You've seen them as ETags, Git commit IDs, and password storage.
abc123... commit hash is exactly this: a SHA-1 of (tree + parent + author + message).import hashlib
h = hashlib.sha256(b"hello").hexdigest()
# '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'const { createHash } = require('crypto');
const h = createHash('sha256').update('hello').digest('hex');echo -n "hello" | openssl dgst -sha256Properties to memorize
| Property | Means | Why blockchain cares |
|---|---|---|
| Pre-image resistance | Given h, can't find x | Commit-reveal schemes |
| Second pre-image | Given x, can't find x' with same h | Block integrity |
| Collision resistance | Can't find any x, x' with same h | Merkle trees |
| Avalanche | 1-bit change → ~50% output bits flip | PoW mining |
3. Symmetric vs asymmetric
Two families, both needed.
| Symmetric | Asymmetric | |
|---|---|---|
| Keys | 1 shared secret | Keypair (public, private) |
| Speed | Fast (AES, ChaCha20) | ~1000× slower (RSA, ECC) |
| Used for | Bulk data | Key exchange, signatures |
| Blockchain use | Rare (wallet encryption) | Ubiquitous (tx signing) |
4. Digital signatures
A signature lets Alice prove to Bob that a message came from her, without sharing her private key. Every Ethereum transaction is a signature over the tx payload.
Ethereum uses ECDSA on secp256k1 (same curve as Bitcoin). You do not choose; this is fixed.
Show: sign & verify in Python (ECDSA)
from ecdsa import SigningKey, SECP256k1
sk = SigningKey.generate(curve=SECP256k1)
vk = sk.verifying_key
msg = b"pay bob 10 eth"
sig = sk.sign(msg)
print(vk.verify(sig, msg)) # True
5. Mini-project — a hash + sign CLI
Build a 30-line Python script that (a) takes a file, (b) prints its SHA-256, (c) signs the hash with a locally generated keypair, and (d) verifies the signature.
python sign.py hash file.txt, python sign.py sign file.txt, python sign.py verify file.txt sig.bin pub.pem. This is the exact mental model of how a wallet signs a transaction.Starter (expand after you try)
import sys, hashlib
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes, serialization
cmd = sys.argv[1]
if cmd == "hash":
print(hashlib.sha256(open(sys.argv[2],"rb").read()).hexdigest())
elif cmd == "keygen":
sk = ec.generate_private_key(ec.SECP256K1())
open("priv.pem","wb").write(sk.private_bytes(
serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8,
serialization.NoEncryption()))
open("pub.pem","wb").write(sk.public_key().public_bytes(
serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo))
# ... sign / verify left as exerciseQuiz
- AES is too slow for blockchain throughput
- Symmetric keys are shared — they can't prove who signed, only that whoever signed knew the secret
- AES outputs are too long to fit in a block
- AES doesn't produce deterministic outputs