SECTION 1: LEARNING OBJECTIVES
By the end of this lesson, you will be able to:
-
Define blockchain wallets and their components.
-
Differentiate between custodial and non-custodial wallets.
-
Understand HD wallets and BIP standards (BIP32, BIP39, BIP44).
-
Explain seed phrases and their role in key recovery.
-
Describe Self-Sovereign Identity (SSI) and Decentralised Identifiers (DIDs).
-
Understand the integration of KYC/AML with blockchain identity.
-
Implement a wallet key generation and mnemonic simulation in Python.
-
Develop a conceptual framework for digital identity solutions.
SECTION 2: WHAT IS A BLOCKCHAIN WALLET?
2.1 Definition
A blockchain wallet is a software or hardware device that stores the cryptographic keys required to interact with a blockchain network. It does not store cryptocurrency itself but provides the keys to access and manage funds on-chain.
2.2 Wallet Components
┌─────────────────────────────────────────────────────────────────────────────┐ │ WALLET COMPONENTS │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ PRIVATE KEY │ │ │ │ • Secret, never shared. │ │ │ │ • Generates signatures. │ │ │ │ • Controls all assets. │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ v │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ PUBLIC KEY │ │ │ │ • Derived from private key. │ │ │ │ • Shared openly. │ │ │ │ • Used for verification. │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ v │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ ADDRESS │ │ │ │ • Hashed public key. │ │ │ │ • Human-readable (0x... or bc1...). │ │ │ │ • Used for receiving funds. │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ v │ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │ │ SEED PHRASE (MNEMONIC) │ │ │ │ • 12-24 words from BIP39 wordlist. │ │ │ │ • Backs up all keys. │ │ │ │ • Store securely offline. │ │ │ └──────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘
2.3 Types of Wallets
| Type | Description | Pros | Cons |
|---|---|---|---|
| Hot Wallet | Connected to internet | Convenient, fast | Vulnerable to hacks |
| Cold Wallet | Offline storage | Very secure | Inconvenient for daily use |
| Hardware Wallet | Dedicated device | Secure, portable | Cost (~$50-$200) |
| Paper Wallet | Physical print | Immune to digital attacks | Can be lost/damaged |
| Custodial Wallet | Keys held by 3rd party | Easy recovery, support | Trust required |
| Non-Custodial | User holds keys | Full control | User responsible for security |
2.4 Hot vs Cold Comparison
┌─────────────────────────────────────────────────────────────────────────────┐ │ HOT WALLET VS COLD WALLET │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ HOT WALLET │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ ✓ Always connected │ │ │ │ ✓ Quick transactions │ │ │ │ ✓ Good for daily use │ │ │ │ ✗ Exposed to malware/attacks │ │ │ │ ✗ Keys stored in memory │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ │ COLD WALLET │ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │ │ ✓ Keys never touch internet │ │ │ │ ✓ Unhackable remotely │ │ │ │ ✓ Long-term storage │ │ │ │ ✗ Inconvenient for frequent use │ │ │ │ ✗ Requires physical security │ │ │ └─────────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘
SECTION 3: HD WALLETS AND BIP STANDARDS
3.1 What is an HD Wallet?
Hierarchical Deterministic (HD) wallets, defined in BIP32, derive a tree of keys from a single seed. This allows:
-
Generating unlimited addresses from one seed.
-
Organising accounts and sub-accounts.
-
Easy backup (one seed for all keys).
3.2 BIP Standards
| Standard | Description |
|---|---|
| BIP32 | Defines the HD wallet structure and key derivation. |
| BIP39 | Defines the mnemonic seed phrase (12-24 words). |
| BIP44 | Defines a multi-account structure (m/44’/coin’/account’/change/address_index). |
| BIP49 | Defines SegWit addresses (P2WPKH in P2SH). |
| BIP84 | Defines native SegWit addresses (bech32). |
3.3 BIP39 Wordlist
-
2048 English words.
-
Designed to avoid ambiguity (e.g., “test” and “testable” are both in the list).
-
Checksum ensures seed validity.
-
Example:
abandon ability able about above absent absorb abstract absurd abuse access accident
3.4 Derivation Path (BIP44)
m / purpose' / coin_type' / account' / change / address_index Example for Bitcoin: m/44'/0'/0'/0/0 → First external address m/44'/0'/0'/1/0 → First internal (change) address Example for Ethereum: m/44'/60'/0'/0/0 → First Ethereum address
SECTION 4: DIGITAL IDENTITY
4.1 Self-Sovereign Identity (SSI)
SSI is a model where individuals have full control over their digital identity without relying on central authorities.
Core Principles:
-
Existence: Identities exist independently.
-
Control: User controls access and data.
-
Access: User can access their identity at any time.
-
Transparency: Systems are open and auditable.
-
Persistence: Identities endure over time.
-
Privacy: Minimal data sharing.
4.2 Decentralised Identifiers (DIDs)
DIDs are globally unique identifiers that are:
-
Decentralised: No central registry.
-
Verifiable: Cryptographic proof of control.
-
Persistent: Long-lasting independent of providers.
did:example:123456789abcdef Parts: did: → DID method example → Method-specific identifier (e.g., ethr, key, web) 123456789abcdef → Method-specific ID
4.3 Verifiable Credentials (VCs)
-
Cryptographic credentials issued by a trusted party.
-
Can be presented to verify attributes without revealing underlying data (zero-knowledge proofs).
-
Privacy-preserving (selective disclosure).
4.4 Identity in Digital Finance
| Use Case | Description |
|---|---|
| KYC/AML | Verify identity for onboarding. |
| Access Control | Permissioned DeFi protocols. |
| Credit Scoring | On-chain reputation and credit history. |
| Fraud Prevention | Sybil resistance in governance. |
| Regulatory Compliance | Reporting and monitoring. |
SECTION 5: IMPLEMENTATION IN PYTHON
# =================================================================== # MODULE 1, LESSON 5: BLOCKCHAIN WALLETS AND DIGITAL IDENTITY # =================================================================== import hashlib import hmac import os import binascii import struct from typing import List, Tuple, Optional import pandas as pd import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') print("="*70) print("BLOCKCHAIN WALLETS AND DIGITAL IDENTITY") print("="*70) # ---------------------------------------------------------------- # PART A: SIMPLE WALLET KEY GENERATION # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART A: Basic Wallet Key Generation") print("-"*60) def generate_private_key() -> str: """Generate a random 256-bit private key (hex).""" return binascii.hexlify(os.urandom(32)).decode('utf-8') def private_to_public(private_key_hex: str) -> str: """ Simulate public key derivation using SHA-256. Note: Real ECC uses secp256k1; this is a simplified simulation. """ # In reality: ECC point multiplication; we simulate with hash priv_bytes = binascii.unhexlify(private_key_hex) # Simulate public key as hash of private key pub = hashlib.sha256(priv_bytes).hexdigest() return "04" + pub # 04 = uncompressed prefix def public_to_address(public_key_hex: str) -> str: """Simulate address generation from public key.""" # In reality: SHA-256 + RIPEMD-160 + checksum + Base58 # Simplified: hash of public key pub_bytes = binascii.unhexlify(public_key_hex) sha = hashlib.sha256(pub_bytes).digest() ripemd = hashlib.new('ripemd160', sha).digest() address = binascii.hexlify(ripemd).decode('utf-8') return "0x" + address # Generate a key pair priv_key = generate_private_key() pub_key = private_to_public(priv_key) address = public_to_address(pub_key) print(f"Private Key: {priv_key[:16]}...{priv_key[-16:]}") print(f"Public Key (simulated): {pub_key[:16]}...{pub_key[-16:]}") print(f"Address: {address}") # ---------------------------------------------------------------- # PART B: BIP39 MNEMONIC SIMULATION # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART B: BIP39 Mnemonic Generation (Simulated)") print("-"*60) # Define a small subset of the BIP39 wordlist for demonstration BIP39_WORDS = [ "abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid", "acoustic", "acquire", "across", "act", "action", "actor", "actress", "actual", "adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance", "advice", "aerobic", "affair", "afford", "afraid", "again", "age", "agent", "agree", "ahead", "aim", "air", "airport", "aisle", "alarm", "album", "alert", "alien", "all", "alley", "allow", "almost", "alone", "alpha" ] def generate_mnemonic(num_words: int = 12) -> List[str]: """Generate a BIP39 mnemonic phrase (simplified).""" # In reality: entropy + checksum # Simplified: select random words from list entropy = os.urandom(16) # 128 bits for 12 words # Map entropy to indices indices = [] for i in range(num_words): # Use bytes to select words deterministically from entropy idx = int.from_bytes(entropy[i % len(entropy):(i % len(entropy)) + 2], 'big') % len(BIP39_WORDS) indices.append(idx) words = [BIP39_WORDS[idx] for idx in indices] return words def mnemonic_to_seed(words: List[str], passphrase: str = "") -> str: """Convert mnemonic to seed using PBKDF2 (simplified).""" mnemonic_string = " ".join(words) salt = "mnemonic" + passphrase # PBKDF2 with 2048 iterations (simplified hash) seed = hashlib.pbkdf2_hmac( 'sha512', mnemonic_string.encode('utf-8'), salt.encode('utf-8'), 2048 ) return binascii.hexlify(seed[:32]).decode('utf-8') # Only 256 bits for demo # Generate 12-word mnemonic mnemonic = generate_mnemonic(12) print(f"Mnemonic phrase ({len(mnemonic)} words):") print(" " + " ".join(mnemonic)) # Derive seed seed = mnemonic_to_seed(mnemonic) print(f"Seed (first 32 chars): {seed[:32]}...") # Generate private key from seed def seed_to_private_key(seed_hex: str) -> str: """Derive private key from seed (simplified).""" seed_bytes = binascii.unhexlify(seed_hex) # HMAC-SHA512 master_key = hmac.new( b"Bitcoin seed", seed_bytes, hashlib.sha512 ).digest() # First 32 bytes = private key return binascii.hexlify(master_key[:32]).decode('utf-8') priv_from_seed = seed_to_private_key(seed) print(f"Private key derived from seed: {priv_from_seed[:16]}...") # ---------------------------------------------------------------- # PART C: HD WALLET DERIVATION PATH # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART C: HD Wallet Derivation Path Simulation") print("-"*60) def derive_path(seed_hex: str, path: str) -> str: """ Simulate HD key derivation along a BIP44 path. path format: "m/44'/0'/0'/0/0" """ # Simplified: hash the seed with the path string seed_bytes = binascii.unhexlify(seed_hex) path_bytes = path.encode('utf-8') # Derive key using HMAC-SHA512 with path derived = hmac.new(seed_bytes, path_bytes, hashlib.sha512).digest() return binascii.hexlify(derived[:32]).decode('utf-8') # Derive multiple addresses paths = [ "m/44'/0'/0'/0/0", # First external address "m/44'/0'/0'/0/1", # Second external address "m/44'/0'/0'/1/0", # First internal (change) address "m/44'/60'/0'/0/0", # Ethereum address ] print("Derived keys for different paths:") for p in paths: key = derive_path(seed, p) # Simulate address from key addr_hash = hashlib.sha256(binascii.unhexlify(key)).hexdigest()[:20] print(f" {p}: 0x{addr_hash}") # ---------------------------------------------------------------- # PART D: WALLET TYPES COMPARISON # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART D: Wallet Types Comparison") print("-"*60) wallet_comparison = pd.DataFrame({ 'Type': ['Hot', 'Cold', 'Hardware', 'Paper', 'Custodial', 'Non-Custodial'], 'Security': ['Low', 'Very High', 'High', 'Medium', 'Medium', 'High'], 'Convenience': ['Very High', 'Low', 'Medium', 'Very Low', 'High', 'Medium'], 'Cost': ['Free', 'Free', '$50-200', 'Free', 'Free', 'Free'], 'Recovery': ['Easy', 'Medium', 'Easy', 'Hard', 'Easy', 'User-dependent'], 'Control': ['User', 'User', 'User', 'User', 'Third-party', 'User'] }) print(wallet_comparison.to_string(index=False)) # ---------------------------------------------------------------- # PART E: DIGITAL IDENTITY FRAMEWORK # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART E: Digital Identity Components") print("-"*60) identity_components = { "DID (Decentralised Identifier)": { "Structure": "did:method:identifier", "Purpose": "Unique, permanent identifier", "Example": "did:ethr:0x1234..." }, "DID Document": { "Structure": "JSON-LD with public keys, services", "Purpose": "Describes how to interact with DID", "Example": "Contains verification methods" }, "Verifiable Credential (VC)": { "Structure": "Context, ID, type, issuer, issuance date, subject, proof", "Purpose": "Digitally signed attestation", "Example": "University degree credential" }, "Verifiable Presentation (VP)": { "Structure": "One or more VCs with proof", "Purpose": "Present credentials to verifier", "Example": "Present degree + ID for KYC" } } for component, details in identity_components.items(): print(f"\n{component.upper()}:") for key, value in details.items(): print(f" {key}: {value}") # ---------------------------------------------------------------- # PART F: WALLET SECURITY BEST PRACTICES # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART F: Wallet Security Best Practices") print("-"*60) security_tips = { "Seed Phrase Storage": [ "Write on paper, not digital", "Store in multiple secure locations", "Never share with anyone", "Use metal backup for fire/flood protection" ], "Private Key Management": [ "Use hardware wallets for large amounts", "Keep hot wallets for small amounts only", "Use multi-signature for institutional custody", "Regularly rotate keys (if possible)" ], "Transaction Practices": [ "Always verify recipient address", "Start with small test transactions", "Check gas estimates before sending", "Be wary of phishing and fake sites" ], "Recovery Planning": [ "Test recovery process", "Have contingency plans", "Keep up-to-date emergency contacts", "Document recovery steps securely" ] } for category, tips in security_tips.items(): print(f"\n{category.upper()}:") for tip in tips: print(f" • {tip}") # ---------------------------------------------------------------- # PART G: IDENTITY IN DIGITAL FINANCE (KYC/AML) # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART G: KYC/AML Integration with Digital Identity") print("-"*60) kyc_steps = { "Step 1: Customer Identification": { "Process": "Collect personal information", "Data": ["Name", "Date of birth", "Address", "Nationality"], "Blockchain Role": "Store hash of verified identity, not raw data" }, "Step 2: Identity Verification": { "Process": "Verify documents (passport, ID card)", "Data": ["Passport number", "Photo", "Proof of address"], "Blockchain Role": "Issuer signs VC attesting to verification" }, "Step 3: Risk Assessment": { "Process": "Screen against watchlists", "Data": ["PEP status", "Sanctions lists", "Politically exposed persons"], "Blockchain Role": "Smart contract checks for compliance" }, "Step 4: Ongoing Monitoring": { "Process": "Monitor for suspicious activity", "Data": ["Transaction patterns", "Geolocation", "Amount thresholds"], "Blockchain Role": "On-chain monitoring with ML/AI" } } for step, details in kyc_steps.items(): print(f"\n{step.upper()}:") print(f" Process: {details['Process']}") print(f" Data: {', '.join(details['Data'])}") print(f" Blockchain Role: {details['Blockchain Role']}") # ---------------------------------------------------------------- # PART H: VISUALISE WALLET ECOSYSTEM # ---------------------------------------------------------------- print("\n" + "-"*60) print("PART H: Wallet Ecosystem Visualisation") print("-"*60) # Create a simple visualisation of wallet usage fig, axes = plt.subplots(1, 2, figsize=(12, 4)) # Wallet types usage wallet_types = ['Hot', 'Cold', 'Hardware', 'Paper'] usage = [65, 20, 10, 5] colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99'] ax1 = axes[0] ax1.pie(usage, labels=wallet_types, autopct='%1.1f%%', startangle=90, colors=colors) ax1.set_title('Wallet Type Adoption (Estimate)') # Security vs Convenience types = ['Hot', 'Custodial', 'Hardware', 'Paper', 'Cold'] security = [3, 5, 9, 7, 10] convenience = [10, 9, 6, 3, 2] ax2 = axes[1] ax2.scatter(security, convenience, s=200, c=range(len(types)), cmap='coolwarm', alpha=0.8) for i, t in enumerate(types): ax2.annotate(t, (security[i], convenience[i]), xytext=(5, 5), textcoords='offset points', fontsize=9) ax2.set_xlabel('Security (10 = highest)') ax2.set_ylabel('Convenience (10 = highest)') ax2.set_title('Wallet Trade-off: Security vs Convenience') ax2.grid(True, alpha=0.3) plt.tight_layout() plt.savefig('wallet_ecosystem.png', dpi=300, bbox_inches='tight') plt.show() print("Wallet ecosystem chart saved as 'wallet_ecosystem.png'") # ---------------------------------------------------------------- # PART I: SUMMARY AND RECOMMENDATIONS # ---------------------------------------------------------------- print("\n" + "="*70) print("PART I: Summary and Recommendations") print("="*70) print(""" Blockchain Wallets and Digital Identity – Key Takeaways: 1. Wallets manage cryptographic keys (private/public/address). 2. Types: hot (online) vs cold (offline), custodial vs non-custodial. 3. HD wallets (BIP32) derive unlimited addresses from a single seed. 4. BIP39 defines 12-24 word seed phrases for backup and recovery. 5. SSI gives users control over their identity without central authorities. 6. DIDs (Decentralised Identifiers) are permanent, verifiable identifiers. 7. VCs (Verifiable Credentials) enable privacy-preserving attestations. 8. KYC/AML can be integrated with blockchain identity systems. Recommendations: - Always back up your seed phrase securely (offline). - Use hardware wallets for significant holdings. - Verify addresses before sending transactions. - Understand the difference between custodial and non-custodial. - Stay updated on digital identity standards (W3C, DIF). - Consider privacy and regulatory requirements in identity solutions. """)