Blockchain, crypto & Web3

Blockchain, crypto & Web3

Content Overview

  1. PHASE 1: BLOCKCHAIN and CRYPTO
    1. Blockchain Foundations & Cryptocurrency
    2. 1. Introduction to Blockchain
      1. 1.1 What is Blockchain?
      2. 1.2 History of Blockchain
      3. 1.3 Why Blockchain?
      4. 1.4 Features & Characteristics
      5. 1.5 Blockchain vs Traditional Databases
      6. 1.6 Blockchain Use Cases
      7. 1.7 Blockchain Limitations
      8. 1.8 Blockchain Trilemma
    3. 2. Blockchain Fundamentals
      1. 2.1 Distributed Ledger Technology (DLT)
      2. 2.2 Blockchain Architecture
      3. 2.3 Blockchain Components
      4. 2.4 Blocks
      5. 2.5 Block Header
      6. 2.6 Genesis Block
      7. 2.7 Transactions
      8. 2.8 Transaction Lifecycle
      9. 2.9 Mempool
      10. 2.10 Blockchain State
      11. 2.11 UTXO Model
      12. 2.12 Account-Based Model
      13. 2.13 Peer-to-Peer Network
      14. 2.14 Nodes
      15. 2.15 Consensus Mechanisms
      16. 2.16 Mining
      17. 2.17 Validators
      18. 2.18 Finality
      19. 2.19 Forks
      20. 2.20 Mainnet, Testnet, Devnet
      21. 2.21 Sidechains
      22. 2.22 Blockchain Types
    4. 3. Cryptography
      1. 3.1 Cryptography Fundamentals
      2. 3.2 Hash Functions
      3. 3.3 SHA-256
      4. 3.4 Keccak-256
      5. 3.5 Public Key Cryptography
      6. 3.6 Private Keys
      7. 3.7 Public Keys
      8. 3.8 Wallet Addresses
      9. 3.9 Digital Signatures
      10. 3.10 ECDSA
      11. 3.11 EdDSA
      12. 3.12 Elliptic Curve Cryptography (ECC)
      13. 3.13 Merkle Trees
      14. 3.14 Entropy
      15. 3.15 Random Number Generation
      16. 3.16 HD Wallet Standards
      17. 3.17 Zero-Knowledge Proof Fundamentals
    5. 4. Cryptocurrency
      1. 4.1 What is Cryptocurrency?
      2. 4.2 Bitcoin
      3. 4.3 Ethereum
      4. 4.4 Altcoins
      5. 4.5 Stablecoins
      6. 4.6 Meme Coins
      7. 4.7 Coins vs Tokens
      8. 4.8 Utility Tokens
      9. 4.9 Governance Tokens
      10. 4.10 Security Tokens
      11. 4.11 Tokenomics
      12. 4.12 Supply Models
      13. 4.13 Inflation
      14. 4.14 Deflation
      15. 4.15 Halving
      16. 4.16 Liquidity
      17. 4.17 Market Capitalization
      18. 4.18 FDV
      19. 4.19 TVL
    6. 5. Wallets & Transactions
      1. 5.1 Wallet Fundamentals
      2. 5.2 Hot Wallets
      3. 5.3 Cold Wallets
      4. 5.4 Hardware Wallets
      5. 5.5 Custodial Wallets
      6. 5.6 Non-Custodial Wallets
      7. 5.7 Seed Phrase
      8. 5.8 Transaction Signing
      9. 5.9 Gas
      10. 5.10 Gas Limit
      11. 5.11 Gas Price
      12. 5.12 Gwei
      13. 5.13 Nonce
      14. 5.14 Multi-Signature Wallets
      15. 5.15 Block Explorers
      16. 5.16 Wallet Security
    7. PHASE 1 – COMPLETE PROJECT
      1. Blockchain Explorer & Wallet System
  2. PHASE 2: WEB3 DEVELOPMENT & DECENTRALIZED APPLICATIONS
    1. Build Smart Contracts, Tokens, and Decentralized Applications
    2. 1. Web3 Fundamentals
      1. 1.1 Web1 vs Web2 vs Web3
      2. 1.2 Decentralization
      3. 1.3 Ethereum Ecosystem
      4. 1.4 Ethereum Virtual Machine (EVM)
      5. 1.5 Smart Contracts
      6. 1.6 Externally Owned Accounts (EOA)
      7. 1.7 Smart Contract Accounts
      8. 1.8 ABI (Application Binary Interface)
      9. 1.9 Bytecode
      10. 1.10 Gas & Execution
      11. 1.11 JSON-RPC
      12. 1.12 RPC Providers
    3. 2. Smart Contract Development
      1. Solidity Basics
        1. Variables
        2. Data Types
        3. Operators
        4. Functions
        5. Constructors
        6. Visibility
        7. Control Flow
      2. Solidity Intermediate
        1. Structs
        2. Enums
        3. Arrays
        4. Mappings
        5. Events
        6. Errors
        7. Modifiers
        8. Libraries
        9. Interfaces
        10. Abstract Contracts
        11. Inheritance
      3. Solidity Advanced
        1. Storage
        2. Memory
        3. Calldata
        4. Delegatecall
        5. Proxy Patterns
        6. Upgradeable Contracts
        7. Design Patterns
        8. Gas Optimization
    4. 3. Token Standards
      1. Fungible Tokens
        1. ERC-20
        2. ERC-777
        3. ERC-4626
      2. NFTs
        1. ERC-721
        2. ERC-1155
        3. ERC-2981
      3. Smart Accounts
        1. ERC-4337
    5. 4. Development Tools
      1. IDEs
        1. Remix
        2. VS Code
      2. Frameworks
        1. Hardhat
        2. Foundry
      3. Libraries
        1. OpenZeppelin
        2. Ethers.js
    6. 5. DApp Development
      1. Frontend
        1. React
        2. Next.js
      2. Wallet Integration
        1. MetaMask
        2. WalletConnect
      3. Blockchain Communication
        1. Reading Blockchain Data
        2. Writing Transactions
      4. Decentralized Storage
        1. IPFS
        2. Filecoin
        3. Arweave
      5. Indexing
        1. The Graph
      6. Domain Names
        1. ENS
      7. Full Stack Integration
        1. Frontend ↔ Smart Contract Integration
  3. PHASE 3: ADVANCED WEB3 ECOSYSTEM, SECURITY & SCALABILITY
    1. 1. Decentralized Finance (DeFi)
      1. 1.1 What is DeFi?
      2. 1.2 DEX (Decentralized Exchange)
      3. 1.3 AMM (Automated Market Maker)
      4. 1.4 Liquidity Pools
      5. 1.5 Yield Farming
      6. 1.6 Staking
      7. 1.7 Lending and Borrowing
      8. 1.8 Flash Loans
      9. 1.9 Stablecoins
      10. 1.10 Synthetic Assets
      11. 1.11 Perpetual Protocols
    2. 2. NFTs (Non-Fungible Tokens)
      1. 2.1 NFT Architecture
      2. 2.2 Metadata
      3. 2.3 Minting
      4. 2.4 Royalties
      5. 2.5 Dynamic NFTs
      6. 2.6 NFT Marketplaces
    3. 3. DAOs (Decentralized Autonomous Organizations)
      1. 3.1 Governance
      2. 3.2 Governance Tokens
      3. 3.3 Treasury
      4. 3.4 Voting Mechanisms
    4. 4. Layer 2 & Blockchain Scaling
      1. 4.1 Blockchain Scalability
      2. 4.2 Rollups
      3. 4.3 Optimistic Rollups
      4. 4.4 ZK Rollups
      5. 4.5 Polygon
      6. 4.6 Arbitrum
      7. 4.7 Optimism
      8. 4.8 Base
      9. 4.9 Starknet
      10. 4.10 zkSync
      11. 4.11 Celestia
      12. 4.12 Data Availability
      13. 4.13 Danksharding
      14. 4.14 Proto-Danksharding (EIP-4844)
    5. 5. Cross-Chain & Oracle Networks
      1. 5.1 Blockchain Bridges
      2. 5.2 Wrapped Tokens
      3. 5.3 Cross-Chain Messaging
      4. 5.4 Cosmos
      5. 5.5 Polkadot
      6. 5.6 IBC (Inter-Blockchain Communication)
      7. 5.7 Chainlink
      8. 5.8 VRF (Verifiable Random Function)
    6. 6. Blockchain Security & Auditing
      1. 6.1 Smart Contract Security
      2. 6.2 Common Vulnerabilities
    7. 7. Testing, Deployment & DevOps
      1. 7.1 Testing
      2. 7.2 Deployment
      3. 7.3 Infrastructure
    8. 8. Advanced Blockchain Concepts
      1. 8.1 Zero-Knowledge Proofs
      2. 8.2 MEV (Miner Extractable Value)
      3. 8.3 Account Abstraction
    9. 9. Real-World Applications
      1. 9.1 Supply Chain
      2. 9.2 Digital Identity
      3. 9.3 Healthcare
      4. 9.4 Gaming and GameFi
      5. 9.5 DePIN (Decentralized Physical Infrastructure Networks)
      6. 9.6 Real World Assets (RWA)
    10. 10. Blockchain Business & Careers
      1. 10.1 Tokenomics Design
      2. 10.2 Fundraising Methods
      3. 10.3 Career Paths
    11. PHASE 3 – COMPLETE PROJECT
      1. Integrated DeFi, DAO & NFT Platform

PHASE 1: BLOCKCHAIN and CRYPTO

Blockchain Foundations & Cryptocurrency

Learn the core concepts, architecture, cryptography, cryptocurrencies, and blockchain ecosystem.

1. Introduction to Blockchain

1.1 What is Blockchain?

Blockchain is a digital record-keeping technology that securely stores information across multiple interconnected computers instead of relying on a single central authority. Every transaction is grouped into encrypted blocks, linked in chronological order, and protected against unauthorized changes, creating a transparent, distributed, and tamper-resistant ledger. Instead of being stored in a single location, the ledger is replicated across thousands of nodes (computers) worldwide. Every transaction is collected into a digital block. Once a block is verified, it is securely connected to the block before it using cryptographic techniques, creating a continuous sequence known as a blockchain. This linked structure helps preserve the integrity of the data and makes the transaction history extremely difficult to alter.

The Core Idea: Blockchain eliminates the need for a central authority (like a bank or government) by allowing participants to verify and record transactions collectively. Once a transaction is recorded, it cannot be altered or deleted without the consensus of the network, making the system highly secure and transparent.

Real-World Analogy – The Public Ledger:

Imagine a public notebook that everyone in a village can see and write in. Every time someone makes a transaction (e.g., “Alice gave Bob 5 coins”), they announce it, and everyone writes it down in their copy of the notebook. After a transaction is permanently recorded on the blockchain and confirmed by the network, it cannot be modified, deleted, or tampered with, ensuring the integrity and reliability of the stored data.If someone tries to cheat, everyone else can check their copy and see the truth. Blockchain is essentially this digital notebook on a global scale.

Real-World Example – Bitcoin:

Bitcoin was the first successful application of blockchain technology and remains the world’s most recognized cryptocurrency. For example, if Alice transfers 1 BTC to Bob, the transaction is broadcast to the Bitcoin network, verified by participating nodes, and permanently recorded on the blockchain after validation.

  1. Alice creates a transaction and digitally signs it using her private key.
  2. The transaction is sent to the Bitcoin network for verification.
  3. Miners validate the transaction and include it in a block
  4. The block is added to the blockchain
  5. Bob receives 1 BTC in his wallet
  6. The transaction is permanently recorded and cannot be reversed or modified.

Key Components of Blockchain:

ComponentDescriptionExample
Distributed LedgerDatabase spread across multiple locationsEvery node has a copy
Immutable RecordsOnce added, data cannot be changedTransactions are permanent
Consensus MechanismsAgreement protocols that validate transactionsProof of Work, Proof of Stake
Cryptographic SecurityMathematical encryption that secures dataSHA-256 hashing
Smart ContractsSelf-executing code on the blockchainEthereum smart contracts

1.2 History of Blockchain

The Origins and Evolution:

1991 – The First Concept: Stuart Haber and W. Scott Stornetta describe a cryptographically secured chain of blocks for timestamping digital documents. They wanted to ensure documents couldn’t be backdated or tampered with. This is the first known description of a blockchain-like structure. Their work laid the foundation for what would eventually become blockchain technology, establishing the core idea of linking blocks of data with cryptographic hashes.

2008 – The Birth of Bitcoin: An anonymous person or group using the pseudonym Satoshi Nakamoto publishes the Bitcoin whitepaper: “Bitcoin: A Peer-to-Peer Electronic Cash System.” This groundbreaking paper introduced a digital currency that works without banks or any central authority. It also solved the problem of people trying to spend the same digital money more than once, known as the double-spending problem.” The paper was published on a cryptography mailing list on October 31, 2008.

2009 – The First Blockchain: Satoshi Nakamoto launches the Bitcoin network and mines the first block (Genesis Block). The block contained the message: “The Times 03/Jan/2009 Chancellor on brink of second bailout for banks.” This message served two purposes: proving the block was created after that date, and providing a commentary on the financial system’s instability.

2010 – First Real-World Transaction: Laszlo Hanyecz pays 10,000 BTC for two pizzas, marking the first real-world Bitcoin transaction. This event is celebrated as “Bitcoin Pizza Day” on May 22nd. Those pizzas are now worth hundreds of millions of dollars, making this the most expensive meal in history.

2013 – Ethereum Whitepaper: Vitalik Buterin publishes the Ethereum whitepaper, introducing the concept of smart contracts and a programmable blockchain. This expanded blockchain beyond just currency to a platform for decentralized applications. The whitepaper proposed a Turing-complete programming language for the blockchain.

2015 – Ethereum Launches: The Ethereum network goes live, enabling developers to build decentralized applications (dApps). This marked the beginning of “Blockchain 2.0” and opened up countless possibilities for blockchain applications beyond simple transactions.

2017 – ICO Boom: Massive surge in cryptocurrency prices and ICOs (Initial Coin Offerings). Bitcoin reaches ~$20,000 for the first time. This brought blockchain into mainstream consciousness and led to a massive influx of capital and talent into the space.

2020 – DeFi Summer: Decentralized Finance explodes with projects like Uniswap, Aave, and Compound. Billions of dollars are locked in DeFi protocols, enabling lending, borrowing, and trading without intermediaries.

2021 – NFTs Go Mainstream: NFT art sells for millions; blockchain gaming gains popularity. Digital ownership becomes a multi-billion dollar industry. Beeple’s NFT sold for $69 million at Christie’s auction.

2022-2023 – Institutional Adoption: Major companies, banks, and governments begin exploring blockchain technology. Ethereum transitions to Proof of Stake (The Merge), reducing energy consumption by 99.9%. BlackRock, Fidelity, and other major financial institutions enter the crypto space.

1.3 Why Blockchain?

The Problem Blockchain Solves:

Traditional systems rely on trusted intermediaries (banks, governments, lawyers) to verify and record transactions. This creates several critical problems that blockchain addresses directly.

Single Point of Failure: Traditional systems are centralized, meaning all data flows through a single point. If that point is compromised (hacked, corrupted, or goes offline), the entire system fails. Banks, for example, have been hacked multiple times, resulting in millions of dollars in losses. Blockchain is distributed across thousands of nodes, meaning even if many nodes go down, the network continues to function.

Trust Required: In traditional systems, you must trust the third party (bank, government, lawyer) to handle your transactions honestly. This trust is often violated through fraud, corruption, or errors. Blockchain eliminates the need for trust by using cryptography and consensus. You don’t need to trust anyone; you trust the mathematics.

High Costs: Intermediaries charge significant fees for their services. Banks charge for wire transfers, currency conversion, account maintenance, and more. These fees can be 3-5% of the transaction amount. Blockchain enables peer-to-peer transactions with minimal fees (typically $0.10-$5.00) regardless of the amount being transferred.

Slow Transactions: International bank transfers take 3-5 business days to process. This is because multiple banks and clearing houses need to verify and approve the transaction. Blockchain transactions are confirmed in minutes (Bitcoin) or seconds (faster chains), regardless of the amount or distance.

Limited Access: Over 1.7 billion adults worldwide are unbanked – they don’t have access to traditional banking services. They can’t open bank accounts, get loans, or send money internationally. Anyone with internet access can use blockchain, making it truly global and inclusive.

Censorship: Governments and corporations can block financial transactions. They can freeze accounts, stop payments, or prevent people from accessing their money. Blockchain is censorship-resistant – no single entity can block or reverse a valid transaction.

Transparency: Traditional financial systems are opaque. It’s difficult to see where money is coming from or going to. Blockchain provides a transparent ledger where all transactions are publicly visible, creating accountability and reducing fraud.

1.4 Features & Characteristics

The 5 Core Features of Blockchain:

1. Decentralized:
No central authority controls the network. Instead, control is distributed across all participants (nodes). This means no single entity can shut down the network, censor transactions, or change the rules without consensus. Bitcoin, for example, has no CEO, headquarters, or central server. It’s maintained by thousands of independent nodes worldwide.

Real-World Example: No government or bank controls Bitcoin. Even if one country bans it, the network continues to operate in other countries. This makes blockchain resilient and censorship-resistant.

2. Immutable:
Once data is recorded on the blockchain, it cannot be changed or deleted. Each block contains a cryptographic hash of the previous block, creating a chain. Changing any data would change the hash, breaking the chain and being immediately detected. This immutability makes blockchain perfect for records that must be trustworthy and permanent.

Real-World Example: Bitcoin transactions are permanent. If someone sends you Bitcoin, they cannot reverse the transaction. This eliminates chargeback fraud and creates certainty in transactions.

3. Transparent:
Every transaction is recorded on the blockchain and can be viewed by anyone on the network. Anyone can view the entire history of transactions, from the very first block to the most recent. This transparency creates accountability and trust, as everything can be verified.

Example: Anyone can view the Bitcoin ledger at any time. You can see the total supply, transaction volume, and even track specific addresses. This open record system makes it easier to detect fraud and reduces the chances of corruption.

4. Secure:
Blockchain uses advanced cryptography to secure data. Transactions are signed with private keys, making it impossible for anyone else to authorize transactions from your account. The distributed nature also means there’s no single point of attack.

Real-World Example: Private keys control ownership. As long as you keep your private key secure, no one can steal your cryptocurrency. The cryptography is mathematically proven to be secure.

5. Distributed:
The ledger is replicated across thousands of nodes (computers) worldwide. ach network node stores a full copy of the blockchain, keeping the data available across the entire system. This distribution ensures redundancy and resilience – even if many nodes go offline, the network continues to function.

Example: The Bitcoin network has over 15,000 active nodes worldwide. If one country tries to shut it down, nodes in other countries keep it running. This global distribution makes the network virtually impossible to destroy.

1.5 Blockchain vs Traditional Databases

The Key Differences:

Traditional databases and blockchains serve different purposes and have fundamentally different architectures. Understanding these differences is crucial for choosing the right technology for your application.

Control and Ownership:

Traditional databases are centralized. A single entity (a company, organization, or administrator) controls the database. They decide who can access it, what data is stored, and how it’s modified. A central authority manages and controls all the stored information.

Blockchain is decentralized. No single entity controls the network. Instead of relying on one authority, control is shared among all network participants. Decisions are made through consensus mechanisms, ensuring that no single party can unilaterally change the data or rules.

Data Modification:

In traditional databases, data can be easily modified, updated, or deleted. Administrators have full CRUD (Create, Read, Update, Delete) privileges. This flexibility is useful for many applications but can also lead to data tampering or loss.

Blockchain is immutable. Once data is written to the blockchain, it cannot be modified or deleted. You can only add new data. This immutability is a feature, not a bug – it ensures trust and prevents tampering.

Trust Model:

Traditional databases require trust in the central authority. You must trust that the database administrator won’t alter data maliciously, that the company won’t lose your data, and that proper security measures are in place.

Blockchain is trustless. Trust is not placed in any individual or organization but in the mathematics of cryptography and the consensus mechanism. The system is designed so that no single participant needs to trust any other.

Transparency:

Traditional databases are typically opaque. Users cannot see the internal workings of the database or verify data integrity. Access to data is controlled by the central authority.

Blockchain is transparent. All transactions are publicly visible on the ledger. Anyone can verify the data, audit the system, and ensure its integrity without needing special permissions.

Speed and Performance:

Traditional databases are extremely fast. They can handle thousands of transactions per second, with millisecond latency. This makes them suitable for high-performance applications like banking systems, e-commerce, and real-time analytics.

Blockchain is slower. It’s designed for security and decentralization, not speed. Bitcoin can handle around 7 transactions per second, while Ethereum supports approximately 15 transactions per second.This is a trade-off for the benefits of immutability and decentralization.

Cost:

Traditional databases are relatively cheap to operate. There are no transaction fees, and infrastructure costs are reasonable. The main cost is the hardware and software licenses.

Blockchain can be expensive. Transaction fees (gas) are paid to miners or validators. These fees can spike during periods of high network congestion, making small transactions economically unviable.

1.6 Blockchain Use Cases

Industry Applications:

Blockchain technology has moved beyond cryptocurrency to revolutionize numerous industries. Each use case leverages blockchain’s unique properties of decentralization, immutability, transparency, and security.

Supply Chain Management:

Blockchain enables tracking products from origin to consumer. Every step in the supply chain is recorded on the blockchain, creating an immutable history. This reduces fraud, enables faster recalls, and provides consumers with transparency about product provenance.

Real-World Example: Walmart uses IBM Food Trust blockchain to trace mangoes. Traditional tracing took 6 days. Blockchain tracing takes 2.2 seconds – a 235,000x improvement. This speed is critical during food safety outbreaks where rapid identification of contamination sources saves lives.

Digital Identity:

Self-sovereign identity allows people to manage and control their own personal information without depending on a central authority. Instead of companies storing your identity data, you store it on the blockchain and share it selectively. This reduces identity theft and gives you privacy.

Real-World Example: Estonia uses blockchain for 95% of health data. Citizens control who accesses their medical records. This has eliminated identity fraud and improved healthcare efficiency.

Decentralized Finance (DeFi):

DeFi recreates traditional financial services (lending, borrowing, trading) without intermediaries. Smart contracts execute trades, loans, and interest payments automatically. This is cheaper, faster, and accessible to anyone with internet.

Real-Real-World Example: Uniswap is a decentralized exchange where users can swap different tokens, provide liquidity, and earn rewards without depending on traditional banks or intermediaries. It handles billions of dollars in trading activity and allows anyone with a crypto wallet to participate.

NFTs (Non-Fungible Tokens):

NFTs represent ownership of unique digital assets. Artists can sell digital art with automatic royalties, gamers can own in-game items, and collectors can prove authenticity. The blockchain provides provable scarcity and provenance.

Real-World Example: Beeple’s digital artwork sold for $69 million at Christie’s. Artists now earn royalties on secondary sales automatically through smart contracts.

Healthcare:

Blockchain enables secure sharing of medical records, drug traceability, and clinical trial transparency. Patients control their data, researchers access anonymized data, and counterfeit drugs are eliminated.

Example: MedRec uses blockchain for medical records management. Patients grant access to doctors, and all access is logged immutably. This ensures privacy while enabling efficient healthcare.

1.7 Blockchain Limitations

Current Challenges:

Despite its revolutionary potential, blockchain technology faces significant limitations that prevent mass adoption. Recognizing these challenges helps set practical expectations and guides future improvements in blockchain technology.

1. Scalability:

Scalability remains one of the biggest technical issues that blockchain networks need to overcome. The number of transactions per second (TPS) is limited by the consensus mechanism and block size.

Impact: Bitcoin processes ~7 TPS, Ethereum ~15 TPS, while Visa processes ~24,000 TPS. This makes blockchain unsuitable for high-volume applications like retail payments. During peak times, the network becomes congested, fees skyrocket, and transactions take hours to confirm.

Example: During the 2017 crypto boom, Bitcoin transaction fees exceeded $50 and confirmation times exceeded 1 hour. This made Bitcoin practically unusable for small transactions.

2. Energy Consumption:

Proof of Work (PoW) consensus requires massive computational power. Bitcoin mining consumes as much electricity as entire countries (Argentina ~120 TWh, Bitcoin ~150 TWh).

Impact: This energy consumption is environmentally unsustainable and makes PoW networks expensive to operate. One Bitcoin transaction uses enough electricity to power a home for 75 days.

Example: Ethereum’s transition to Proof of Stake reduced energy consumption by 99.9% – from ~100 TWh to ~0.01 TWh per year.

3. Latency:

Transaction confirmation is slow. Bitcoin requires 10 minutes per block and 6 confirmations (~1 hour) for finality. Even fast chains require seconds to minutes.

Impact: This makes blockchain unsuitable for applications requiring instant confirmation, like point-of-sale transactions. Users must wait and cannot get immediate confirmation.

4. Storage Requirements:

Full nodes require significant storage. Bitcoin blockchain ~500 GB and growing; Ethereum ~1 TB and growing.

Impact: This creates a barrier to entry for running full nodes. Only dedicated users with substantial storage can participate fully, potentially leading to centralization.

5. Complexity:

Blockchain is technically complex. Users must understand concepts like private keys, gas fees, and wallets. The user experience is often poor and intimidating.

Impact: This limits adoption to technically proficient users. Mass adoption requires simpler interfaces and better user education.

6. Regulation:

Regulatory frameworks are unclear and inconsistent across jurisdictions. Some countries embrace blockchain, others ban it, and many are uncertain.

Impact: This creates legal uncertainty for businesses and users. Companies are hesitant to invest heavily in blockchain projects without clear regulatory guidance.

7. Privacy:

Blockchain is pseudonymous, not anonymous. All transactions are public, and addresses can often be traced to individuals through analysis.

Impact: This lack of privacy is a concern for users and businesses. Financial privacy is a basic expectation that blockchain doesn’t fulfill.

8. Cost:

Transaction fees can be prohibitively high during network congestion. Ethereum gas fees have exceeded $100 during periods of high demand.

Impact: This makes small transactions economically unviable. When transaction fees become too high, small payments become impractical. For example, sending $5 worth of tokens does not make sense if the network charges a $50 fee.

1.8 Blockchain Trilemma

The Blockchain Trilemma is the challenge of achieving three key properties simultaneously: decentralization, security, and scalability. This concept was popularized by Vitalik Buterin, co-founder of Ethereum, and describes a fundamental trade-off in blockchain design.

The Three Properties:

1. Decentralization:

Decentralization means that control is distributed across many participants rather than concentrated in a single entity. A decentralized blockchain has many nodes validating transactions, no single point of failure, and no central authority that can change the rules unilaterally.

Trade-off: Decentralization can reduce performance because all network participants must agree before confirming changes. The more nodes you have, the slower the process. More decentralization also means more data to process and store, making scalability harder.

2. Security:

Security means the blockchain is resistant to attacks. A secure blockchain requires significant resources to attack (e.g., 51% of mining power or stake). The cryptography is robust, and the consensus mechanism prevents tampering.

Trade-off: High security requires more computational resources (PoW) or more stake (PoS). This can limit scalability and may increase centralization because only participants with enough resources can operate effectively.

3. Scalability:

Scalability means the blockchain can process many transactions per second and handle growing usage. A scalable blockchain can process many transactions quickly, provide faster confirmations, and maintain affordable transaction costs..

Trade-off: High scalability often requires sacrificing some decentralization (fewer nodes, faster consensus) or some security (less robust validation). This is the fundamental tension.

The Trilemma Explained:

A blockchain can usually optimize only TWO of these three key properties at the same time. If you want high security and decentralization, you sacrifice scalability (Bitcoin). If you want high scalability and security, you sacrifice decentralization (Solana). If a blockchain focuses on high decentralization and scalability, it may compromise security because newer solutions are often less tested and proven.

How Different Blockchains Prioritize:

Bitcoin: Prioritizes Decentralization and Security, sacrificing Scalability.

  • 15,000+ nodes worldwide (decentralized)
  • Highly secure (PoW, 6 confirmations)
  • Only 7 TPS (not scalable)

Ethereum: Prioritizes Decentralization and Security, with moderate Scalability.

  • Thousands of nodes
  • Secure (PoS)
  • 15 TPS (better but still limited)

Solana: Prioritizes Scalability and Security, sacrificing Decentralization.

  • 3,000+ TPS (scalable)
  • Secure (PoS)
  • Fewer nodes (less decentralized)

Solutions to the Trilemma:

Layer 2 (L2) Solutions: Rollups process transactions off-chain and batch them to the main chain. This maintains decentralization and security while dramatically improving scalability. Examples: Arbitrum, Optimism, Polygon.

Sharding: Splitting the blockchain into smaller pieces (shards) that process transactions in parallel. This improves scalability while maintaining security and decentralization. Being implemented in Ethereum 2.0.

New Consensus Mechanisms: Proof of Stake (PoS) is more scalable and less energy-intensive than PoW while maintaining security. Delegated Proof of Stake (DPoS) improves transaction speed and efficiency by using selected validators, but it reduces the level of decentralization compared to traditional consensus methods.

Data Availability Solutions: Techniques like data availability sampling ensure that even with sharding, all data is available for verification. This improves scalability while maintaining security.

2. Blockchain Fundamentals

2.1 Distributed Ledger Technology (DLT)

Distributed Ledger Technology (DLT) is a digital system for recording transactions in which the records and their transaction data are replicated, shared, and synchronized across multiple locations, countries, or institutions. Blockchain is one specific form of Distributed Ledger Technology (DLT) that organizes data into linked blocks secured by cryptography.

The Core Concept:

DLT is the broader category of technologies that enable distributed databases. In a traditional centralized system, a single entity controls the database.In a Distributed Ledger Technology (DLT) network, several participants maintain identical copies of the ledger, and any changes are verified and synchronized using a consensus mechanism.the data, and all updates are synchronized through a consensus process.

Key Characteristics of DLT:

Shared Ledger: All network participants can access the same version of the stored information. Updates are recorded in the ledger only after consensus is reached among participants.

Decentralized Control: No single entity controls the ledger. Instead of relying on a single authority, control is shared among all participants in the network.

Immutable Records: Once recorded, data cannot be changed. This ensures trust and transparency, as the history of all transactions is permanent.

Cryptographic Security: Transactions are secured using cryptography. Each record is linked to previous records using cryptographic hashes, creating an unbreakable chain.

Types of DLT:

1. Blockchain:

The most well-known type of DLT. Data is organized into blocks, and each block is cryptographically linked to the previous one, forming a chain. Used by Bitcoin, Ethereum, and most cryptocurrencies.

Structure: Chain of blocks with cryptographic links.

Advantages: Immutable, secure, proven in production.

Disadvantages: Scalability limitations, high storage requirements.

Examples: Bitcoin, Ethereum, Solana.

2. Directed Acyclic Graph (DAG):

Instead of blocks, DAG uses a graph structure where each transaction references previous transactions. This eliminates the need for blocks and miners, enabling faster transactions.

Structure: Directed acyclic graph of transactions.

Advantages: Scalable, no miners, fast transactions.

Disadvantages: Less proven, complex verification.

Examples: IOTA (Tangle), Nano, Hedera.

3. Hashgraph:

A gossip protocol where nodes communicate through “gossip about gossip.” The protocol achieves consensus through virtual voting, making it extremely fast and fair.

Structure: Gossip protocol with DAG.

Advantages: Very fast, fair, secure.

Disadvantages: Not fully open, complex.

Examples: Hedera Hashgraph.

Comparison of DLT Types:

FeatureBlockchainDAGHashgraph
StructureChain of blocksDirected graphGossip + graph
SpeedMediumHighVery High
ScalabilityLimitedHighVery High
SecurityVery HighHighVery High
MaturityHighMediumLow
Energy UseHigh (PoW)LowLow

2.2 Blockchain Architecture

The Layered Architecture:

Blockchain architecture is organized into five distinct layers, each with specific functions and responsibilities. Understanding these layers is crucial for understanding how blockchain systems work.

Layer 1: Data Layer

The data layer is the foundation of the blockchain. It consists of the actual data stored on the blockchain – the blocks and transactions. This layer defines the data structures and how they are organized.

Components:

  • Blocks: The basic unit of storage, containing transactions and metadata
  • Transactions: The actual operations (transfers, smart contract calls)
  • Merkle Trees: Efficient verification of transaction integrity
  • Hash Functions: SHA-256, Keccak-256 for linking blocks

Purpose: To store data securely and immutably.

Layer 2: Network Layer

The network layer handles peer-to-peer communication between nodes. It defines how nodes discover each other, share data, and propagate transactions and blocks.

Components:

  • P2P Protocol: How nodes communicate (DevP2P, libp2p)
  • Node Discovery: How nodes find each other
  • Data Propagation: How transactions and blocks spread
  • Gossip Protocol: Information dissemination

Purpose: To enable distributed communication and synchronization.

Layer 3: Consensus Layer

The consensus layer is responsible for achieving agreement on the state of the blockchain. It defines the rules and mechanisms for validating transactions and adding blocks.

Components:

  • Consensus Mechanisms: PoW, PoS, PBFT, DPoS
  • Block Production: How blocks are created (mining, validation)
  • Finality: When transactions are irreversible
  • Fork Resolution: How to handle chain splits

Purpose: To ensure all nodes agree on the canonical state.

Layer 4: Smart Contract Layer

The smart contract layer enables programmable logic on the blockchain. It defines the virtual machine, languages, and execution environment for smart contracts.

Components:

  • Virtual Machine: Execution environment (EVM, WASM)
  • Programming Languages: Solidity, Vyper, Rust
  • State Management: Contract storage and execution
  • Gas System: Fee mechanism for computation

Purpose: To enable programmable, decentralized applications.

Layer 5: Application Layer

The application layer is the part of blockchain technology where users access and interact with blockchain-based services and applications. It includes user interfaces, dApps, wallets, and other tools that make blockchain usable.

Components:

  • dApps: Decentralized applications
  • Wallets: Key management and transaction creation
  • Interfaces: User-facing applications
  • APIs: Programmatic access

Purpose: To provide user interaction and utility.

How Data Flows Through the Layers:

  1. User interacts with an application (Layer 5)
  2. Application calls a smart contract (Layer 4)
  3. Smart contract creates transactions
  4. Consensus validates and orders transactions (Layer 3)
  5. Network broadcasts to all nodes (Layer 2)
  6. Data is stored in blocks (Layer 1)

2.3 Blockchain Components

Core Components of a Blockchain:

1. Blocks:

Blocks are the fundamental data containers in a blockchain. Each block contains a list of transactions, a timestamp, a reference to the previous block, and a cryptographic hash.

Purpose: Blocks organize and store transactions permanently and immutably.

Example: A Bitcoin block contains ~1MB of data and approximately 2,000 transactions.

2. Transactions:

Transactions are actions that update or modify the information stored on the blockchain.They represent transfers of value, smart contract executions, or other state changes.

Purpose: Transactions are the basic units of value transfPurpose: Transactions are the fundamental operations that transfer value and update the state of the blockchain.

Example: A transaction sending 1 BTC from Alice to Bob.

3. Consensus Mechanism:

The consensus mechanism is the algorithm that nodes use to agree on the state of the blockchain. It ensures that all nodes have the same view of the ledger.

Purpose: Consensus prevents double-spending and ensures network security.

Example: Proof of Work (Bitcoin), Proof of Stake (Ethereum).

4. Nodes:

Nodes are computers connected to the blockchain network that store, verify, and share blockchain data. They maintain copies of the blockchain, validate transactions, and propagate information.

Purpose: Nodes provide the distributed infrastructure and security.

Example: Full nodes, light nodes, validator nodes.

5. Cryptography:

Cryptography secures the blockchain through hashing, digital signatures, and encryption. It ensures transaction authenticity, data integrity, and privacy.

Purpose: Cryptography provides security and trust without intermediaries.

Example: SHA-256 hashing, ECDSA signatures.

6. Smart Contracts:

Smart contracts are automated programs stored on the blockchain that execute predefined actions when specific conditions are met. They automatically execute when predefined conditions are met.

Purpose: Smart contracts enable programmable, automated applications.

Example: ERC-20 token contracts, Uniswap exchange contracts.

7. Wallets:

Wallets are tools for managing private keys and interacting with the blockchain. They create transactions, sign them, and manage addresses.

Purpose: Wallets provide user control over blockchain assets.

Example: MetaMask (browser), Ledger (hardware).

2.4 Blocks

What is a Block?

A block is the fundamental data structure in a blockchain. It contains a collection of transactions, metadata about those transactions, and cryptographic links to the previous block. Blocks are the building blocks of the blockchain—they are the containers that organize and permanently store transaction data.

Block Structure:

Every block in a blockchain consists of three main parts:

1. Block Header:

The block header contains metadata about the block. It includes:

  • Version: The protocol version number
  • Previous Block Hash: The cryptographic hash of the previous block (32 bytes)
  • Merkle Root: The hash of all transactions in the block (32 bytes)
  • Timestamp: The time when the block was created (4 bytes)
  • Difficulty Target: The mining difficulty for this block (4 bytes)
  • Nonce: A random number used for mining (4 bytes)

2. Transaction List:

The transaction list contains all the transactions included in the block. Each transaction is a signed message authorizing a transfer of value or execution of code.

3. Block Size:

The total size of the block in bytes. Bitcoin blocks are limited to ~1MB. Ethereum blocks have variable size limited by gas.

How Blocks Form a Chain:

Each block contains the hash of the previous block, creating a chain:

Block 1 ← Block 2 ← Block 3 ← Block 4

If anyone tries to modify a previous block, its hash would change, breaking the chain and making the tampering detectable. This is what makes blockchain immutable.

Real-World Example – Bitcoin Block:

A typical Bitcoin block (#833,000):

  • Height: 833,000
  • Size: ~1.2 MB
  • Transactions: ~2,000
  • Miner: Foundry USA
  • Reward: 6.25 BTC + fees
  • Time: ~10 minutes after previous block
  • Hash: 00000000000000000005f8a3b2b4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9

Code Example – Block Implementation:

"""
BLOCK STRUCTURE
===============
Complete block implementation with mining
"""

import hashlib
import json
import time

class Block:
    def __init__(self, index, transactions, timestamp, previous_hash):
        # Block Header
        self.index = index
        self.version = 1
        self.transactions = transactions
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.nonce = 0
        self.difficulty = 0x1d00ffff

        # Calculate block hash
        self.hash = self.calculate_hash()
        self.merkle_root = self.calculate_merkle_root()

    def calculate_hash(self):
        """Calculate the SHA-256 hash of the block"""
        block_string = json.dumps({
            "index": self.index,
            "transactions": self.transactions,
            "timestamp": self.timestamp,
            "previous_hash": self.previous_hash,
            "nonce": self.nonce
        }, sort_keys=True)
        return hashlib.sha256(block_string.encode()).hexdigest()

    def calculate_merkle_root(self):
        """Calculate the Merkle root of all transactions"""
        if not self.transactions:
            return hashlib.sha256("empty".encode()).hexdigest()
        tx_string = json.dumps(self.transactions, sort_keys=True)
        return hashlib.sha256(tx_string.encode()).hexdigest()

    def mine_block(self, difficulty):
        """Proof of Work mining"""
        target = "0" * difficulty
        print(f" Mining block {self.index}...")

        start = time.time()
        while self.hash[:difficulty] != target:
            self.nonce += 1
            self.hash = self.calculate_hash()

        elapsed = time.time() - start
        print(f" Block mined! Nonce: {self.nonce}, Time: {elapsed:.2f}s")
        return self.hash

    def display(self):
        print("=" * 50)
        print(f" BLOCK #{self.index}")
        print("=" * 50)
        print("\nBLOCK HEADER:")
        print(f"  Version: {self.version}")
        print(f"  Previous Hash: {self.previous_hash[:16]}...")
        print(f"  Merkle Root: {self.merkle_root[:16]}...")
        print(f"  Timestamp: {time.ctime(self.timestamp)}")
        print(f"  Nonce: {self.nonce}")
        print(f"  Hash: {self.hash[:16]}...")
        print(f"\nTRANSACTIONS ({len(self.transactions)}):")
        for i, tx in enumerate(self.transactions, 1):
            print(f"  {i}. {tx.get('from', 'Unknown')} → {tx.get('to', 'Unknown')}: {tx.get('amount', 0)} coins")
        print(f"\nBLOCK SIZE: {len(json.dumps(self.__dict__))} bytes")

def demo_block():
    transactions = [
        {"from": "Alice", "to": "Bob", "amount": 10},
        {"from": "Bob", "to": "Charlie", "amount": 5}
    ]

    block = Block(1, transactions, time.time(), "0" * 64)
    block.display()
    print("\n" + "-" * 50)
    block.mine_block(3)
    block.display()

if __name__ == "__main__":
    demo_block()

2.5 Block Header

What is a Block Header?

The block header is the metadata section of a block. It contains information about the block itself, including the cryptographic links that make the blockchain secure and immutable. The header is separate from the transactions—it describes the block while the transactions contain the actual data.

Why the Block Header Matters:

The block header is critical because:

  1. It links blocks together (previous block hash)
  2. It verifies all transactions (merkle root)
  3. It proves computational work (nonce and difficulty)
  4. It provides timing information (timestamp)
  5. It contains the consensus information

Block Header Fields:

1. Version (4 bytes):

The version number indicates which protocol rules this block follows. It’s used for network upgrades and ensures all nodes follow the same rules.

Example: Bitcoin version 0x20000000 (segwit enabled)

2. Previous Block Hash (32 bytes):

This is the double SHA-256 hash of the previous block’s header. This creates the chain—each block references the previous block, making the blockchain a linked list of blocks. If anyone tries to change a previous block, this hash would no longer match, and the network would reject the chain.

Example: 00000000000000000005f8a3b2b4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9

3. Merkle Root (32 bytes):

The Merkle root is a hash of all transaction hashes in the block, organized in a Merkle tree. This allows efficient verification of transactions—you can prove a transaction is in the block by providing a small Merkle proof, without downloading the entire block.

Example: 0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1

4. Timestamp (4 bytes):

The timestamp is the approximate time when the block was created. It’s used for preventing tampering (must be after the previous block) and for the difficulty adjustment algorithm.

Example: 1704067200 (January 1, 2024)

5. Difficulty Target (4 bytes):

ThThis is the required value that a block hash must be below to meet the network’s mining difficulty requirement. It controls how hard mining is. The difficulty adjusts every 2016 blocks to ensure blocks are found approximately every 10 minutes.

Example: 0x170f0e1d

6. Nonce (4 bytes):

A random number that miners change to try to find a valid block hash. When a block hash generated with a valid nonce is lower than the required target value, the block is considered valid and can be added to the blockchain. billions of nonces to find a valid hash.

Example: 0x1a2b3c4d

Merkle Root Calculation:

The Merkle root is created by repeatedly combining and hashing pairs of transaction hashes until a single hash value remains.

Transaction Hashes:
Tx1: Hash1
Tx2: Hash2
Tx3: Hash3
Tx4: Hash4

Step 1: Hash12 = Hash(Hash1 + Hash2)
Step 2: Hash34 = Hash(Hash3 + Hash4)
Step 3: Merkle Root = Hash(Hash12 + Hash34)

This creates a binary tree where the root represents all transactions.

Code Example – Block Header:

"""
BLOCK HEADER
============
Complete block header implementation
"""

import struct
import hashlib
import time

class BlockHeader:
    def __init__(self):
        self.version = 1
        self.previous_hash = "0" * 64
        self.merkle_root = "0" * 64
        self.timestamp = int(time.time())
        self.difficulty = 0x1d00ffff
        self.nonce = 0

    def get_header_bytes(self):
        """Convert header to bytes for hashing"""
        # Version (4 bytes, little endian)
        header = struct.pack('<I', self.version)
        # Previous block hash (32 bytes, reversed)
        header += bytes.fromhex(self.previous_hash)[::-1]
        # Merkle root (32 bytes, reversed)
        header += bytes.fromhex(self.merkle_root)[::-1]
        # Timestamp (4 bytes, little endian)
        header += struct.pack('<I', self.timestamp)
        # Difficulty (4 bytes, little endian)
        header += struct.pack('<I', self.difficulty)
        # Nonce (4 bytes, little endian)
        header += struct.pack('<I', self.nonce)
        return header

    def calculate_hash(self):
        """Calculate double SHA-256 of the block header"""
        header_bytes = self.get_header_bytes()
        hash1 = hashlib.sha256(header_bytes).digest()
        hash2 = hashlib.sha256(hash1).digest()
        # Reverse for Bitcoin convention
        return hash2[::-1].hex()

    def mine(self, difficulty):
        """Mine the block header"""
        target = "0" * difficulty
        print(f" Mining header with difficulty {difficulty}...")

        start = time.time()
        attempts = 0

        while self.calculate_hash()[:difficulty] != target:
            self.nonce += 1
            attempts += 1
            if attempts % 10000 == 0:
                print(f"  Attempt {attempts}: {self.calculate_hash()[:8]}...", end="\r")

        elapsed = time.time() - start
        print(f"\n Mined! Nonce: {self.nonce}, Time: {elapsed:.2f}s, Attempts: {attempts}")
        return self.calculate_hash()

    def display(self):
        print("=" * 50)
        print("BLOCK HEADER")
        print("=" * 50)
        print("\nHEADER FIELDS:")
        print(f"  Version: {self.version}")
        print(f"  Previous Block Hash: {self.previous_hash[:16]}...")
        print(f"  Merkle Root: {self.merkle_root[:16]}...")
        print(f"  Timestamp: {time.ctime(self.timestamp)}")
        print(f"  Difficulty Target: {hex(self.difficulty)}")
        print(f"  Nonce: {self.nonce}")
        print(f"  Block Hash: {self.calculate_hash()[:16]}...")
        print(f"\nHEADER SIZE: {len(self.get_header_bytes())} bytes")

def demo_header():
    header = BlockHeader()
    header.display()
    print("\n" + "-" * 50)
    header.mine(3)
    header.display()

    print("\n" + "=" * 50)
    print("HEADER FIELDS EXPLANATION:")
    print("=" * 50)
    print("""
 Version:     Protocol version for upgrades
 Prev Hash:   Links to previous block (creates chain)
 Merkle Root: Hash of all transactions (verifies data)
 Timestamp:   Block creation time (prevents tampering)
 Difficulty:  Mining target (controls block time)
 Nonce:       Random number (Proof of Work)
    """)

if __name__ == "__main__":
    demo_header()

2.6 Genesis Block

What is the Genesis Block?

The genesis block is the very first block created in a blockchain network and serves as the foundation for all following blocks. It is hardcoded into the blockchain’s software and has no previous block to reference. This block is the starting point of the entire blockchain—all subsequent blocks trace their lineage back to this single block.

Why is the Genesis Block Special?

No Previous Block: Unlike all other blocks, the genesis block doesn’t have a previous block hash. It uses a placeholder (e.g., 64 zeros). This is because there is no block before it.

Hardcoded: The genesis block is embedded in the blockchain’s source code. Every node that joins the network must have the same genesis block. If a node has a different genesis block, it’s on a different blockchain.

Historical Message: Many genesis blocks contain a special message or timestamp. This serves as proof that the blockchain existed at a certain time (prevents backdating) and often contains a commentary on current events.

Unspendable Rewards: The mining reward from the genesis block is often unspendable. In Bitcoin, the 50 BTC reward from the genesis block can never be spent (it’s hardcoded as unspendable).

Bitcoin Genesis Block (Block 0):

The first block ever created by Satoshi Nakamoto:

  • Timestamp: January 3, 2009, 18:15:05 UTC
  • Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
  • Message: “The Times 03/Jan/2009 Chancellor on brink of second bailout for banks” was included in Bitcoin’s genesis block as a reference to the financial crisis and the need for an alternative financial system.
  • Reward: 50 BTC (unspendable)
  • Nonce: 2083236893
  • Difficulty: 1

Why the Message Matters:

The message in the Bitcoin genesis block is:

  1. Proof of Existence: It proves that the block was created after January 3, 2009
  2. Historical Significance: It references a real newspaper headline from that date
  3. Political Statement: It comments on the financial system’s instability and the need for an alternative

Ethereum Genesis Block:

The first block of the Ethereum network:

  • Timestamp: July 30, 2015, 15:26:13 UTC
  • Hash: 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3
  • Message: “A prelude to all that is great”
  • Reward: 5 ETH
  • Nonce: 5840239993216924760

Code Example – Genesis Block:

"""
ORIGIN BLOCK EXPLORATION
========================
Comprehensive analysis of foundational ledger blocks across major networks
"""

class OriginBlockExplorer:
    def __init__(self):
        self.origin_registry = {
            "Bitcoin": {
                "birth": "2009-01-03 18:15:05",
                "fingerprint": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
                "inscription": "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks",
                "compensation": "50 BTC",
                "architect": "Satoshi Nakamoto",
                "puzzle_solution": "2083236893",
                "complexity": "1"
            },
            "Ethereum": {
                "birth": "2015-07-30 15:26:13",
                "fingerprint": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
                "inscription": "A prelude to all that is great",
                "compensation": "5 ETH",
                "architect": "Vitalik Buterin",
                "puzzle_solution": "5840239993216924760",
                "complexity": "17171480576"
            }
        }

    def inspect_origin(self, network="Bitcoin"):
        """Examine origin block details for a specific network"""
        details = self.origin_registry.get(network)
        if not details:
            print(f"❌ Network not found: {network}")
            return

        print("=" * 70)
        print(f" ORIGIN BLOCK ANALYSIS - {network.upper()}")
        print("=" * 70)
        print(f"\n⏰ BIRTH TIMESTAMP: {details['birth']}")
        print(f"🔐 FINGERPRINT: {details['fingerprint']}")
        print(f"📝 INSCRIPTION: \"{details['inscription']}\"")
        print(f"💰 COMPENSATION: {details['compensation']}")
        print(f"👤 ARCHITECT: {details['architect']}")
        print(f"🧩 PUZZLE SOLUTION: {details['puzzle_solution']}")
        print(f"📊 COMPLEXITY: {details['complexity']}")

    def enumerate_all_origins(self):
        """Catalog all known origin blocks"""
        print("=" * 70)
        print(" KNOWN ORIGIN BLOCKS INVENTORY")
        print("=" * 70)

        for network in self.origin_registry:
            details = self.origin_registry[network]
            print(f"\n {network.upper()}:")
            print(f"   ⏰ Birth: {details['birth']}")
            print(f"   📝 Inscription: {details['inscription'][:45]}...")
            print(f"   💰 Compensation: {details['compensation']}")
            print(f"   👤 Architect: {details['architect']}")

    def interpret_inscriptions(self):
        """Decode the historical significance of origin messages"""
        print("\n" + "=" * 70)
        print(" ORIGIN INSCRIPTION INTERPRETATION")
        print("=" * 70)

        btc_inscription = self.origin_registry["Bitcoin"]["inscription"]
        eth_inscription = self.origin_registry["Ethereum"]["inscription"]

        print(f"\n📰 Bitcoin Origin Inscription:")
        print(f"  \"{btc_inscription}\"")
        print("\n  ◆ Front page headline from The Times, January 3, 2009")
        print("  ◆ Documents the global financial crisis context")
        print("  ◆ Provides timestamp proof-of-existence")
        print("  ◆ Serves as permanent historical anchor")
        print("  ◆ Commentary on need for alternative monetary systems")

        print(f"\n🚀 Ethereum Origin Inscription:")
        print(f"  \"{eth_inscription}\"")
        print("\n  ◆ Signals the dawn of programmable distributed systems")
        print("  ◆ Represents vision beyond simple value transfer")
        print("  ◆ Sets stage for smart contract paradigm")
        print("  ◆ Philosophical foundation for decentralized applications")

class OriginBlockSignificance:
    """Analyze the broader meaning and impact of origin blocks"""
    
    @staticmethod
    def evaluate_historical_impact():
        """Assess the historical significance of origin blocks"""
        print("\n" + "=" * 70)
        print(" ORIGIN BLOCK HISTORICAL IMPACT ASSESSMENT")
        print("=" * 70)
        
        significance_factors = {
            "Factor": ["Technological", "Economic", "Social", "Political", "Philosophical"],
            "Bitcoin Impact": ["Revolutionary", "Alternative Currency", "Decentralization", "Cryptographic Sovereignty", "Trust-minimized Systems"],
            "Ethereum Impact": ["Programmable Ledger", "Smart Contracts", "Token Economy", "Decentralized Governance", "Computational Primitive"]
        }
        
        print(f"\n {'Factor':15} | {'Bitcoin':25} | {'Ethereum':25}")
        print("-" * 70)
        
        for i in range(len(significance_factors["Factor"])):
            factor = significance_factors["Factor"][i]
            btc_impact = significance_factors["Bitcoin Impact"][i]
            eth_impact = significance_factors["Ethereum Impact"][i]
            print(f" {factor:15} | {btc_impact:25} | {eth_impact:25}")
        
        print("\n" + "=" * 70)

class OriginBlockTechnicalAnalysis:
    """Technical examination of origin block properties"""
    
    @staticmethod
    def examine_cryptographic_properties():
        """Analyze cryptographic characteristics of origin blocks"""
        print("\n" + "=" * 70)
        print(" ORIGIN BLOCK CRYPTOGRAPHIC PROPERTIES")
        print("=" * 70)
        
        print("\n🔑 Cryptographic Characteristics:")
        print("  • SHA-256 hashing algorithm (Bitcoin)")
        print("  • Keccak-256 hashing algorithm (Ethereum)")
        print("  • Complete hash preimage computational requirements")
        print("  • Difficulty adjustment starting points")
        print("  • Nonce discovery for proof-of-work validation")
        print("  • Chain of trust foundation establishment")
        
        print("\n📊 Genesis Block Mathematical Properties:")
        print("  • Zero prior reference (indicated by null hash)")
        print("  • Block height starts at zero index")
        print("  • Foundational difficulty setting")
        print("  • Initial reward specifications")
        print("  • Empty transaction pool at initialization")
        
        print("\n" + "=" * 70)

def demonstrate_origin_exploration():
    """Execute comprehensive origin block investigation"""
    print("\n" + "=" * 70)
    print(" ORIGIN BLOCK EXPLORATION TOOL")
    print("=" * 70)
    
    # Primary exploration
    explorer = OriginBlockExplorer()
    explorer.inspect_origin("Bitcoin")
    print("\n" + "-" * 70)
    explorer.inspect_origin("Ethereum")
    
    # Additional analyses
    explorer.enumerate_all_origins()
    explorer.interpret_inscriptions()
    
    # Advanced perspectives
    OriginBlockSignificance.evaluate_historical_impact()
    OriginBlockTechnicalAnalysis.examine_cryptographic_properties()
    
    print("\n" + "=" * 70)
    print(" ORIGIN BLOCK EXPLORATION COMPLETE")
    print("=" * 70 + "\n")

if __name__ == "__main__":
    demonstrate_origin_exploration()

2.7 Transactions

What is a Transaction?

A transaction is a signed message authorizing a transfer of value or execution of code on the blockchain. It is the basic unit of activity on the blockchain—the operation that changes the state of the network.

Transaction Components:

1. From (Sender):

The address of the sender. This identifies who is sending the value or initiating the operation. The sender must have enough balance or the required permission to authorize and complete the transaction.

Example: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e

2. To (Recipient):

The address of the recipient. For value transfers, this is the destination address. For smart contract calls, this is the contract address.

Example: 0x9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWVH

3. Amount:

The value being transferred. For Ethereum, this is measured in ETH (or wei). For Bitcoin, in BTC (or satoshis).

Example: 1.5 ETH

4. Gas:

The maximum amount of gas the sender is willing to pay for the transaction.Gas is a unit used to measure the amount of computational work required to execute operations on the blockchain. More complex operations (smart contract calls) require more gas.

Example: 21000 (for a simple ETH transfer)

5. Gas Price:

The price the sender is willing to pay for each unit of gas used in a transaction. This is measured in Gwei (1 Gwei = 10^-9 ETH). Higher gas prices prioritize the transaction.

Example: 50 Gwei

6. Nonce:

A number that keeps track of transactions from an address. The nonce starts at 0 and increments with each transaction sent. This prevents double-spending attacks and ensures that transactions are verified and recorded in the correct order.

Example: 5 (fifth transaction from this address)

7. Signature:

A cryptographic signature proving that the transaction was authorized by the owner of the private key. This prevents others from sending transactions on your behalf.

Example: 0xabcd1234...

8. Data:

Additional data included in the transaction. For smart contract calls, this contains the function name and parameters. For simple transfers, this is often empty.

Example: 0x095ea7b3... (ERC-20 approve function)

Transaction Flow:

  1. User creates transaction in their wallet
  2. Wallet signs transaction with private key
  3. Signed transaction is broadcast to the network
  4. Nodes validate the transaction
  5. Miners/validators include it in a block
  6. Transaction is confirmed when the block is added to the chain

Code Example – Transaction:

"""
DISTRIBUTED LEDGER OPERATION FRAMEWORK
=======================================
Complete implementation of value transfer operations with cryptographic verification
"""

import hashlib
import json
import time
from typing import Optional, Dict, Any

class ValueTransferOperation:
    """Represents a cryptographic value transfer between parties"""
    
    def __init__(self, origin: str, destination: str, value: float, 
                 computational_budget: int = 21000, unit_price: int = 50):
        self.origin = origin
        self.destination = destination
        self.value = value
        self.computational_budget = computational_budget
        self.unit_price = unit_price
        self.sequence_number = 0
        self.payload = ""
        self.cryptographic_mark = None
        self.creation_timestamp = time.time()
        self.operation_hash = None
        self.state = "Queued"

    def generate_operation_hash(self) -> str:
        """Compute cryptographic fingerprint of the operation"""
        operation_data = {
            "origin": self.origin,
            "destination": self.destination,
            "value": self.value,
            "computational_budget": self.computational_budget,
            "unit_price": self.unit_price,
            "sequence_number": self.sequence_number,
            "payload": self.payload,
            "creation_timestamp": self.creation_timestamp
        }
        return hashlib.sha256(json.dumps(operation_data, sort_keys=True).encode()).hexdigest()

    def apply_cryptographic_mark(self, secret_key: str) -> str:
        """Digitally sign the operation using a private key"""
        self.operation_hash = self.generate_operation_hash()
        self.cryptographic_mark = hashlib.sha256((secret_key + self.operation_hash).encode()).hexdigest()
        self.state = "Authenticated"
        return self.cryptographic_mark

    def validate_cryptographic_mark(self) -> bool:
        """Verify the cryptographic signature authenticity"""
        if not self.cryptographic_mark:
            return False
        return True

    def calculate_network_fee(self) -> float:
        """Compute the network transaction fee"""
        return (self.computational_budget * self.unit_price) / 1e9

    def compute_total_expense(self) -> float:
        """Calculate complete cost including fees"""
        return self.value + self.calculate_network_fee()

    def present_details(self):
        """Display comprehensive operation information"""
        print("=" * 60)
        print(" VALUE TRANSFER OPERATION DETAILS")
        print("=" * 60)
        print(f"\n🔑 Operation Hash: {self.operation_hash[:16] if self.operation_hash else 'Not authenticated'}...")
        print(f"📤 Origin: {self.origin[:16]}...")
        print(f"📥 Destination: {self.destination[:16]}...")
        print(f"💰 Value: {self.value} Units")
        print(f"⚙️  Computational Budget: {self.computational_budget}")
        print(f"💲 Unit Price: {self.unit_price} Gwei")
        print(f"🧾 Network Fee: {self.calculate_network_fee():.6f} Units")
        print(f"💵 Total Expense: {self.compute_total_expense():.6f} Units")
        print(f"🔢 Sequence Number: {self.sequence_number}")
        print(f"📊 Status: {self.state}")
        print(f"✍️  Signature: {self.cryptographic_mark[:16] if self.cryptographic_mark else 'None'}...")
        print(f"🕐 Timestamp: {time.ctime(self.creation_timestamp)}")

class OperationFactory:
    """Factory for creating and managing value transfer operations"""
    
    def __init__(self):
        self.sequence_tracker = {}

    def construct_operation(self, origin: str, destination: str, value: float, 
                           payload: str = "", budget: int = 21000, price: int = 50) -> ValueTransferOperation:
        """Create a new operation with automatic sequence management"""
        if origin not in self.sequence_tracker:
            self.sequence_tracker[origin] = 0

        operation = ValueTransferOperation(origin, destination, value, budget, price)
        operation.sequence_number = self.sequence_tracker[origin]
        operation.payload = payload
        self.sequence_tracker[origin] += 1
        return operation

class TransactionAnalysis:
    """Additional analysis and utilities for transactions"""
    
    @staticmethod
    def compare_transaction_types():
        """Compare different transaction characteristics"""
        print("\n" + "=" * 60)
        print(" TRANSACTION TYPE COMPARISON")
        print("=" * 60)
        
        transaction_types = {
            "Simple Transfer": {"Speed": "High", "Cost": "Low", "Complexity": "Simple", "Use Case": "Peer-to-peer"},
            "Smart Contract": {"Speed": "Medium", "Cost": "Variable", "Complexity": "Complex", "Use Case": "Programmable"},
            "Batch Transfer": {"Speed": "Medium", "Cost": "Optimized", "Complexity": "Medium", "Use Case": "Bulk operations"},
            "Cross-Chain": {"Speed": "Low", "Cost": "High", "Complexity": "Very Complex", "Use Case": "Interoperability"}
        }
        
        print(f"\n {'Type':18} | {'Speed':10} | {'Cost':12} | {'Complexity':14} | {'Use Case':15}")
        print("-" * 75)
        
        for tx_type, characteristics in transaction_types.items():
            print(f" {tx_type:18} | {characteristics['Speed']:10} | {characteristics['Cost']:12} | "
                  f"{characteristics['Complexity']:14} | {characteristics['Use Case']:15}")
    
    @staticmethod
    def analyze_fee_structures():
        """Analyze different fee models"""
        print("\n" + "=" * 60)
        print(" FEE STRUCTURE ANALYSIS")
        print("=" * 60)
        
        print("\n📊 Fee Models Comparison:")
        print("  • Fixed Fee: Constant cost regardless of network conditions")
        print("  • Dynamic Fee: Adjusts based on network congestion")
        print("  • Priority Fee: Higher cost for faster confirmation")
        print("  • Gas-Based: Cost depends on computational complexity")
        
        print("\n⏱️  Timing Considerations:")
        print("  • Low Fee: 1-2 hour confirmation window")
        print("  • Standard Fee: 10-30 minute confirmation")
        print("  • High Fee: 1-5 minute confirmation")
        print("  • Priority Fee: 10-60 second confirmation")

def demonstrate_operation_workflow():
    """Execute comprehensive transaction demonstration"""
    print("\n" + "=" * 60)
    print(" VALUE TRANSFER OPERATION WORKFLOW DEMONSTRATION")
    print("=" * 60)

    # Initialize factory
    factory = OperationFactory()
    
    # Create a sample operation
    operation = factory.construct_operation(
        "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "0x9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWVH",
        1.5,
        payload="Sample transfer"
    )

    # Display before signing
    print("\n📋 BEFORE CRYPTOGRAPHIC AUTHENTICATION:")
    operation.present_details()
    
    # Sign the operation
    print("\n" + "-" * 60)
    print("✍️  APPLYING CRYPTOGRAPHIC MARK...")
    operation.apply_cryptographic_mark("private_key_123")
    
    # Display after signing
    print("\n📋 AFTER CRYPTOGRAPHIC AUTHENTICATION:")
    operation.present_details()
    
    # Additional analysis
    TransactionAnalysis.compare_transaction_types()
    TransactionAnalysis.analyze_fee_structures()

if __name__ == "__main__":
    demonstrate_operation_workflow()

2.8 Transaction Lifecycle

The Journey of a Transaction:

A transaction goes through several stages from creation to final confirmation. Understanding this lifecycle is crucial for understanding how blockchain networks operate.

1. Creation:

The user creates a transaction using their wallet. They specify the recipient, amount, gas, and other parameters. The transaction is not yet signed.

2. Signing:

The wallet signs the transaction with the user’s private key. This creates a cryptographic signature that proves the transaction was authorized by the owner. Once digitally signed, the transaction is ready to be broadcast to the blockchain network for verification and processing.

3. Broadcast:

The signed transaction is broadcast to the blockchain network. It’s sent to one or more nodes (typically through a public RPC endpoint or peer-to-peer network).

4. Validation:

Nodes validate the transaction:

  • Check the signature is valid
  • Check the sender has sufficient balance
  • Check the nonce is correct
  • Check the gas is sufficient

If valid, the transaction enters the mempool.

5. Mempool:

The transaction waits in the mempool (memory pool). Transactions are ordered by gas price—higher gas prices get prioritized. The transaction remains in the mempool until selected by a miner/validator.

6. Selection:

Miners or validators select pending transactions from the mempool and include them in the next block for verification and confirmation. They prioritize transactions with higher gas prices to maximize their revenue.

7. Inclusion:

The transaction is included in a block. This is the first “confirmation.” The block is broadcast to the network.

8. Confirmation:

As more blocks are added to the chain, the transaction gets more confirmations. Each block adds one confirmation. The more confirmations, the more certain the transaction is irreversible.

9. Finality:

The transaction is considered final when it has enough confirmations. For Bitcoin, 6 confirmations is standard (~1 hour). For Ethereum, finality occurs with 2-3 confirmations (~6-15 minutes).

Code Example – Lifecycle:

"""
VALUE TRANSFER JOURNEY FRAMEWORK
=================================
Complete simulation of cryptographic operation progression from creation to finality
"""

import time
from enum import Enum
from typing import Dict, List, Optional

class ProgressionPhase(Enum):
    """Defines the evolutionary stages of a value transfer operation"""
    INITIATED = "Initiated"
    AUTHENTICATED = "Authenticated"
    PROPAGATED = "Propagated"
    VERIFIED = "Verified"
    QUEUED = "Queued"
    SELECTED = "Selected"
    INCORPORATED = "Incorporated"
    VALIDATED = "Validated"
    SETTLED = "Settled (Irreversible)"

class OperationJourneyTracker:
    """Tracks the complete lifecycle of a cryptographic operation"""
    
    def __init__(self, operation_reference: str):
        self.operation_reference = operation_reference
        self.current_phase = ProgressionPhase.INITIATED
        self.phase_timestamps: Dict[ProgressionPhase, float] = {self.current_phase: time.time()}
        self.validation_count = 0
        self.required_validations = 6
        self.phase_messages = {
            ProgressionPhase.INITIATED: "Operation created in client application",
            ProgressionPhase.AUTHENTICATED: "Cryptographic signature applied",
            ProgressionPhase.PROPAGATED: "Distributed to network participants",
            ProgressionPhase.VERIFIED: "Consensus validation completed",
            ProgressionPhase.QUEUED: "Pending in transaction pool",
            ProgressionPhase.SELECTED: "Chosen for inclusion by validator",
            ProgressionPhase.INCORPORATED: "Added to distributed ledger block",
            ProgressionPhase.VALIDATED: "Network confirmation received",
            ProgressionPhase.SETTLED: "Permanently recorded - irreversible"
        }

    def advance_to_phase(self, new_phase: ProgressionPhase) -> None:
        """Transition to the next phase in the journey"""
        self.current_phase = new_phase
        self.phase_timestamps[new_phase] = time.time()

        if new_phase == ProgressionPhase.VALIDATED:
            self.validation_count += 1

    def calculate_phase_duration(self, phase: ProgressionPhase) -> float:
        """Compute time elapsed in a specific phase"""
        if phase in self.phase_timestamps:
            return time.time() - self.phase_timestamps[phase]
        return 0.0

    def check_finality(self) -> bool:
        """Determine if the operation has achieved finality"""
        return self.validation_count >= self.required_validations

    def render_journey(self) -> None:
        """Display the complete operation journey"""
        print("\n" + "=" * 60)
        print(f"OPERATION JOURNEY: {self.operation_reference[:16]}...")
        print("=" * 60)

        print("\n 📊 Progress Timeline:")
        print("-" * 50)

        for phase in ProgressionPhase:
            if phase in self.phase_timestamps:
                marker = "▶" if phase == self.current_phase else " "
                duration = self.calculate_phase_duration(phase)
                print(f"  {marker} {phase.value:25} {duration:7.1f}s")
                if phase == ProgressionPhase.VALIDATED:
                    print(f"       Confirmations: {self.validation_count}/{self.required_validations}")
                print(f"       {self.phase_messages[phase]}")
            elif phase == self.current_phase:
                print(f"  ▶ {phase.value:25} (current phase)")
                print(f"       {self.phase_messages[phase]}")

        print(f"\n 📈 Journey Summary:")
        print(f"  Total duration: {self.calculate_total_duration():.1f} seconds")
        print(f"  Confirmations: {self.validation_count}/{self.required_validations}")
        print(f"  Finality achieved: {'✅ Yes' if self.check_finality() else '⏳ No'}")

    def calculate_total_duration(self) -> float:
        """Compute total time from initiation to current phase"""
        if ProgressionPhase.INITIATED in self.phase_timestamps:
            return time.time() - self.phase_timestamps[ProgressionPhase.INITIATED]
        return 0.0

class JourneySimulationEngine:
    """Simulates the progression of operations through phases"""
    
    @staticmethod
    def execute_simulation():
        """Run complete journey simulation"""
        print("=" * 60)
        print(" OPERATION JOURNEY SIMULATION")
        print("=" * 60)

        operation_id = "0x9a8b7c6d5e4f3g2h1i0j9k8l7m6n5o4p3q2r1s0t9u8v7w6x5y4z3a2b1c0d9e8f"
        tracker = OperationJourneyTracker(operation_id)

        # Define the journey sequence
        journey_sequence = [
            ProgressionPhase.AUTHENTICATED,
            ProgressionPhase.PROPAGATED,
            ProgressionPhase.VERIFIED,
            ProgressionPhase.QUEUED,
            ProgressionPhase.SELECTED,
            ProgressionPhase.INCORPORATED,
        ]

        # Add validation confirmations
        for _ in range(6):
            journey_sequence.append(ProgressionPhase.VALIDATED)

        journey_sequence.append(ProgressionPhase.SETTLED)

        # Execute the journey with timing
        print("\n 🚀 Initiating operation journey...")
        for phase in journey_sequence:
            time.sleep(0.8)
            tracker.advance_to_phase(phase)
            print(f"  → Phase transition: {phase.value}")

        # Display final journey details
        tracker.render_journey()

class JourneyPhaseAnalyzer:
    """Additional analysis of journey phases and timing"""
    
    @staticmethod
    def compare_phase_durations():
        """Compare typical durations for different phases"""
        print("\n" + "=" * 60)
        print(" PHASE DURATION ANALYSIS")
        print("=" * 60)
        
        phase_durations = {
            "Initiation Phase": {"Low": "0.1s", "Typical": "0.5s", "High": "1s", "Description": "Client creation"},
            "Authentication Phase": {"Low": "0.05s", "Typical": "0.1s", "High": "0.3s", "Description": "Signature generation"},
            "Propagation Phase": {"Low": "0.5s", "Typical": "2s", "High": "5s", "Description": "Network broadcast"},
            "Verification Phase": {"Low": "0.2s", "Typical": "1s", "High": "3s", "Description": "Initial validation"},
            "Queue Phase": {"Low": "1s", "Typical": "30s", "High": "300s", "Description": "Mempool waiting"},
            "Selection Phase": {"Low": "5s", "Typical": "15s", "High": "60s", "Description": "Validator selection"},
            "Incorporation Phase": {"Low": "2s", "Typical": "5s", "High": "15s", "Description": "Block addition"},
            "Validation Phase": {"Low": "30s", "Typical": "300s", "High": "3600s", "Description": "Network confirmations"},
            "Settlement Phase": {"Low": "60s", "Typical": "600s", "High": "7200s", "Description": "Finality achievement"}
        }
        
        print("\n 📊 Phase Duration Metrics:")
        print(f" {'Phase':25} | {'Typical':10} | {'Description':20}")
        print("-" * 60)
        
        for phase, metrics in phase_durations.items():
            print(f" {phase:25} | {metrics['Typical']:10} | {metrics['Description']:20}")

def demonstrate_journey_framework():
    """Execute comprehensive journey demonstration"""
    print("\n" + "=" * 60)
    print(" VALUE TRANSFER JOURNEY FRAMEWORK DEMONSTRATION")
    print("=" * 60)
    
    # Execute main simulation
    JourneySimulationEngine.execute_simulation()
    
    # Additional analysis
    JourneyPhaseAnalyzer.compare_phase_durations()
    
    print("\n" + "=" * 60)
    print(" JOURNEY FRAMEWORK DEMONSTRATION COMPLETE")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_journey_framework()

2.9 Mempool

What is the Mempool?

The mempool (memory pool) is where pending transactions wait to be included in a block. It’s a temporary storage area for unconfirmed transactions that have been validated but not yet mined.

Why is the Mempool Important?

Temporary Storage: Transactions that are valid but not yet in a block are stored in the mempool. This prevents them from being lost if they’re not immediately mined.

Fee Prioritization: The mempool organizes transactions by gas price/fee. Miners select the highest-fee transactions first, creating a competitive market for block space.

Network Propagation: The mempool ensures transactions are propagated across the network before being mined, allowing all nodes to see pending transactions.

How Mempool Works:

1. Receiving:

New transactions are broadcasted to the network. Nodes receive these transactions from peers or directly from users.

2. Validation:

Nodes validate each transaction:

  • Verify the signature is valid
  • Check the sender has sufficient balance
  • Ensure the nonce is correct
  • Verify the gas is sufficient

3. Storage:

Valid transactions are added to the mempool. Each node maintains its own mempool, which may differ slightly from other nodes (mempool is not globally synchronized).

4. Ordering:

Transactions are ordered by gas price/fee. Higher fees get priority for inclusion in the next block. This creates a market where users bid for block space.

5. Selection:

Miners or validators choose pending transactions from the mempool and add them to the next block for validation and inclusion in the blockchain. They typically choose the highest-fee transactions to maximize revenue.

6. Removal:

When a transaction is included in a block, it’s removed from the mempool. Transactions that remain in the mempool too long may be dropped (mempool expiry).

Mempool Dynamics:

Congestion: When the network is busy, the mempool fills up with transactions. This drives up fees as users compete for limited block space.

Spikes: During high-demand periods (e.g., NFT launches, airdrops), the mempool can contain hundreds of thousands of transactions, causing fees to spike dramatically.

Replace-By-Fee (RBF): Users can replace a pending transaction with a new one with a higher fee. This allows users to “bump” the fee to get their transaction included faster.

Code Example – Mempool:

"""
PENDING OPERATION POOL FRAMEWORK
=================================
Complete simulation of transaction queuing and prioritization system
"""

import time
import heapq
from typing import Dict, List, Optional, Tuple

class OperationPool:
    """Manages pending value transfer operations with priority-based selection"""
    
    def __init__(self, capacity_limit: int = 100, retention_period: int = 300):
        self.capacity_limit = capacity_limit
        self.retention_period = retention_period
        self.operation_registry: Dict[str, Dict] = {}
        self.priority_heap: List[Tuple[float, float, str]] = []
        self.metrics = {
            "total_submitted": 0,
            "total_processed": 0,
            "total_expired": 0,
            "peak_occupancy": 0
        }
        print(f" 🔄 Operation Pool initialized: capacity={capacity_limit}, retention={retention_period}s")

    def submit_operation(self, operation: Dict) -> bool:
        """Add a new operation to the pending pool"""
        if not self._validate_operation(operation):
            return False

        operation_id = operation.get("id", f"op_{int(time.time())}")

        if operation_id in self.operation_registry:
            print(f" ⚠️  Operation {operation_id[:16]}... already exists in pool")
            return False

        if len(self.operation_registry) >= self.capacity_limit:
            print(f" ❌ Pool at capacity ({self.capacity_limit} operations)")
            return False

        # Store operation
        self.operation_registry[operation_id] = operation
        priority_score = operation.get("priority", 0.001)
        heapq.heappush(self.priority_heap, (-priority_score, time.time(), operation_id))

        self.metrics["total_submitted"] += 1
        self.metrics["peak_occupancy"] = max(self.metrics["peak_occupancy"], len(self.operation_registry))

        print(f" ✅ Operation submitted: {operation_id[:16]}... priority: {priority_score} units")
        return True

    def _validate_operation(self, operation: Dict) -> bool:
        """Verify operation has required fields and valid values"""
        required_fields = ["origin", "destination", "value"]
        for field in required_fields:
            if field not in operation:
                print(f" ❌ Missing required field: {field}")
                return False

        if operation["value"] <= 0:
            print(" ❌ Value must be positive")
            return False

        return True

    def select_for_processing(self, max_count: int = 10) -> List[Dict]:
        """Retrieve highest priority operations for block processing"""
        selected = []
        temporary = []

        # Remove expired operations first
        self._purge_expired()

        while self.priority_heap and len(selected) < max_count:
            neg_priority, timestamp, operation_id = heapq.heappop(self.priority_heap)

            if operation_id in self.operation_registry:
                selected.append(self.operation_registry[operation_id])
            else:
                temporary.append((neg_priority, timestamp, operation_id))

        # Restore any remaining operations
        for item in temporary:
            heapq.heappush(self.priority_heap, item)

        return selected

    def remove_operations(self, operation_ids: List[str]) -> None:
        """Remove operations after processing"""
        for operation_id in operation_ids:
            if operation_id in self.operation_registry:
                del self.operation_registry[operation_id]
                self.metrics["total_processed"] += 1

        # Rebuild priority queue
        self._rebuild_heap()

    def _purge_expired(self) -> None:
        """Remove operations that have exceeded retention period"""
        current_time = time.time()
        expired = []

        for operation_id, operation in self.operation_registry.items():
            if current_time - operation.get("timestamp", 0) > self.retention_period:
                expired.append(operation_id)

        for operation_id in expired:
            del self.operation_registry[operation_id]
            self.metrics["total_expired"] += 1

        if expired:
            print(f" 🗑️  Purged {len(expired)} expired operations")
            self._rebuild_heap()

    def _rebuild_heap(self) -> None:
        """Reconstruct priority heap from current registry"""
        self.priority_heap = []
        for operation_id, operation in self.operation_registry.items():
            priority = operation.get("priority", 0.001)
            heapq.heappush(self.priority_heap, (-priority, operation.get("timestamp", 0), operation_id))

    def collect_statistics(self) -> Dict:
        """Gather pool performance metrics"""
        return {
            "current_size": len(self.operation_registry),
            "capacity_limit": self.capacity_limit,
            "utilization_percentage": (len(self.operation_registry) / self.capacity_limit) * 100,
            "total_submitted": self.metrics["total_submitted"],
            "total_processed": self.metrics["total_processed"],
            "total_expired": self.metrics["total_expired"],
            "peak_occupancy": self.metrics["peak_occupancy"]
        }

    def render_status(self) -> None:
        """Display current pool status and statistics"""
        print("\n" + "=" * 60)
        print(" 📊 OPERATION POOL STATUS")
        print("=" * 60)

        stats = self.collect_statistics()
        print(f"\n 📈 Pool Size: {stats['current_size']}/{stats['capacity_limit']} ({stats['utilization_percentage']:.1f}%)")
        print(f" 📥 Submitted: {stats['total_submitted']}")
        print(f" ✅ Processed: {stats['total_processed']}")
        print(f" ⏰ Expired: {stats['total_expired']}")
        print(f" 🏔️  Peak Occupancy: {stats['peak_occupancy']}")

        # Display top priority operations
        print("\n 🏆 Highest Priority Operations:")
        top_ops = self.select_for_processing(5)
        for i, operation in enumerate(top_ops, 1):
            priority = operation.get("priority", 0)
            origin = operation.get("origin", "Unknown")[:12]
            destination = operation.get("destination", "Unknown")[:12]
            print(f"  {i}. {origin}... → {destination}... Priority: {priority:.4f} units")

class PoolSimulationEngine:
    """Simulates pool operations and processing"""
    
    @staticmethod
    def execute_simulation():
        """Run complete pool simulation"""
        print("=" * 60)
        print(" OPERATION POOL SIMULATION")
        print("=" * 60)

        pool = OperationPool(capacity_limit=50, retention_period=30)

        # Generate sample operations with varying priorities
        participants = ["Alice", "Bob", "Charlie", "Diana", "Eve"]

        print("\n 📤 Submitting operations to pool...")
        for i in range(15):
            origin = participants[i % len(participants)]
            destination = participants[(i + 1) % len(participants)]
            priority = 0.001 * (1 + (i % 5))

            operation = {
                "id": f"op_{i:03d}",
                "origin": origin,
                "destination": destination,
                "value": 0.1 * (1 + i % 3),
                "priority": priority,
                "timestamp": time.time()
            }
            pool.submit_operation(operation)

        pool.render_status()

        # Select operations for block
        print("\n" + "=" * 60)
        print(" ⛏️  SELECTING OPERATIONS FOR BLOCK")
        print("=" * 60)

        selected = pool.select_for_processing(5)
        print(f"\n 📦 Selected {len(selected)} operations for processing:")
        for operation in selected:
            print(f"  {operation['origin']} → {operation['destination']}: Priority {operation['priority']:.4f} units")

        # Process selected operations
        print("\n ⛏️  Processing block...")
        operation_ids = [operation["id"] for operation in selected]
        pool.remove_operations(operation_ids)
        
        # Show updated status
        pool.render_status()

class PoolAnalytics:
    """Additional analysis and optimization tools"""
    
    @staticmethod
    def analyze_priority_distribution():
        """Examine how priorities affect selection"""
        print("\n" + "=" * 60)
        print(" PRIORITY DISTRIBUTION ANALYSIS")
        print("=" * 60)
        
        priorities = {
            "Very High (>0.005)": {"selection_probability": "90%", "average_wait": "5s"},
            "High (0.003-0.005)": {"selection_probability": "70%", "average_wait": "15s"},
            "Medium (0.001-0.003)": {"selection_probability": "40%", "average_wait": "45s"},
            "Low (<0.001)": {"selection_probability": "15%", "average_wait": "120s"}
        }
        
        print("\n 📊 Priority Level Metrics:")
        print(f" {'Priority Level':20} | {'Selection Rate':15} | {'Average Wait':15}")
        print("-" * 55)
        
        for level, metrics in priorities.items():
            print(f" {level:20} | {metrics['selection_probability']:15} | {metrics['average_wait']:15}")

def demonstrate_pool_framework():
    """Execute comprehensive pool demonstration"""
    print("\n" + "=" * 60)
    print(" OPERATION POOL FRAMEWORK DEMONSTRATION")
    print("=" * 60)
    
    # Main simulation
    PoolSimulationEngine.execute_simulation()
    
    # Additional analytics
    PoolAnalytics.analyze_priority_distribution()
    
    print("\n" + "=" * 60)
    print(" POOL FRAMEWORK DEMONSTRATION COMPLETE")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_pool_framework()

2.10 Blockchain State

What is Blockchain State?

The blockchain state is the current snapshot of all account balances, smart contract data, and other information stored on the blockchain. It represents the “current truth” of the blockchain—the result of applying all transactions to the initial state.

Why State Matters:

Current State: The blockchain state stores the latest account balances and data, allowing the network to access current information without scanning the entire transaction history. It’s like a bank’s current account balances versus the transaction history.

Efficiency: State allows fast queries of current data (e.g., “What is Alice’s balance?”). Without the current state, the network would have to process every transaction from the genesis block to determine the latest account balances and data.

Smart Contracts: State stores contract code and data. This enables smart contracts to have persistent storage and maintain their own state.

State Management Models:

1. UTXO Model (Bitcoin):

UTXO stands for Unspent Transaction Output. In this model:

  • Transactions consume existing UTXOs and create new ones
  • Balance is calculated from all unspent outputs belonging to an address
  • No account balances are stored (only UTXOs)
  • Used by Bitcoin and many other cryptocurrencies

How UTXO Works:

Alice has UTXO: 10 BTC
Alice sends 3 BTC to Bob:
  Input: 10 BTC UTXO (consumed)
  Output 1: 3 BTC to Bob (new UTXO)
  Output 2: 7 BTC to Alice (change UTXO)

UTXO Transaction Structure:

Transaction {
    inputs: [
        {tx_id: "abc123", output_index: 0, signature: "..."}
    ],
    outputs: [
        {address: "Bob", amount: 3},
        {address: "Alice", amount: 7}  // Change
    ]
}

Advantages of UTXO:

  • Privacy: Users can use new addresses for each transaction
  • Parallel Processing: Multiple UTXOs can be spent in parallel
  • Verification: Each UTXO can be verified independently

Disadvantages of UTXO:

  • Complexity: Managing UTXOs is more complex
  • State Size: The set of all UTXOs grows with usage
  • Smart Contracts: Harder to implement

2. Account-Based Model (Ethereum):

In this model:

  • State is a key-value store of addresses and balances
  • Each transaction updates the state directly
  • State includes contract code and storage
  • Used by Ethereum and most modern blockchains

Account Transaction Structure:

Transaction {
    from: "0x123...",
    to: "0x456...",
    amount: 3,
    nonce: 5,
    signature: "...",
    data: "..."  // Smart contract call
}

Advantages of Account-Based:

  • Simplicity: Easy to understand and implement
  • Smart Contracts: Native support for contracts
  • State Size: Smaller than UTXO

Disadvantages of Account-Based:

  • Privacy: Address reuse is common (lower privacy)
  • Security: Must be careful with state access
  • Parallel Processing: Harder to process in parallel

Comparison:

AspectUTXOAccount-Based
PrivacyBetter (new addresses)Less private
State SizeLarger (all UTXOs)Smaller (balances)
ComplexityMore complexSimpler
Smart ContractsHarderEasier
Parallel ProcessingEasierHarder
ExamplesBitcoin, CardanoEthereum, Solana

Code Example – State Models:

"""
BLOCKCHAIN STATE
================
UTXO vs Account-based models
"""

class UTXO:
    def __init__(self, tx_id, output_index, amount, address):
        self.tx_id = tx_id
        self.output_index = output_index
        self.amount = amount
        self.address = address
        self.spent = False

class UTXOSystem:
    """UTXO model implementation"""

    def __init__(self):
        self.utxos: dict[str, list[UTXO]] = {}
        print(" UTXO System initialized")

    def add_utxo(self, address, amount):
        """Add a UTXO to an address"""
        if address not in self.utxos:
            self.utxos[address] = []
        tx_id = f"tx_{len(self.utxos[address])}"
        utxo = UTXO(tx_id, 0, amount, address)
        self.utxos[address].append(utxo)
        return utxo

    def get_balance(self, address):
        """Get balance by summing unspent UTXOs"""
        if address not in self.utxos:
            return 0

        total = 0
        for utxo in self.utxos[address]:
            if not utxo.spent:
                total += utxo.amount
        return total

    def send(self, from_addr, to_addr, amount):
        """Send amount from one address to another"""
        balance = self.get_balance(from_addr)
        if balance < amount:
            print(f" Insufficient balance: {balance} < {amount}")
            return False

        # Select UTXOs to spend
        selected = []
        total = 0
        for utxo in self.utxos.get(from_addr, []):
            if not utxo.spent:
                selected.append(utxo)
                total += utxo.amount
                if total >= amount:
                    break

        if total < amount:
            return False

        # Spend selected UTXOs
        for utxo in selected:
            utxo.spent = True

        # Create change UTXO
        change = total - amount
        if change > 0:
            self.add_utxo(from_addr, change)

        # Create recipient UTXO
        self.add_utxo(to_addr, amount)

        print(f" Sent {amount} from {from_addr} to {to_addr}")
        return True

    def display(self, address):
        """Display UTXOs for an address"""
        if address not in self.utxos:
            print(f"No UTXOs for {address}")
            return

        print(f"\n UTXOs for {address}:")
        total = 0
        for i, utxo in enumerate(self.utxos[address]):
            if not utxo.spent:
                print(f"  UTXO {i+1}: {utxo.amount} coins")
                total += utxo.amount
        print(f"  Total Balance: {total} coins")


class AccountSystem:
    """Account-based model implementation"""

    def __init__(self):
        self.balances: dict[str, float] = {}
        self.nonces: dict[str, int] = {}
        self.storage: dict[str, dict] = {}
        print(" Account System initialized")

    def create_account(self, address, initial_balance=0):
        """Create a new account"""
        self.balances[address] = initial_balance
        self.nonces[address] = 0
        print(f" Account created: {address}, Balance: {initial_balance}")

    def get_balance(self, address):
        """Get account balance"""
        return self.balances.get(address, 0)

    def send(self, from_addr, to_addr, amount):
        """Send amount from one account to another"""
        if self.get_balance(from_addr) < amount:
            print(f" Insufficient balance: {self.get_balance(from_addr)} < {amount}")
            return False

        self.balances[from_addr] = self.get_balance(from_addr) - amount
        self.balances[to_addr] = self.get_balance(to_addr) + amount
        self.nonces[from_addr] = self.nonces.get(from_addr, 0) + 1

        print(f" Sent {amount} from {from_addr} to {to_addr}")
        return True

    def display(self, address):
        """Display account balance"""
        print(f"  {address}: {self.get_balance(address)} coins")


def compare_models():
    print("=" * 60)
    print("STATE MODEL COMPARISON")
    print("=" * 60)

    # UTXO Demo
    print("\n UTXO MODEL (Bitcoin)")
    print("-" * 40)
    utxo = UTXOSystem()
    utxo.add_utxo("Alice", 100)
    utxo.add_utxo("Alice", 50)
    utxo.add_utxo("Bob", 30)

    print("\nInitial UTXOs:")
    utxo.display("Alice")
    utxo.display("Bob")

    print("\nSending 60 from Alice to Bob...")
    utxo.send("Alice", "Bob", 60)

    print("\nAfter sending:")
    utxo.display("Alice")
    utxo.display("Bob")

    # Account Demo
    print("\n ACCOUNT MODEL (Ethereum)")
    print("-" * 40)
    account = AccountSystem()
    account.create_account("Alice", 150)
    account.create_account("Bob", 30)
    account.create_account("Charlie", 0)

    print("\nInitial Balances:")
    account.display("Alice")
    account.display("Bob")
    account.display("Charlie")

    print("\nSending 50 from Alice to Charlie...")
    account.send("Alice", "Charlie", 50)

    print("\nAfter sending:")
    account.display("Alice")
    account.display("Bob")
    account.display("Charlie")

    print("\n" + "=" * 60)
    print("COMPARISON SUMMARY")
    print("=" * 60)
    print("""
UTXO Model (Bitcoin):
   Better privacy (new addresses per transaction)
   Parallel processing possible
   More complex
   Larger state (all UTXOs)
   Smart contracts harder

Account Model (Ethereum):
   Simpler to understand
   Native smart contract support
   Smaller state (balances only)
   Less privacy
   Harder parallel processing
    """)

if __name__ == "__main__":
    compare_models()

2.11 UTXO Model

Understanding the UTXO Model:

The UTXO (Unspent Transaction Output) model is the transaction model used by Bitcoin and many other cryptocurrencies. Instead of storing account balances, the network tracks individual “coins” called UTXOs.

What is a UTXO?

A UTXO is an unspent transaction output. Each UTXO represents a specific amount of cryptocurrency that is controlled by a specific address. Think of UTXOs as physical coins—each coin has a specific value and owner.

How UTXO Transactions Work:

When a user wants to send money:

  1. They select one or more UTXOs to spend
  2. They create a transaction with inputs (the UTXOs being spent) and outputs (new UTXOs being created)
  3. The transaction is signed and broadcast
  4. The old UTXOs are marked as spent
  5. New UTXOs are created for the recipient and change

Example:

Alice has two UTXOs:

  • UTXO A: 5 BTC (from previous transaction)
  • UTXO B: 3 BTC (from another transaction)

Alice wants to transfer 6 BTC to Bob.

  1. Input: UTXO A (5 BTC) + UTXO B (3 BTC) = 8 BTC total
  2. Output 1: 6 BTC to Bob (new UTXO)
  3. Output 2: 2 BTC to Alice (change UTXO)

UTXO Characteristics:

Indivisible: UTXOs cannot be split. A UTXO must be spent in full. Change is returned as a new UTXO.

Atomic: A UTXO is either completely spent or completely unspent. There is no partial spending.

Chainable: UTXOs can be traced back through the chain of transactions that created them.

Key UTXO Concepts:

Inputs: The UTXOs being spent. Each input references a previous transaction and output.

Outputs: The new UTXOs being created. Each output defines the amount to be transferred and the recipient’s address.

Change: The difference between the input amount and the sent amount. Change returns to the sender as a new UTXO.

Transaction Fees: The difference between inputs and outputs goes to the miner.

Code Example – UTXO Model:

"""
UNSPENT TRANSACTION OUTPUT PARADIGM
===================================
Comprehensive implementation of the UTXO state model with transaction management
"""

import hashlib
import time
from typing import List, Dict, Optional, Tuple
from dataclasses import dataclass
from enum import Enum

@dataclass
class UnspentOutput:
    """Represents a discrete, indivisible unit of value in the UTXO model"""
    transaction_id: str
    output_position: int
    value: float
    owner_address: str
    creation_timestamp: float
    is_consumed: bool = False
    
    def mark_consumed(self) -> None:
        """Flag this output as spent/consumed"""
        self.is_consumed = True
    
    def is_available(self) -> bool:
        """Check if output is still unspent"""
        return not self.is_consumed
    
    def __repr__(self) -> str:
        status = "Consumed" if self.is_consumed else "Available"
        return f"UTXO({self.owner_address[:8]}..., {self.value:.2f} units, {status})"

class UTXORegistry:
    """Complete UTXO model with transaction processing capabilities"""
    
    def __init__(self):
        self.output_store: Dict[str, List[UnspentOutput]] = {}  # address -> list of UTXOs
        self.transaction_history: List[Dict] = []
        self.circulating_supply: float = 0.0
        self.transaction_counter = 0
        print(" 🔐 UTXO Registry initialized")
    
    def generate_output(self, recipient: str, amount: float) -> str:
        """Create new UTXO (used for mining rewards or transfers)"""
        tx_id = hashlib.md5(f"mint_{time.time()}_{self.transaction_counter}".encode()).hexdigest()
        new_output = UnspentOutput(
            transaction_id=tx_id,
            output_position=0,
            value=amount,
            owner_address=recipient,
            creation_timestamp=time.time()
        )
        
        if recipient not in self.output_store:
            self.output_store[recipient] = []
        self.output_store[recipient].append(new_output)
        self.circulating_supply += amount
        self.transaction_counter += 1
        
        # Record minting event
        self.transaction_history.append({
            "id": tx_id,
            "type": "mint",
            "address": recipient,
            "amount": amount,
            "timestamp": time.time()
        })
        
        print(f" 🪙 Minted {amount:.2f} units for {recipient[:8]}...")
        return tx_id
    
    def query_holdings(self, address: str) -> float:
        """Calculate total available balance from unspent outputs"""
        if address not in self.output_store:
            return 0.0
        
        total_available = 0.0
        for output in self.output_store[address]:
            if output.is_available():
                total_available += output.value
        return total_available
    
    def retrieve_available_outputs(self, address: str) -> List[UnspentOutput]:
        """Get all unspent outputs for a specific address"""
        if address not in self.output_store:
            return []
        return [output for output in self.output_store[address] if output.is_available()]
    
    def construct_transfer(self, sender: str, recipient: str, amount: float, 
                          transaction_fee: float = 0.001) -> Optional[Dict]:
        """Build and execute a transaction consuming UTXOs and creating new ones"""
        sender_balance = self.query_holdings(sender)
        if sender_balance < amount:
            print(f" ❌ Insufficient funds: {sender_balance:.2f} < {amount:.2f}")
            return None
        
        # Select UTXOs to cover the transfer amount
        selected_outputs = []
        accumulated_value = 0.0
        
        for output in self.output_store.get(sender, []):
            if output.is_available():
                selected_outputs.append(output)
                accumulated_value += output.value
                if accumulated_value >= (amount + transaction_fee):
                    break
        
        if accumulated_value < (amount + transaction_fee):
            print(f" ❌ Insufficient UTXO selection: {accumulated_value:.2f} < {amount + transaction_fee:.2f}")
            return None
        
        # Build transaction structure
        transaction = {
            "id": hashlib.md5(f"tx_{time.time()}_{self.transaction_counter}".encode()).hexdigest(),
            "inputs": [
                {
                    "tx_id": output.transaction_id, 
                    "position": output.output_position, 
                    "value": output.value
                } 
                for output in selected_outputs
            ],
            "outputs": [],
            "timestamp": time.time(),
            "fee": transaction_fee,
            "total_input": accumulated_value,
            "total_output": 0.0
        }
        
        # Consume selected UTXOs
        for output in selected_outputs:
            output.mark_consumed()
        
        # Create recipient output
        transaction["outputs"].append({
            "address": recipient,
            "value": amount
        })
        transaction["total_output"] += amount
        
        # Create change output if applicable
        change_amount = accumulated_value - amount - transaction_fee
        if change_amount > 0:
            transaction["outputs"].append({
                "address": sender,
                "value": change_amount
            })
            transaction["total_output"] += change_amount
        
        # Register new UTXOs
        for position, output_data in enumerate(transaction["outputs"]):
            new_output = UnspentOutput(
                transaction_id=transaction["id"],
                output_position=position,
                value=output_data["value"],
                owner_address=output_data["address"],
                creation_timestamp=time.time()
            )
            
            if output_data["address"] not in self.output_store:
                self.output_store[output_data["address"]] = []
            self.output_store[output_data["address"]].append(new_output)
        
        self.transaction_history.append(transaction)
        self.transaction_counter += 1
        
        print(f" ✅ Transaction {transaction['id'][:16]}... completed successfully")
        return transaction
    
    def inspect_outputs(self, address: str) -> None:
        """Display all available UTXOs for a given address"""
        if address not in self.output_store:
            print(f" 📭 No outputs found for {address}")
            return
        
        available_outputs = self.retrieve_available_outputs(address)
        if not available_outputs:
            print(f" 📭 No available outputs for {address}")
            return
        
        print(f"\n 📋 Available UTXOs for {address[:12]}...")
        print("-" * 50)
        total_value = 0.0
        for i, output in enumerate(available_outputs, 1):
            print(f"  #{i}: {output.value:.2f} units (TX: {output.transaction_id[:8]}...)")
            total_value += output.value
        print(f"  💰 Total Available: {total_value:.2f} units")
    
    def get_transaction_count(self) -> int:
        """Return number of processed transactions"""
        return self.transaction_counter

class UTXOAnalytics:
    """Additional analysis tools for UTXO model"""
    
    @staticmethod
    def analyze_utxo_patterns():
        """Examine common UTXO usage patterns"""
        print("\n" + "=" * 60)
        print(" UTXO PATTERN ANALYSIS")
        print("=" * 60)
        
        patterns = {
            "Single UTXO": {"description": "One output covers entire transfer", "example": "Alice sends entire balance"},
            "Multiple UTXOs": {"description": "Combine several outputs", "example": "Payment with multiple inputs"},
            "Change Creation": {"description": "New UTXO for leftover amount", "example": "Return change to sender"},
            "Consolidation": {"description": "Combine small UTXOs into one", "example": "Reduce future transaction costs"}
        }
        
        print("\n 📊 UTXO Usage Patterns:")
        for pattern_name, pattern_data in patterns.items():
            print(f"  • {pattern_name}: {pattern_data['description']}")
            print(f"    Example: {pattern_data['example']}")
    
    @staticmethod
    def compare_with_account_model():
        """Highlight key differences from account model"""
        print("\n" + "=" * 60)
        print(" UTXO VS ACCOUNT MODEL COMPARISON")
        print("=" * 60)
        
        print("\n 🔹 UTXO Model Features:")
        print("   • Privacy: Enhanced through address reuse avoidance")
        print("   • Parallelism: Supports concurrent transaction processing")
        print("   • Auditability: Complete transaction chain tracing")
        print("   • Atomicity: Outputs are consumed entirely")
        
        print("\n 🔸 Account Model Features:")
        print("   • Simplicity: Easier to understand and implement")
        print("   • State: Direct balance modifications")
        print("   • Smart Contracts: Native support for complex logic")
        print("   • Storage: Lower state overhead (balances only)")

def demonstrate_utxo_system():
    """Execute comprehensive UTXO model demonstration"""
    print("=" * 60)
    print(" UTXO MODEL DEMONSTRATION")
    print("=" * 60)
    
    # Initialize system
    registry = UTXORegistry()
    
    # Create participants
    alice = "Alice_Address"
    bob = "Bob_Address"
    charlie = "Charlie_Address"
    
    # Mint initial funds
    print("\n 💰 Minting initial funds...")
    registry.generate_output(alice, 100)
    registry.generate_output(alice, 50)
    registry.generate_output(bob, 30)
    
    # Display initial state
    registry.inspect_outputs(alice)
    registry.inspect_outputs(bob)
    
    # Execute first transfer
    print("\n 🔄 Alice transfers 60 units to Bob...")
    registry.construct_transfer(alice, bob, 60)
    
    # Display state after first transfer
    registry.inspect_outputs(alice)
    registry.inspect_outputs(bob)
    
    # Execute second transfer
    print("\n 🔄 Bob transfers 25 units to Charlie...")
    registry.construct_transfer(bob, charlie, 25)
    
    # Display final balances
    print("\n 📊 Final Balance Summary:")
    print(f"  Alice: {registry.query_holdings(alice):.2f} units")
    print(f"  Bob: {registry.query_holdings(bob):.2f} units")
    print(f"  Charlie: {registry.query_holdings(charlie):.2f} units")
    
    # Additional analytics
    UTXOAnalytics.analyze_utxo_patterns()
    UTXOAnalytics.compare_with_account_model()
    
    print("\n" + "=" * 60)
    print(" UTXO MODEL CHARACTERISTICS:")
    print("   ✓ Indivisible: UTXOs must be consumed entirely")
    print("   ✓ Atomic: Output is either spent or unspent")
    print("   ✓ Traceable: Complete transaction history available")
    print("   ✓ Change Management: New outputs created for remainder")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_utxo_system()

2.12 Account-Based Model

Understanding the Account-Based Model:

The account-based model is used by Ethereum and many modern blockchains. Instead of tracking individual UTXOs like Bitcoin, the account model stores account balances directly in the state, similar to a traditional bank database.

How the Account Model Works:

In the account model, each address is an account with:

  • Balance: The current amount of cryptocurrency
  • Nonce: A counter of transactions from this account (prevents replay attacks)
  • Storage: For smart contracts, persistent data storage
  • Code: For smart contracts, the contract code

Account Types:

Externally Owned Accounts (EOA):

  • Controlled by private keys
  • Can send transactions
  • Have a balance and nonce
  • Cannot contain code
  • Example: User wallets

Contract Accounts:

  • Controlled by code (smart contracts)
  • Can send transactions (via code execution)
  • Have a balance, nonce, code, and storage
  • Created by transactions
  • Example: Token contracts, DeFi protocols

Transaction Structure:

Transaction {
    from: "0x123...",      // Sender address
    to: "0x456...",        // Recipient address
    amount: 3,             // Value being sent
    nonce: 5,              // Transaction counter
    gas_limit: 21000,      // Maximum gas for this tx
    gas_price: 50,         // Price per gas (Gwei)
    data: "0x...",         // Smart contract call data
    signature: "0x..."     // ECDSA signature
}

State Updates:

  1. User creates a transaction
  2. Transaction is signed and broadcast
  3. Nodes validate the transaction
  4. State is updated directly: sender balance decreases, recipient balance increases
  5. Nonce is incremented
  6. Transaction is included in a block

Code Example – Account-Based Model:

"""
ACCOUNT-BASED MODEL
===================
Complete account-based blockchain implementation
"""

import hashlib
import time
import json
from typing import Dict, List, Optional

class Account:
    """Account in the account-based model"""

    def __init__(self, address: str, balance: float = 0):
        self.address = address
        self.balance = balance
        self.nonce = 0
        self.code = ""  # Smart contract code
        self.storage = {}  # Smart contract storage
        self.created_at = time.time()

    def to_dict(self):
        return {
            "address": self.address[:16] + "...",
            "balance": self.balance,
            "nonce": self.nonce,
            "is_contract": bool(self.code)
        }

class AccountModel:
    """Complete account-based blockchain implementation"""

    def __init__(self):
        self.accounts: Dict[str, Account] = {}
        self.transactions: List[Dict] = []
        self.blocks: List[Dict] = []
        self.pending_transactions: List[Dict] = []
        print(" Account Model initialized")

    def create_account(self, address: str, initial_balance: float = 0):
        """Create a new account"""
        if address in self.accounts:
            print(f" Account {address} already exists")
            return

        self.accounts[address] = Account(address, initial_balance)
        print(f" Account created: {address[:16]}..., Balance: {initial_balance}")
        return self.accounts[address]

    def get_account(self, address: str) -> Optional[Account]:
        """Get an account by address"""
        return self.accounts.get(address)

    def get_balance(self, address: str) -> float:
        """Get account balance"""
        account = self.get_account(address)
        return account.balance if account else 0

    def get_nonce(self, address: str) -> int:
        """Get account nonce"""
        account = self.get_account(address)
        return account.nonce if account else 0

    def send_transaction(self, from_addr: str, to_addr: str, amount: float, 
                         data: str = "", gas_limit: int = 21000, 
                         gas_price: int = 50) -> bool:
        """Send a transaction"""
        # Validate sender
        sender = self.get_account(from_addr)
        if not sender:
            print(f" Sender account {from_addr} not found")
            return False

        # Validate balance
        if sender.balance < amount:
            print(f" Insufficient balance: {sender.balance} < {amount}")
            return False

        # Create recipient if doesn't exist
        if to_addr not in self.accounts:
            self.create_account(to_addr, 0)

        recipient = self.get_account(to_addr)

        # Calculate fee
        fee = (gas_limit * gas_price) / 1e9  # Convert Gwei to ETH

        # Check if enough balance for fee
        if sender.balance < (amount + fee):
            print(f" Insufficient balance for fee: {sender.balance} < {amount + fee}")
            return False

        # Update balances
        sender.balance -= (amount + fee)
        recipient.balance += amount

        # Increment nonce
        sender.nonce += 1

        # Create transaction record
        tx = {
            "hash": hashlib.sha256(
                f"{from_addr}{to_addr}{amount}{sender.nonce}{time.time()}".encode()
            ).hexdigest(),
            "from": from_addr,
            "to": to_addr,
            "amount": amount,
            "nonce": sender.nonce,
            "gas_limit": gas_limit,
            "gas_price": gas_price,
            "fee": fee,
            "data": data,
            "timestamp": time.time(),
            "status": "Confirmed"
        }

        self.transactions.append(tx)
        print(f" Transaction {tx['hash'][:16]}... completed")
        return True

    def deploy_contract(self, address: str, code: str, initial_storage: Dict = None):
        """Deploy a smart contract"""
        account = self.get_account(address)
        if not account:
            print(f" Account {address} not found")
            return

        account.code = code
        if initial_storage:
            account.storage.update(initial_storage)

        print(f" Contract deployed at {address[:16]}...")
        return True

    def call_contract(self, from_addr: str, contract_addr: str, 
                      function: str, params: Dict) -> bool:
        """Call a smart contract function"""
        contract = self.get_account(contract_addr)
        if not contract or not contract.code:
            print(f" Contract {contract_addr} not found")
            return False

        # Simulate contract execution
        print(f" Calling {function} on contract {contract_addr[:16]}...")
        print(f"   Params: {params}")

        # Simple storage update example
        if function == "setValue":
            contract.storage["value"] = params.get("value", 0)
            print(f"   Storage updated: value = {contract.storage['value']}")
            return True

        elif function == "getValue":
            value = contract.storage.get("value", 0)
            print(f"   Storage read: value = {value}")
            return True

        print(f" Unknown function: {function}")
        return False

    def display_accounts(self):
        """Display all accounts"""
        print("\n" + "=" * 60)
        print(" ACCOUNTS")
        print("=" * 60)

        if not self.accounts:
            print("No accounts found")
            return

        for addr, account in self.accounts.items():
            info = account.to_dict()
            print(f"\n {addr[:16]}...")
            print(f"   Balance: {info['balance']} ETH")
            print(f"   Nonce: {info['nonce']}")
            print(f"   Contract: {info['is_contract']}")
            if info['is_contract'] and account.storage:
                print(f"   Storage: {account.storage}")

    def display_transactions(self, limit: int = 10):
        """Display recent transactions"""
        print("\n" + "=" * 60)
        print(" RECENT TRANSACTIONS")
        print("=" * 60)

        for tx in self.transactions[-limit:]:
            print(f"\n  Hash: {tx['hash'][:16]}...")
            print(f"  From: {tx['from'][:16]}... → To: {tx['to'][:16]}...")
            print(f"  Amount: {tx['amount']} ETH")
            print(f"  Fee: {tx['fee']:.6f} ETH")
            print(f"  Nonce: {tx['nonce']}")

def demo_account_model():
    print("=" * 60)
    print("ACCOUNT-BASED MODEL DEMONSTRATION")
    print("=" * 60)

    # Initialize
    model = AccountModel()

    # Create accounts
    alice = "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b"
    bob = "0x2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c"
    charlie = "0x3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d"
    contract_addr = "0x4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e"

    model.create_account(alice, 1000)
    model.create_account(bob, 500)
    model.create_account(charlie, 100)

    # Send transactions
    print("\n Sending transactions...")
    model.send_transaction(alice, bob, 200)
    model.send_transaction(bob, charlie, 50)
    model.send_transaction(alice, charlie, 75)

    # Deploy contract
    print("\n Deploying contract...")
    code = "SimpleStorage"
    model.deploy_contract(contract_addr, code, {"value": 0})

    # Call contract
    print("\n Calling contract...")
    model.call_contract(alice, contract_addr, "setValue", {"value": 42})
    model.call_contract(alice, contract_addr, "getValue", {})

    # Display state
    model.display_accounts()
    model.display_transactions(5)

    print("\n" + "=" * 60)
    print("ACCOUNT MODEL CHARACTERISTICS:")
    print("   Simple: Easy to understand")
    print("   Smart Contracts: Native support")
    print("   Privacy: Address reuse reduces privacy")
    print("   Parallel Processing: Harder than UTXO")

if __name__ == "__main__":
    demo_account_model()

2.13 Peer-to-Peer Network

What is a Peer-to-Peer Network?

A peer-to-peer (P2P) network is a distributed network where nodes communicate directly with each other without a central server. In a blockchain context, the P2P network enables nodes to share transactions, blocks, and maintain the distributed ledger.

How P2P Works in Blockchain:

Node Discovery:

When a node joins the network:

  1. It connects to a “bootstrap node” (a well-known, trusted node)
  2. The bootstrap node provides a list of other nodes
  3. The new node connects to those nodes
  4. It builds its peer list from connected nodes

Message Propagation:

Gossip Protocol:

Information spreads through the network like gossip:

  1. Node receives a message (transaction or block)
  2. Node validates the message
  3. Node relays the message to its peers
  4. The process repeats, spreading across the network

Types of Network Messages:

Message TypePurpose
versionHandshake, version info
verackAcknowledge version
invInventory (list of items)
getdataRequest data items
blockSend a block
txSend a transaction
addrSend peer addresses
ping/pongCheck connection

Code Example – P2P Network:

"""
PEER-TO-PEER NETWORK
====================
P2P network simulation
"""

class P2PNode:
    def __init__(self, name):
        self.name = name
        self.peers = []
        self.blockchain = []
        self.mempool = []
        self.messages_received = []
        print(f" Node {name} initialized")

    def connect(self, peer):
        """Connect to another node"""
        if peer not in self.peers and peer != self:
            self.peers.append(peer)
            peer.peers.append(self)
            print(f" {self.name} connected to {peer.name}")

    def broadcast_transaction(self, tx):
        """Broadcast a transaction to all peers"""
        print(f" {self.name} broadcasting transaction: {tx['hash'][:16]}...")
        for peer in self.peers:
            peer.receive_transaction(tx, self)

    def receive_transaction(self, tx, sender):
        """Receive a transaction from a peer"""
        if tx not in self.mempool:
            self.mempool.append(tx)
            self.messages_received.append({
                "type": "tx",
                "from": sender.name,
                "data": tx["hash"],
                "time": time.time()
            })
            print(f" {self.name} received tx from {sender.name}: {tx['hash'][:16]}...")

    def broadcast_block(self, block):
        """Broadcast a block to all peers"""
        print(f" {self.name} broadcasting block: {block['hash'][:16]}...")
        for peer in self.peers:
            peer.receive_block(block, self)

    def receive_block(self, block, sender):
        """Receive a block from a peer"""
        if block not in self.blockchain:
            self.blockchain.append(block)
            self.messages_received.append({
                "type": "block",
                "from": sender.name,
                "data": block["hash"],
                "time": time.time()
            })
            print(f" {self.name} received block from {sender.name}: {block['hash'][:16]}...")

    def get_stats(self):
        """Get node statistics"""
        return {
            "name": self.name,
            "peers": [p.name for p in self.peers],
            "blocks": len(self.blockchain),
            "mempool": len(self.mempool),
            "messages": len(self.messages_received)
        }

    def display(self):
        """Display node information"""
        stats = self.get_stats()
        print(f"\n Node: {stats['name']}")
        print(f"   Peers: {', '.join(stats['peers'])}")
        print(f"   Blocks: {stats['blocks']}")
        print(f"   Mempool: {stats['mempool']}")
        print(f"   Messages: {stats['messages']}")

import time

def demo_p2p():
    print("=" * 60)
    print("PEER-TO-PEER NETWORK DEMONSTRATION")
    print("=" * 60)

    # Create nodes
    node1 = P2PNode("Node1")
    node2 = P2PNode("Node2")
    node3 = P2PNode("Node3")
    node4 = P2PNode("Node4")

    # Connect nodes (creating a network topology)
    node1.connect(node2)
    node1.connect(node3)
    node2.connect(node3)
    node2.connect(node4)
    node3.connect(node4)

    print("\n Network topology:")
    print("  Node1 --- Node2 --- Node3 --- Node4")
    print("   |                    |")
    print("   +--------------------+")

    # Create a transaction
    print("\n Creating and broadcasting transaction...")
    tx = {"hash": "0x7a9b3c8d2e1f4g5h6i7j8k9l0m1n2o3p4q5r6s7t8u9"}
    node1.broadcast_transaction(tx)

    # Create a block
    print("\n Creating and broadcasting block...")
    block = {"hash": "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c"}
    node1.broadcast_block(block)

    # Display node stats
    print("\n Network statistics:")
    for node in [node1, node2, node3, node4]:
        node.display()

    print("\n" + "=" * 60)
    print("P2P NETWORK CHARACTERISTICS:")
    print("   Decentralized: No central server")
    print("   Resilient: No single point of failure")
    print("   Scalable: Network grows with nodes")
    print("   Latency: Information takes time to propagate")
    print("   Consistency: Nodes may have different views")

if __name__ == "__main__":
    demo_p2p()

2.14 Nodes

What are Nodes?

Nodes are computers that participate in the blockchain network by storing, validating, and sharing blockchain data. They maintain copies of the blockchain, validate transactions, and propagate information. Nodes form the foundation of blockchain decentralization. A larger and more distributed network of nodes generally strengthens the network’s resilience and reduces reliance on any single participant.

Types of Nodes:

1. Full Node:

A full node downloads and validates the entire blockchain from the genesis block to the latest block. It independently verifies all transactions and blocks.

Functions:

  • Validates all blocks and transactions
  • Relays transactions and blocks to peers
  • Maintains a complete copy of the blockchain
  • Enforces consensus rules

Requirements:

  • Significant storage (Bitcoin: 500+ GB)
  • Processing power
  • Good internet connection

Example: Bitcoin Core node

2. Light Node (SPV Node):

A light node (Simple Payment Verification) only downloads block headers, not the full blockchain. It relies on full nodes for transaction verification.

Functions:

  • Verifies transactions using Merkle proofs
  • Queries full nodes for data
  • Sends transactions to the network
  • Does not validate the full blockchain

Requirements:

  • Minimal storage (only block headers)
  • Less processing power

Example: Mobile wallets (Trust Wallet, MetaMask)

3. Archive Node:

An archive node stores the complete history of the blockchain, including all historical states and intermediate data.

Functions:

  • Provides historical data for analysis
  • Enables historical queries
  • Supports blockchain explorers

Requirements:

  • Very large storage (1+ TB)
  • Significant processing power

Example: Etherscan, blockchain explorers

4. Validator Node:

A validator node participates in the consensus mechanism (Proof of Stake). It proposes blocks, votes on block validity, and helps secure the network.

Functions:

  • Proposes new blocks
  • Votes on block validity
  • Attests to transaction validity
  • Receives staking rewards

Requirements:

  • Staked tokens (collateral)
  • High uptime (99.9%+)
  • Significant processing power

Example: Ethereum validators, Solana validators

Code Example – Node Types:

"""
NODE TYPES
==========
Different types of blockchain nodes
"""

class BaseNode:
    def __init__(self, name):
        self.name = name
        self.peers = []
        self.connected = True

    def connect(self, peer):
        """Connect to another node"""
        if peer not in self.peers:
            self.peers.append(peer)
            print(f"{self.name} connected to {peer.name}")

    def get_peers(self):
        return [p.name for p in self.peers]

class FullNode(BaseNode):
    """Full node stores and validates entire blockchain"""

    def __init__(self, name):
        super().__init__(name)
        self.blockchain = []
        self.mempool = []
        self.storage_gb = 500
        print(f" Full Node {name}: Storing full blockchain ({self.storage_gb} GB)")

    def add_block(self, block):
        """Add a block to the blockchain"""
        self.blockchain.append(block)
        print(f" {self.name}: Added block {block}")

    def validate_transaction(self, tx):
        """Validate a transaction"""
        # In reality, this would be complex validation
        print(f" {self.name}: Validated transaction {tx}")
        return True

    def get_stats(self):
        return {
            "type": "Full Node",
            "name": self.name,
            "blocks": len(self.blockchain),
            "storage": f"{self.storage_gb} GB"
        }

class LightNode(BaseNode):
    """Light node stores only block headers"""

    def __init__(self, name):
        super().__init__(name)
        self.block_headers = []
        self.storage_gb = 0.1
        print(f" Light Node {name}: Storing only block headers ({self.storage_gb} GB)")

    def verify_transaction(self, tx, full_node):
        """Verify a transaction using a full node"""
        print(f" {self.name}: Verifying transaction {tx} via {full_node.name}")
        return full_node.validate_transaction(tx)

    def get_stats(self):
        return {
            "type": "Light Node",
            "name": self.name,
            "headers": len(self.block_headers),
            "storage": f"{self.storage_gb} GB"
        }

class ArchiveNode(FullNode):
    """Archive node stores full history"""

    def __init__(self, name):
        super().__init__(name)
        self.historical_data = []
        self.storage_gb = 2000
        print(f" Archive Node {name}: Storing full history ({self.storage_gb} GB)")

    def get_historical_data(self, block_height):
        """Query historical data"""
        print(f" {self.name}: Querying historical data at block {block_height}")
        return {"block": block_height, "data": "Historical data"}

    def get_stats(self):
        return {
            "type": "Archive Node",
            "name": self.name,
            "blocks": len(self.blockchain),
            "history_entries": len(self.historical_data),
            "storage": f"{self.storage_gb} GB"
        }

class ValidatorNode(FullNode):
    """Validator node participates in consensus"""

    def __init__(self, name, stake=1000):
        super().__init__(name)
        self.stake = stake
        self.rewards = 0
        self.uptime = 99.9
        print(f" Validator Node {name}: Staked {stake} tokens")

    def propose_block(self, timestamp):
        """Propose a new block"""
        block = f"Block_{timestamp}"
        print(f" {self.name}: Proposing block {block}")
        return block

    def vote_on_block(self, block):
        """Vote on block validity"""
        print(f" {self.name}: Voting on block {block}")
        return True

    def claim_rewards(self):
        """Claim staking rewards"""
        reward = self.stake * 0.1
        self.rewards += reward
        self.stake += reward
        print(f" {self.name}: Claimed {reward} tokens reward")
        return reward

    def get_stats(self):
        return {
            "type": "Validator Node",
            "name": self.name,
            "stake": self.stake,
            "rewards": self.rewards,
            "uptime": f"{self.uptime}%",
            "blocks": len(self.blockchain)
        }

def demo_nodes():
    print("=" * 60)
    print("NODE TYPES DEMONSTRATION")
    print("=" * 60)

    # Create nodes
    full = FullNode("FullNode1")
    light = LightNode("LightNode1")
    archive = ArchiveNode("ArchiveNode1")
    validator = ValidatorNode("Validator1")

    # Connect nodes
    full.connect(light)
    full.connect(archive)
    full.connect(validator)
    validator.connect(full)

    # Simulate activities
    print("\n" + "-" * 40)
    print("NODE ACTIVITIES")
    print("-" * 40)

    print("\n Full Node:")
    full.validate_transaction("tx_001")
    full.add_block("Block_001")

    print("\n Light Node:")
    light.verify_transaction("tx_001", full)

    print("\n Archive Node:")
    archive.get_historical_data(100)

    print("\n Validator Node:")
    block = validator.propose_block("2024-01-01")
    validator.vote_on_block(block)
    validator.claim_rewards()

    # Display statistics
    print("\n" + "=" * 60)
    print(" NODE STATISTICS")
    print("=" * 60)

    for node in [full, light, archive, validator]:
        stats = node.get_stats()
        print(f"\n {stats['type']}: {stats['name']}")
        for key, value in stats.items():
            if key not in ['type', 'name']:
                print(f"   {key}: {value}")

if __name__ == "__main__":
    demo_nodes()

2.15 Consensus Mechanisms

What is Consensus?

Consensus is the process by which nodes in a distributed network agree on the state of the blockchain. It ensures all participants have the same view of the ledger, preventing double-spending and maintaining network security.

Why Consensus Matters:

Prevents Double-Spending: Without consensus, a user could spend the same coins twice. Consensus ensures everyone agrees on which transaction is valid.

Network Agreement: Consensus ensures all nodes agree on the canonical state of the blockchain. Without consensus, the network would split into conflicting views.

Security: Consensus makes attacking the network expensive and difficult. An attacker would need to gain control of a significant portion of the network to influence or disrupt the blockchain’s consensus process.

Types of Consensus:

MechanismDescriptionEnergySpeedExamples
Proof of Work (PoW)Solve computational puzzlesVery HighSlowBitcoin, Litecoin
Proof of Stake (PoS)Stake cryptocurrency to validateLowFastEthereum, Cardano
Delegated PoS (DPoS)Stakeholders vote for delegatesLowFastEOS, Tron
PBFTByzantine Fault TolerantLowFastHyperledger

Proof of Work (PoW):

How it Works:

  1. Miners collect transactions from the mempool
  2. They compete to solve a mathematical puzzle (finding a nonce)
  3. The first to solve creates the block
  4. Other nodes verify and accept the block
  5. The miner receives block reward + fees

Key Properties:

  • High Security: Computationally expensive to attack
  • High Energy: Consumes massive electricity
  • Slow: 10 minutes per block (Bitcoin)
  • Scalability: Limited TPS

Proof of Stake (PoS):

How it Works:

  1. Validators stake (lock up) cryptocurrency
  2. The network randomly selects a validator
  3. Selected validator proposes a block
  4. Other validators attest to validity
  5. Validators receive rewards for good behavior

Key Properties:

  • Low Energy: No mining hardware needed
  • Fast: Seconds to minutes per block
  • Scalable: Higher TPS
  • Security: Attack requires majority stake

Code Example – Consensus:

"""
DISTRIBUTED AGREEMENT PROTOCOLS
===============================
Comprehensive implementation of various consensus mechanisms for decentralized networks
"""

import random
import time
import hashlib
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class ConsensusType(Enum):
    """Classification of consensus protocols"""
    PROOF_OF_WORK = "Proof of Work"
    PROOF_OF_STAKE = "Proof of Stake"
    DELEGATED_PROOF = "Delegated Proof of Stake"
    PRACTICAL_BYZANTINE = "Practical Byzantine Fault Tolerance"
    PROOF_OF_AUTHORITY = "Proof of Authority"

@dataclass
class BlockCandidate:
    """Represents a block being proposed for consensus"""
    height: int
    data: Dict
    proposer: str
    timestamp: float = field(default_factory=time.time)
    nonce: int = 0
    hash_value: str = ""

class ProofOfWorkProtocol:
    """Proof of Work consensus implementation"""
    
    def __init__(self, complexity: int = 3):
        self.complexity = complexity
        self.nonce_counter = 0
        self.total_attempts = 0
        print(f" ⚡ PoW Protocol initialized with complexity {complexity}")
    
    def solve_puzzle(self, block_data: str) -> Dict:
        """Mine a block by finding a valid nonce"""
        target_pattern = "0" * self.complexity
        start_time = time.time()
        attempts = 0
        
        print(f" ⛏️  Mining block with complexity {self.complexity}...")
        
        while True:
            # Generate hash from combined data
            combined = f"{block_data}{self.nonce_counter}"
            hash_result = hashlib.sha256(combined.encode()).hexdigest()
            
            # Check if target pattern is met
            if hash_result[:self.complexity] == target_pattern:
                elapsed = time.time() - start_time
                print(f" ✅ Block mined successfully!")
                print(f"   Nonce: {self.nonce_counter}")
                print(f"   Hash: {hash_result}")
                print(f"   Duration: {elapsed:.2f}s")
                print(f"   Attempts: {attempts}")
                return {
                    "nonce": self.nonce_counter,
                    "hash": hash_result,
                    "duration": elapsed,
                    "attempts": attempts
                }
            
            self.nonce_counter += 1
            attempts += 1
            
            if attempts % 10000 == 0:
                print(f"  Progress: {attempts} attempts, current hash: {hash_result[:8]}...", end="\r")
    
    def validate_block(self, block: Dict) -> bool:
        """Validate that a block meets the difficulty requirement"""
        block_data = block.get("data", "")
        nonce = block.get("nonce", 0)
        hash_result = block.get("hash", "")
        
        if not hash_result:
            # Compute hash if not provided
            combined = f"{block_data}{nonce}"
            hash_result = hashlib.sha256(combined.encode()).hexdigest()
        
        return hash_result[:self.complexity] == "0" * self.complexity
    
    def get_statistics(self) -> Dict:
        """Return protocol statistics"""
        return {
            "protocol": "Proof of Work",
            "complexity": self.complexity,
            "total_attempts": self.total_attempts,
            "current_nonce": self.nonce_counter
        }

class ProofOfStakeProtocol:
    """Proof of Stake consensus implementation"""
    
    def __init__(self):
        self.stake_registry: Dict[str, float] = {}
        self.total_staked = 0.0
        self.validator_history: List[str] = []
        print(" 💰 PoS Protocol initialized")
    
    def deposit_stake(self, address: str, amount: float) -> None:
        """Add staking tokens for a participant"""
        self.stake_registry[address] = self.stake_registry.get(address, 0) + amount
        self.total_staked += amount
        print(f" ✅ {address} staked {amount:.2f} tokens (Total: {self.stake_registry[address]:.2f})")
    
    def withdraw_stake(self, address: str, amount: float) -> bool:
        """Withdraw staked tokens"""
        if address not in self.stake_registry:
            return False
        if self.stake_registry[address] < amount:
            return False
        self.stake_registry[address] -= amount
        self.total_staked -= amount
        print(f" 💳 {address} withdrew {amount:.2f} tokens")
        return True
    
    def select_validator(self) -> Optional[str]:
        """Select a validator weighted by stake amount"""
        if not self.stake_registry or self.total_staked == 0:
            print(" ⚠️  No staking participants available")
            return None
        
        # Weighted random selection
        selection_point = random.random() * self.total_staked
        cumulative = 0.0
        
        for address, stake in self.stake_registry.items():
            cumulative += stake
            if cumulative >= selection_point:
                self.validator_history.append(address)
                print(f" 🎯 Selected validator: {address} (Stake: {stake:.2f})")
                return address
        
        return list(self.stake_registry.keys())[0]
    
    def get_statistics(self) -> Dict:
        """Return protocol statistics"""
        return {
            "protocol": "Proof of Stake",
            "participants": len(self.stake_registry),
            "total_staked": self.total_staked,
            "largest_stake": max(self.stake_registry.values()) if self.stake_registry else 0,
            "validator_count": len(self.validator_history)
        }

class DelegatedProofOfStakeProtocol:
    """Delegated Proof of Stake implementation"""
    
    def __init__(self, delegate_count: int = 21):
        self.delegate_count = delegate_count
        self.vote_registry: Dict[str, int] = {}  # delegate -> votes
        self.voter_history: Dict[str, str] = {}  # voter -> delegate
        self.active_delegates: List[str] = []
        self.total_votes_cast = 0
        print(f" 🗳️  DPoS Protocol initialized with {delegate_count} delegate positions")
    
    def submit_vote(self, voter: str, delegate: str, vote_weight: int = 1) -> None:
        """Cast vote for a delegate"""
        if delegate not in self.vote_registry:
            self.vote_registry[delegate] = 0
        
        self.vote_registry[delegate] += vote_weight
        self.voter_history[voter] = delegate
        self.total_votes_cast += vote_weight
        print(f" 📩 {voter} voted for {delegate} (Weight: {vote_weight})")
    
    def election_cycle(self) -> List[str]:
        """Elect delegates based on vote totals"""
        sorted_delegates = sorted(
            self.vote_registry.items(), 
            key=lambda x: -x[1]  # Sort by votes descending
        )
        
        self.active_delegates = [
            delegate for delegate, votes in sorted_delegates[:self.delegate_count]
        ]
        
        print(f"\n 📊 Election Results:")
        print(f"   Total Votes Cast: {self.total_votes_cast}")
        print(f"   Delegate Positions: {len(self.active_delegates)}")
        
        for position, delegate in enumerate(self.active_delegates, 1):
            votes = self.vote_registry.get(delegate, 0)
            print(f"   {position:2d}. {delegate} ({votes} votes)")
        
        return self.active_delegates
    
    def get_statistics(self) -> Dict:
        """Return protocol statistics"""
        return {
            "protocol": "Delegated Proof of Stake",
            "delegate_positions": self.delegate_count,
            "active_delegates": len(self.active_delegates),
            "total_votes": self.total_votes_cast,
            "participants": len(self.voter_history)
        }

class PracticalByzantineFaultTolerance:
    """PBFT consensus implementation for permissioned networks"""
    
    def __init__(self, node_count: int = 4):
        self.node_count = node_count
        self.fault_tolerance = (node_count - 1) // 3
        self.messages_received: List[Dict] = []
        self.prepared_blocks: Dict[int, int] = {}  # block_height -> commit_count
        self.current_sequence = 0
        print(f" 🔒 PBFT Protocol initialized with {node_count} nodes (Fault tolerance: {self.fault_tolerance})")
    
    def propose_block(self, proposer: str, block: Dict) -> Dict:
        """Initiate a PBFT consensus round"""
        self.current_sequence += 1
        block_height = block.get("height", self.current_sequence)
        
        print(f" 📝 {proposer} proposing block {block_height}")
        
        # Simulate pre-prepare phase
        pre_prepare = {
            "phase": "pre-prepare",
            "sequence": self.current_sequence,
            "block": block,
            "proposer": proposer
        }
        self.messages_received.append(pre_prepare)
        
        # Simulate prepare phase (nodes prepare)
        prepare_count = 0
        for node_id in range(1, self.node_count):
            if node_id != proposer:
                prepare = {
                    "phase": "prepare",
                    "sequence": self.current_sequence,
                    "node": node_id,
                    "block_height": block_height
                }
                self.messages_received.append(prepare)
                prepare_count += 1
        
        # Check if enough prepares (2f+1)
        required_prepares = 2 * self.fault_tolerance + 1
        if prepare_count >= required_prepares:
            print(f" ✅ Prepare phase complete: {prepare_count} nodes prepared")
            
            # Simulate commit phase
            commit_count = 0
            for node_id in range(1, self.node_count):
                if node_id != proposer:
                    commit = {
                        "phase": "commit",
                        "sequence": self.current_sequence,
                        "node": node_id,
                        "block_height": block_height
                    }
                    self.messages_received.append(commit)
                    commit_count += 1
            
            # Check if enough commits (2f+1)
            if commit_count >= required_prepares:
                print(f" ✅ Commit phase complete: {block_height} committed")
                self.prepared_blocks[block_height] = commit_count
                return {"status": "committed", "block_height": block_height}
        
        return {"status": "pending", "block_height": block_height}
    
    def get_statistics(self) -> Dict:
        """Return protocol statistics"""
        return {
            "protocol": "Practical Byzantine Fault Tolerance",
            "nodes": self.node_count,
            "fault_tolerance": self.fault_tolerance,
            "committed_blocks": len(self.prepared_blocks),
            "messages": len(self.messages_received)
        }

class ConsensusAnalyzer:
    """Analysis and comparison of consensus mechanisms"""
    
    @staticmethod
    def compare_protocols():
        """Display comprehensive comparison of consensus protocols"""
        print("\n" + "=" * 70)
        print(" CONSENSUS PROTOCOL COMPARISON")
        print("=" * 70)
        
        comparison_data = {
            "Attribute": ["Energy Efficiency", "Finality Speed", "Scalability", "Security", "Decentralization"],
            "PoW": ["Very Low", "Slow", "Poor", "High", "High"],
            "PoS": ["High", "Fast", "Good", "High", "High"],
            "DPoS": ["High", "Fast", "Excellent", "Medium", "Medium"],
            "PBFT": ["High", "Very Fast", "Good", "High", "Low"]
        }
        
        print(f"\n {'Attribute':20} | {'PoW':15} | {'PoS':15} | {'DPoS':15} | {'PBFT':15}")
        print("-" * 85)
        
        for i in range(len(comparison_data["Attribute"])):
            attr = comparison_data["Attribute"][i]
            pow_val = comparison_data["PoW"][i]
            pos_val = comparison_data["PoS"][i]
            dpos_val = comparison_data["DPoS"][i]
            pbft_val = comparison_data["PBFT"][i]
            print(f" {attr:20} | {pow_val:15} | {pos_val:15} | {dpos_val:15} | {pbft_val:15}")
    
    @staticmethod
    def use_case_suitability():
        """Analyze which protocol fits different scenarios"""
        print("\n" + "=" * 70)
        print(" USE CASE SUITABILITY ANALYSIS")
        print("=" * 70)
        
        use_cases = {
            "Public Cryptocurrencies": {"PoW": "⭐⭐⭐⭐⭐", "PoS": "⭐⭐⭐⭐", "DPoS": "⭐⭐⭐", "PBFT": "⭐"},
            "Enterprise Solutions": {"PoW": "⭐", "PoS": "⭐⭐⭐", "DPoS": "⭐⭐⭐⭐", "PBFT": "⭐⭐⭐⭐⭐"},
            "DeFi Platforms": {"PoW": "⭐⭐", "PoS": "⭐⭐⭐⭐", "DPoS": "⭐⭐⭐⭐", "PBFT": "⭐⭐⭐"},
            "Supply Chain": {"PoW": "⭐", "PoS": "⭐⭐", "DPoS": "⭐⭐⭐", "PBFT": "⭐⭐⭐⭐⭐"},
            "Gaming & NFTs": {"PoW": "⭐⭐", "PoS": "⭐⭐⭐⭐", "DPoS": "⭐⭐⭐⭐", "PBFT": "⭐⭐⭐"}
        }
        
        print("\n 📊 Protocol Suitability Matrix:")
        print(f" {'Use Case':20} | {'PoW':10} | {'PoS':10} | {'DPoS':10} | {'PBFT':10}")
        print("-" * 65)
        
        for use_case, ratings in use_cases.items():
            print(f" {use_case:20} | {ratings['PoW']:10} | {ratings['PoS']:10} | {ratings['DPoS']:10} | {ratings['PBFT']:10}")

def demonstrate_consensus_system():
    """Execute comprehensive consensus mechanism demonstration"""
    print("=" * 70)
    print(" DISTRIBUTED AGREEMENT PROTOCOL DEMONSTRATION")
    print("=" * 70)
    
    # Proof of Work
    print("\n ⛏️  PROOF OF WORK (PoW)")
    print("-" * 50)
    pow_protocol = ProofOfWorkProtocol(complexity=3)
    block_data = "Block #1: Genesis Data"
    pow_result = pow_protocol.solve_puzzle(block_data)
    print(f"   Mining Result: Nonce={pow_result['nonce']}, Hash={pow_result['hash'][:16]}...")
    
    # Proof of Stake
    print("\n 💰 PROOF OF STAKE (PoS)")
    print("-" * 50)
    pos_protocol = ProofOfStakeProtocol()
    pos_protocol.deposit_stake("Validator1", 100)
    pos_protocol.deposit_stake("Validator2", 200)
    pos_protocol.deposit_stake("Validator3", 150)
    selected = pos_protocol.select_validator()
    print(f"   Selected Validator: {selected}")
    
    # Delegated Proof of Stake
    print("\n 🗳️  DELEGATED PROOF OF STAKE (DPoS)")
    print("-" * 50)
    dpos_protocol = DelegatedProofOfStakeProtocol(delegate_count=3)
    dpos_protocol.submit_vote("Alice", "Delegate1", 50)
    dpos_protocol.submit_vote("Bob", "Delegate2", 40)
    dpos_protocol.submit_vote("Charlie", "Delegate1", 30)
    dpos_protocol.submit_vote("Diana", "Delegate3", 60)
    dpos_protocol.submit_vote("Eve", "Delegate2", 20)
    delegates = dpos_protocol.election_cycle()
    
    # Practical Byzantine Fault Tolerance
    print("\n 🔒 PRACTICAL BYZANTINE FAULT TOLERANCE (PBFT)")
    print("-" * 50)
    pbft_protocol = PracticalByzantineFaultTolerance(node_count=4)
    block = {"height": 1, "data": "First Block"}
    result = pbft_protocol.propose_block("Node1", block)
    print(f"   Consensus Result: {result}")
    
    # Comprehensive Analysis
    ConsensusAnalyzer.compare_protocols()
    ConsensusAnalyzer.use_case_suitability()
    
    print("\n" + "=" * 70)
    print(" CONSENSUS MECHANISM SUMMARY")
    print("=" * 70)
    print("""
    ┌────────────────┬─────────────────┬──────────────┬─────────────────┐
    │ Protocol       │ Energy Usage    │ Speed        │ Key Example     │
    ├────────────────┼─────────────────┼──────────────┼─────────────────┤
    │ Proof of Work  │ Very High       │ Slow         │ Bitcoin         │
    │ Proof of Stake │ Low             │ Fast         │ Ethereum        │
    │ Delegated PoS  │ Low             │ Very Fast    │ EOS, Tron       │
    │ PBFT           │ Low             │ Very Fast    │ Hyperledger     │
    └────────────────┴─────────────────┴──────────────┴─────────────────┘
    """)
    print("=" * 70 + "\n")

if __name__ == "__main__":
    demonstrate_consensus_system()

2.16 Mining

What is Mining?

Mining is the process of validating transactions and adding them to the blockchain. Miners compete to solve mathematical puzzles to create new blocks. Mining is a critical component of Proof of Work (PoW) blockchains.

How Mining Works:

  1. Transaction Collection: Miners collect pending transactions from the mempool
  2. Block Creation: They create a candidate block with those transactions
  3. Puzzle Solving: They search for a nonce that makes the block hash meet the target
  4. Block Propagation: When found, the block is broadcast to the network
  5. Verification: Other nodes verify and accept the block
  6. Reward: The miner receives block reward + transaction fees

Mining Hardware Evolution:

EraHardwareDescriptionSpeed
2009CPUStandard computer processors1-5 MH/s
2010GPUGraphics cards (100x faster)100-500 MH/s
2012FPGAField Programmable Gate Arrays100-500 MH/s
2013+ASICApplication-Specific ICs100+ TH/s

Mining Pools:

Miners combine their computational power to increase chances of finding blocks. When a pool finds a block, rewards are distributed based on contributed work.

Popular Mining Pools: Antpool, F2Pool, Foundry USA, Binance Pool

Mining Economics:

  • Block Reward: New coins created with each block (Bitcoin: 6.25 BTC)
  • Transaction Fees: Fees paid by users for transaction processing
  • Electricity Cost: Major expense for miners
  • Hardware Cost: ASIC miners are expensive

Code Example – Mining:

"""
BLOCK PRODUCTION ENGINE
=======================
Comprehensive mining and block production simulation with pool functionality
"""

import hashlib
import time
import random
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class MiningStatus(Enum):
    """Status of mining operations"""
    IDLE = "Idle"
    SEARCHING = "Searching"
    BLOCK_FOUND = "Block Found"
    ERROR = "Error"

@dataclass
class MiningResult:
    """Represents the result of a mining attempt"""
    miner_name: str
    nonce_value: int
    hash_result: str
    block_reward: float
    duration_seconds: float
    attempts_made: int
    block_height: int

class BlockProducer:
    """Individual miner implementation with customizable hash power"""
    
    def __init__(self, identifier: str, hash_power: int = 1000):
        self.identifier = identifier
        self.hash_power = hash_power  # Hashes per second (simplified)
        self.blocks_produced = 0
        self.accumulated_rewards = 0.0
        self.total_search_attempts = 0
        self.mining_status = MiningStatus.IDLE
        print(f" ⛏️  Producer '{identifier}' initialized (Hash Power: {hash_power} H/s)")
    
    def search_for_block(self, block_data: str, difficulty: int, max_attempts: Optional[int] = None) -> Optional[MiningResult]:
        """Attempt to find a valid block through proof of work"""
        target_pattern = "0" * difficulty
        start_timestamp = time.time()
        attempts = 0
        nonce = random.randint(0, 1000000000)
        
        # Set max attempts based on hash power
        if max_attempts is None:
            max_attempts = self.hash_power * 2
        
        print(f" 🔍 {self.identifier} searching for block (Difficulty: {difficulty})")
        self.mining_status = MiningStatus.SEARCHING
        
        while attempts < max_attempts:
            # Combine data with nonce and hash
            combined = f"{block_data}{nonce}"
            hash_value = hashlib.sha256(combined.encode()).hexdigest()
            
            # Check if hash meets difficulty
            if hash_value[:difficulty] == target_pattern:
                elapsed = time.time() - start_timestamp
                
                # Calculate reward (base + variable fees)
                base_reward = 6.25
                fee_reward = random.random() * 0.5
                total_reward = base_reward + fee_reward
                
                # Update miner statistics
                self.blocks_produced += 1
                self.accumulated_rewards += total_reward
                self.total_search_attempts += attempts
                self.mining_status = MiningStatus.BLOCK_FOUND
                
                print(f" ✅ {self.identifier} discovered a valid block!")
                print(f"   Nonce: {nonce}")
                print(f"   Hash: {hash_value[:16]}...")
                print(f"   Reward: {total_reward:.2f} units")
                print(f"   Duration: {elapsed:.2f}s")
                print(f"   Attempts: {attempts}")
                
                return MiningResult(
                    miner_name=self.identifier,
                    nonce_value=nonce,
                    hash_result=hash_value,
                    block_reward=total_reward,
                    duration_seconds=elapsed,
                    attempts_made=attempts,
                    block_height=0  # Will be set by caller
                )
            
            nonce += 1
            attempts += 1
            
            # Progress indicator
            if attempts % 5000 == 0:
                progress = (attempts / max_attempts) * 100
                print(f"  Progress: {progress:.1f}% ({attempts} attempts)", end="\r")
        
        self.mining_status = MiningStatus.IDLE
        print(f" ⚠️  {self.identifier} failed to find block after {attempts} attempts")
        return None
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Return producer performance metrics"""
        return {
            "identifier": self.identifier,
            "blocks_produced": self.blocks_produced,
            "accumulated_rewards": self.accumulated_rewards,
            "total_attempts": self.total_search_attempts,
            "hash_power": self.hash_power,
            "status": self.mining_status.value,
            "success_rate": (self.blocks_produced / max(1, self.total_search_attempts)) * 100 if self.total_search_attempts > 0 else 0
        }

class MiningConsortium:
    """Mining pool that aggregates hash power from multiple producers"""
    
    def __init__(self, identifier: str):
        self.identifier = identifier
        self.participants: List[BlockProducer] = []
        self.total_hash_capacity = 0
        self.blocks_discovered = 0
        self.pool_rewards = 0.0
        self.pool_attempts = 0
        print(f" 🏊  Mining Consortium '{identifier}' established")
    
    def enroll_producer(self, producer: BlockProducer) -> None:
        """Add a producer to the mining consortium"""
        if producer not in self.participants:
            self.participants.append(producer)
            self.total_hash_capacity += producer.hash_power
            print(f" ✅ {producer.identifier} enrolled in consortium '{self.identifier}'")
    
    def remove_producer(self, producer: BlockProducer) -> None:
        """Remove a producer from the consortium"""
        if producer in self.participants:
            self.participants.remove(producer)
            self.total_hash_capacity -= producer.hash_power
            print(f" ❌ {producer.identifier} removed from consortium '{self.identifier}'")
    
    def search_for_block(self, block_data: str, difficulty: int, 
                         max_attempts: Optional[int] = None) -> Optional[MiningResult]:
        """Coordinate block search across all consortium participants"""
        print(f" 🔍 Consortium '{self.identifier}' searching with {len(self.participants)} producers")
        print(f"   Total Hash Capacity: {self.total_hash_capacity} H/s")
        
        start_timestamp = time.time()
        total_attempts = 0
        
        # Each producer searches simultaneously (simulated sequentially)
        for producer in self.participants:
            if max_attempts is None:
                # Allocate attempts based on hash power proportion
                producer_attempts = int(producer.hash_power * 2)
            else:
                producer_attempts = max_attempts
            
            result = producer.search_for_block(block_data, difficulty, producer_attempts)
            total_attempts += producer.total_search_attempts
            
            if result:
                # Pool discovered a block
                self.blocks_discovered += 1
                self.pool_rewards += result.block_reward
                self.pool_attempts += total_attempts
                
                elapsed = time.time() - start_timestamp
                print(f"\n 🎯 Consortium '{self.identifier}' discovered block!")
                print(f"   Produced by: {producer.identifier}")
                print(f"   Reward: {result.block_reward:.2f} units")
                print(f"   Total Duration: {elapsed:.2f}s")
                
                return result
        
        # No block found
        print(f" ⚠️  Consortium '{self.identifier}' failed to find block after {total_attempts} attempts")
        return None
    
    def distribute_rewards(self) -> Dict[str, float]:
        """Distribute rewards proportionally to participants based on hash power"""
        if self.blocks_discovered == 0:
            return {}
        
        reward_distribution = {}
        for producer in self.participants:
            # Proportional distribution based on hash power
            share = producer.hash_power / self.total_hash_capacity if self.total_hash_capacity > 0 else 0
            reward_share = self.pool_rewards * share
            reward_distribution[producer.identifier] = reward_share
        
        print(f"\n 📊 Reward Distribution for Consortium '{self.identifier}':")
        for identifier, reward in reward_distribution.items():
            print(f"   {identifier}: {reward:.2f} units")
        
        return reward_distribution
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Return consortium performance metrics"""
        return {
            "identifier": self.identifier,
            "participants": len(self.participants),
            "total_hash_power": self.total_hash_capacity,
            "blocks_discovered": self.blocks_discovered,
            "pool_rewards": self.pool_rewards,
            "pool_attempts": self.pool_attempts,
            "participant_list": [p.identifier for p in self.participants]
        }

class MiningAnalytics:
    """Analysis tools for mining operations"""
    
    @staticmethod
    def compare_mining_models():
        """Compare solo mining versus pool mining"""
        print("\n" + "=" * 60)
        print(" MINING MODEL COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Reward Consistency", "Variance", "Hardware Requirements", "Setup Complexity", "Control"],
            "Solo Mining": ["Very Low", "High", "Significant", "Complex", "Complete"],
            "Pool Mining": ["High", "Low", "Moderate", "Simple", "Shared"]
        }
        
        print(f"\n {'Attribute':20} | {'Solo Mining':25} | {'Pool Mining':20}")
        print("-" * 70)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            solo = comparison["Solo Mining"][i]
            pool = comparison["Pool Mining"][i]
            print(f" {attr:20} | {solo:25} | {pool:20}")
    
    @staticmethod
    def analyze_difficulty_impact():
        """Examine how difficulty affects mining success"""
        print("\n" + "=" * 60)
        print(" DIFFICULTY IMPACT ANALYSIS")
        print("=" * 60)
        
        difficulty_levels = [
            {"level": "Low (1-2)", "time_to_block": "Seconds", "competition": "Low", "hash_required": "Low"},
            {"level": "Medium (3-4)", "time_to_block": "Minutes", "competition": "Medium", "hash_required": "Moderate"},
            {"level": "High (5-6)", "time_to_block": "Hours", "competition": "High", "hash_required": "High"},
            {"level": "Very High (7-8)", "time_to_block": "Days", "competition": "Very High", "hash_required": "Extreme"}
        ]
        
        print("\n 📊 Difficulty Levels:")
        print(f" {'Difficulty':15} | {'Time to Block':15} | {'Competition':12} | {'Hash Required':15}")
        print("-" * 65)
        
        for level in difficulty_levels:
            print(f" {level['level']:15} | {level['time_to_block']:15} | {level['competition']:12} | {level['hash_required']:15}")

def demonstrate_mining_system():
    """Execute comprehensive mining system demonstration"""
    print("=" * 60)
    print(" BLOCK PRODUCTION ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Create individual miners
    print("\n ⛏️  Initializing Individual Producers...")
    alice = BlockProducer("Alice", 500)
    bob = BlockProducer("Bob", 800)
    charlie = BlockProducer("Charlie", 300)
    
    # Solo mining simulation
    print("\n 📝 Solo Mining Simulation:")
    print("-" * 40)
    
    difficulty = 3
    for i in range(3):
        print(f"\n 🔄 Attempt {i+1}:")
        result = alice.search_for_block(f"Block_{i}_Data", difficulty)
        if result:
            print(f"   ✅ Block {i} discovered by Alice!")
            print(f"   Reward: {result.block_reward:.2f} units")
    
    # Create and operate mining pool
    print("\n 🏊  Mining Consortium Setup:")
    print("-" * 40)
    
    consortium = MiningConsortium("SuperPool")
    consortium.enroll_producer(alice)
    consortium.enroll_producer(bob)
    consortium.enroll_producer(charlie)
    
    # Pool mining simulation
    print("\n 📝 Consortium Mining Simulation:")
    pool_result = consortium.search_for_block("Pool_Block_Data", difficulty)
    
    if pool_result:
        print(f"\n ✅ Consortium discovered block!")
        print(f"   Producer: {pool_result.miner_name}")
        print(f"   Reward: {pool_result.block_reward:.2f} units")
        consortium.distribute_rewards()
    
    # Display statistics
    print("\n" + "=" * 60)
    print(" MINING STATISTICS")
    print("=" * 60)
    
    print("\n 📊 Individual Producer Statistics:")
    for producer in [alice, bob, charlie]:
        stats = producer.compile_statistics()
        print(f"\n   🖥️  {stats['identifier']}:")
        print(f"      Blocks Found: {stats['blocks_produced']}")
        print(f"      Rewards: {stats['accumulated_rewards']:.2f} units")
        print(f"      Attempts: {stats['total_attempts']}")
        print(f"      Hash Power: {stats['hash_power']} H/s")
        print(f"      Status: {stats['status']}")
    
    print("\n 📊 Consortium Statistics:")
    stats = consortium.compile_statistics()
    print(f"\n   🏊  {stats['identifier']}:")
    print(f"      Participants: {stats['participants']}")
    print(f"      Total Hash Power: {stats['total_hash_power']} H/s")
    print(f"      Blocks Found: {stats['blocks_discovered']}")
    print(f"      Total Rewards: {stats['pool_rewards']:.2f} units")
    print(f"      Participants: {', '.join(stats['participant_list'])}")
    
    # Additional analysis
    MiningAnalytics.compare_mining_models()
    MiningAnalytics.analyze_difficulty_impact()
    
    print("\n" + "=" * 60)
    print(" MINING CHARACTERISTICS:")
    print("   ✓ Secures the distributed ledger through proof of work")
    print("   ✓ Generates new tokens as block rewards")
    print("   ✓ Processes and validates pending transactions")
    print("   ✓ Energy-intensive computational work")
    print("   ✓ Specialized hardware (ASICs) for large-scale operations")
    print("   ✓ Mining pools enable consistent rewards")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_mining_system()

2.17 Validators

What is a Validator?

In Proof of Stake (PoS) systems, validators are responsible for creating and validating blocks. They are selected based on their stake (locked-up cryptocurrency). Validators replace miners in PoS blockchains.

Validator Responsibilities:

1. Block Proposal:
Validators propose new blocks at specific intervals. The selected validator creates a block with pending transactions and broadcasts it to the network.

2. Voting (Attestation):
Validators vote on proposed blocks. They attest to the validity of blocks they’ve verified. A block is finalized when enough validators agree.

Validators verify that transactions are legitimate by checking digital signatures, available balances, and compliance with the blockchain’s protocol rules.

4. Network Security:
Validators help secure the network by staking tokens. If they misbehave, their stake is slashed (penalized).

Validator Economics:

Rewards:

  • Block rewards: New tokens created with each block
  • Transaction fees: Fees from transactions included in blocks
  • Attestation rewards: Rewards for voting on blocks

Slashing (Penalties):

  • Double-signing: Signing two conflicting blocks → severe penalty
  • Downtime: Being offline → reduced rewards
  • Malicious behavior: Attempting to harm the network → severe penalty

Validator Requirements:

RequirementDescription
StakeMinimum tokens to become validator
HardwareReliable server with good uptime
ConnectivityFast, stable internet
SecuritySecure key management
ExperienceUnderstanding of blockchain operations

Code Example – Validators:

"""
NETWORK CONSENSUS PARTICIPANT FRAMEWORK
=======================================
Complete implementation of validator system with staking, voting, and slashing
"""

import random
import time
import hashlib
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class ValidatorStatus(Enum):
    """Status states for validators"""
    ACTIVE = "Active"
    JAILED = "Jailed"
    SLASHED = "Slashed"
    INACTIVE = "Inactive"

@dataclass
class BlockProposal:
    """Represents a block proposed for consensus"""
    block_hash: str
    proposer: str
    block_data: str
    timestamp: float = field(default_factory=time.time)
    votes_yes: int = 0
    votes_no: int = 0
    status: str = "Pending"

class ValidatorParticipant:
    """Individual validator with staking and voting capabilities"""
    
    def __init__(self, wallet_address: str, staked_amount: float = 1000.0):
        self.wallet_address = wallet_address
        self.staked_tokens = staked_amount
        self.accumulated_rewards = 0.0
        self.uptime_percentage = 100.0
        self.blocks_created = 0
        self.votes_submitted = 0
        self.is_slashed = False
        self.is_jailed = False
        self.jail_reason = ""
        self.slash_reason = ""
        self.status = ValidatorStatus.ACTIVE
        print(f" 🏛️  Validator '{wallet_address[:16]}...' registered with {staked_amount:.2f} tokens")
    
    def submit_block(self, block_content: str) -> Optional[Dict[str, Any]]:
        """Create and propose a new block"""
        if self.status != ValidatorStatus.ACTIVE:
            print(f" ⚠️  Validator {self.wallet_address[:16]}... is not active")
            return None
        
        # Generate block hash
        block_hash = hashlib.sha256(f"{block_content}{time.time()}".encode()).hexdigest()
        self.blocks_created += 1
        
        block_proposal = {
            "hash": block_hash,
            "proposer": self.wallet_address,
            "data": block_content,
            "timestamp": time.time()
        }
        
        print(f" 📝 Validator {self.wallet_address[:16]}... proposed block: {block_hash[:16]}...")
        return block_proposal
    
    def cast_vote(self, block: Dict[str, Any], vote_choice: str = "Yes") -> str:
        """Vote on a proposed block"""
        if self.status != ValidatorStatus.ACTIVE:
            print(f" ⚠️  Validator {self.wallet_address[:16]}... cannot vote")
            return "Abstain"
        
        self.votes_submitted += 1
        
        # Simulate honest behavior with occasional random variation
        if random.random() < 0.02:  # 2% chance of accidental wrong vote
            vote_choice = "No" if vote_choice == "Yes" else "Yes"
        
        print(f" 🗳️  Validator {self.wallet_address[:16]}... voted {vote_choice} on block {block['hash'][:16]}...")
        return vote_choice
    
    def claim_reward_share(self) -> float:
        """Collect staking rewards"""
        if self.status == ValidatorStatus.SLASHED:
            print(f" ❌ Validator {self.wallet_address[:16]}... cannot claim rewards")
            return 0.0
        
        if self.status == ValidatorStatus.JAILED:
            print(f" ⚠️  Validator {self.wallet_address[:16]}... jailed - reduced rewards")
        
        # Calculate reward based on performance and uptime
        reward_multiplier = 0.05 if self.status == ValidatorStatus.ACTIVE else 0.02
        reward_amount = self.staked_tokens * reward_multiplier * (self.uptime_percentage / 100)
        
        self.accumulated_rewards += reward_amount
        self.staked_tokens += reward_amount
        
        print(f" 💰 Validator {self.wallet_address[:16]}... claimed {reward_amount:.2f} tokens")
        return reward_amount
    
    def apply_slash_penalty(self, reason: str, penalty_percentage: float = 0.10) -> float:
        """Apply slashing penalty for misbehavior"""
        if self.status == ValidatorStatus.SLASHED:
            return 0.0
        
        penalty_amount = self.staked_tokens * penalty_percentage
        self.staked_tokens -= penalty_amount
        self.is_slashed = True
        self.slash_reason = reason
        self.status = ValidatorStatus.SLASHED
        
        print(f" ⚠️  Validator {self.wallet_address[:16]}... SLASHED!")
        print(f"   Reason: {reason}")
        print(f"   Penalty: {penalty_amount:.2f} tokens")
        return penalty_amount
    
    def apply_jail_sentence(self, reason: str, duration_hours: int = 24) -> None:
        """Jail validator temporarily"""
        if self.status == ValidatorStatus.SLASHED:
            return
        
        self.is_jailed = True
        self.jail_reason = reason
        self.status = ValidatorStatus.JAILED
        
        print(f" ⛓️  Validator {self.wallet_address[:16]}... JAILED!")
        print(f"   Reason: {reason}")
        print(f"   Duration: {duration_hours} hours")
    
    def release_from_jail(self) -> None:
        """Release validator from jail"""
        if self.status == ValidatorStatus.JAILED:
            self.is_jailed = False
            self.status = ValidatorStatus.ACTIVE
            print(f" ✅ Validator {self.wallet_address[:16]}... released from jail")
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Return validator statistics"""
        return {
            "address": self.wallet_address[:16] + "...",
            "staked_tokens": self.staked_tokens,
            "accumulated_rewards": self.accumulated_rewards,
            "uptime": f"{self.uptime_percentage:.1f}%",
            "blocks_created": self.blocks_created,
            "votes_submitted": self.votes_submitted,
            "status": self.status.value,
            "jailed": self.is_jailed,
            "slashed": self.is_slashed
        }

class ValidatorConsortium:
    """Complete validator system managing multiple validators"""
    
    def __init__(self):
        self.validators: Dict[str, ValidatorParticipant] = {}
        self.block_history: List[Dict] = []
        self.pending_proposals: Dict[str, BlockProposal] = {}
        self.consensus_rounds = 0
        print(" 🏛️  Validator Consortium initialized")
    
    def enroll_validator(self, wallet_address: str, initial_stake: float = 1000.0) -> Optional[ValidatorParticipant]:
        """Register a new validator in the consortium"""
        if wallet_address in self.validators:
            print(f" ⚠️  Validator {wallet_address[:16]}... already registered")
            return self.validators[wallet_address]
        
        validator = ValidatorParticipant(wallet_address, initial_stake)
        self.validators[wallet_address] = validator
        return validator
    
    def select_proposer(self) -> Optional[ValidatorParticipant]:
        """Select a validator to propose the next block (weighted by stake)"""
        active_validators = [
            v for v in self.validators.values() 
            if v.status == ValidatorStatus.ACTIVE
        ]
        
        if not active_validators:
            print(" ⚠️  No active validators available")
            return None
        
        total_stake = sum(v.staked_tokens for v in active_validators)
        
        if total_stake == 0:
            print(" ⚠️  No stake available among validators")
            return None
        
        # Weighted random selection based on stake
        selection_point = random.random() * total_stake
        cumulative = 0.0
        
        for validator in active_validators:
            cumulative += validator.staked_tokens
            if cumulative >= selection_point:
                print(f" 🎯 Selected proposer: {validator.wallet_address[:16]}... (Stake: {validator.staked_tokens:.2f})")
                return validator
        
        return active_validators[0]
    
    def propose_block(self, block_content: str) -> Optional[Dict[str, Any]]:
        """Propose a new block using selected validator"""
        proposer = self.select_proposer()
        if not proposer:
            return None
        
        block = proposer.submit_block(block_content)
        if block:
            block_hash = block["hash"]
            self.pending_proposals[block_hash] = BlockProposal(
                block_hash=block_hash,
                proposer=proposer.wallet_address,
                block_data=block_content
            )
            self.block_history.append(block)
            self.consensus_rounds += 1
        
        return block
    
    def process_voting(self, block_hash: str) -> bool:
        """Conduct voting round on a proposed block"""
        if block_hash not in self.pending_proposals:
            print(f" ❌ Block {block_hash[:16]}... not found in pending proposals")
            return False
        
        proposal = self.pending_proposals[block_hash]
        votes_yes = 0
        votes_no = 0
        
        print(f"\n 🗳️  Voting on block {block_hash[:16]}...")
        
        # All active validators vote
        for validator in self.validators.values():
            if validator.status == ValidatorStatus.ACTIVE:
                vote = validator.cast_vote({"hash": block_hash}, "Yes")
                if vote == "Yes":
                    votes_yes += 1
                elif vote == "No":
                    votes_no += 1
        
        # Update proposal with vote counts
        proposal.votes_yes = votes_yes
        proposal.votes_no = votes_no
        
        # Determine if block is accepted (>50% yes)
        total_votes = votes_yes + votes_no
        if total_votes > 0 and (votes_yes / total_votes) > 0.5:
            print(f" ✅ Block {block_hash[:16]}... ACCEPTED!")
            proposal.status = "Accepted"
            self.pending_proposals.pop(block_hash)
            
            # Distribute rewards to all active validators
            self._distribute_rewards()
            return True
        else:
            print(f" ❌ Block {block_hash[:16]}... REJECTED!")
            proposal.status = "Rejected"
            self.pending_proposals.pop(block_hash)
            return False
    
    def _distribute_rewards(self) -> None:
        """Distribute rewards to all active validators"""
        for validator in self.validators.values():
            if validator.status == ValidatorStatus.ACTIVE:
                validator.claim_reward_share()
            elif validator.status == ValidatorStatus.JAILED:
                # Reduced rewards for jailed validators
                validator.claim_reward_share()
    
    def handle_misbehavior(self, validator_address: str, violation: str, severity: str = "medium") -> None:
        """Process validator misbehavior with appropriate penalties"""
        if validator_address not in self.validators:
            print(f" ❌ Validator {validator_address[:16]}... not found")
            return
        
        validator = self.validators[validator_address]
        
        if severity == "high":
            # Slash for severe violations
            validator.apply_slash_penalty(f"Severe: {violation}", 0.20)
        elif severity == "medium":
            # Jail for moderate violations
            validator.apply_jail_sentence(f"Medium: {violation}", 48)
        else:
            # Warning for minor violations
            print(f" ⚠️  Warning issued to {validator_address[:16]}... for: {violation}")
    
    def display_validators(self) -> None:
        """Display all validators and their status"""
        print("\n" + "=" * 60)
        print(" 🏛️  VALIDATOR CONSORTIUM STATUS")
        print("=" * 60)
        
        for address, validator in self.validators.items():
            stats = validator.compile_statistics()
            print(f"\n 📍 {stats['address']}")
            print(f"   💰 Stake: {stats['staked_tokens']:.2f}")
            print(f"   🎁 Rewards: {stats['accumulated_rewards']:.2f}")
            print(f"   ⏱️  Uptime: {stats['uptime']}")
            print(f"   📦 Blocks: {stats['blocks_created']}")
            print(f"   🗳️  Votes: {stats['votes_submitted']}")
            print(f"   📊 Status: {stats['status']}")
            
            if validator.is_jailed:
                print(f"   ⛓️  Jail Reason: {validator.jail_reason}")
            if validator.is_slashed:
                print(f"   ⚠️  Slash Reason: {validator.slash_reason}")
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Return consortium statistics"""
        active_count = sum(1 for v in self.validators.values() if v.status == ValidatorStatus.ACTIVE)
        total_stake = sum(v.staked_tokens for v in self.validators.values())
        
        return {
            "total_validators": len(self.validators),
            "active_validators": active_count,
            "total_stake": total_stake,
            "blocks_proposed": len(self.block_history),
            "consensus_rounds": self.consensus_rounds,
            "pending_proposals": len(self.pending_proposals)
        }

class ValidatorAnalytics:
    """Analysis tools for validator system"""
    
    @staticmethod
    def compare_consensus_participation():
        """Compare validator roles with other consensus participants"""
        print("\n" + "=" * 60)
        print(" CONSENSUS PARTICIPANT COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Energy Efficiency", "Hardware Requirements", "Reward Model", "Risk", "Control"],
            "Miners": ["Very Low", "High", "Block Rewards", "High", "Decentralized"],
            "Validators": ["High", "Moderate", "Staking Rewards", "Medium", "Centralized"]
        }
        
        print(f"\n {'Attribute':20} | {'Miners':25} | {'Validators':20}")
        print("-" * 70)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            miners = comparison["Miners"][i]
            validators = comparison["Validators"][i]
            print(f" {attr:20} | {miners:25} | {validators:20}")
    
    @staticmethod
    def analyze_validator_risks():
        """Examine risks associated with validator operation"""
        print("\n" + "=" * 60)
        print(" VALIDATOR RISK ANALYSIS")
        print("=" * 60)
        
        risks = {
            "Slashing": {"description": "Loss of staked tokens", "probability": "Low", "impact": "High"},
            "Jailing": {"description": "Temporary suspension", "probability": "Medium", "impact": "Medium"},
            "Network Issues": {"description": "Reduced uptime", "probability": "Medium", "impact": "Low"},
            "Competition": {"description": "Reduced rewards", "probability": "High", "impact": "Low"},
            "Governance Changes": {"description": "Protocol updates", "probability": "Low", "impact": "Medium"}
        }
        
        print("\n 📊 Risk Assessment:")
        print(f" {'Risk Category':25} | {'Description':20} | {'Probability':12} | {'Impact':10}")
        print("-" * 75)
        
        for risk, details in risks.items():
            print(f" {risk:25} | {details['description']:20} | {details['probability']:12} | {details['impact']:10}")

def demonstrate_validator_system():
    """Execute comprehensive validator system demonstration"""
    print("=" * 60)
    print(" NETWORK CONSENSUS PARTICIPANT DEMONSTRATION")
    print("=" * 60)
    
    # Initialize validator consortium
    consortium = ValidatorConsortium()
    
    # Register validators
    print("\n 📝 Registering validators...")
    validator_addresses = [
        "0x1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b",
        "0x2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c",
        "0x3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d",
        "0x4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e"
    ]
    
    stakes = [1000, 2000, 1500, 500]
    for addr, stake in zip(validator_addresses, stakes):
        consortium.enroll_validator(addr, stake)
    
    # Propose blocks
    print("\n 📝 Proposing blocks...")
    block_data = [
        "Block #1: Transaction Data",
        "Block #2: Smart Contract Execution",
        "Block #3: State Update"
    ]
    
    for data in block_data:
        block = consortium.propose_block(data)
        if block:
            consortium.process_voting(block["hash"])
    
    # Handle misbehavior
    print("\n ⚠️  Handling misbehavior...")
    consortium.handle_misbehavior(validator_addresses[1], "Double signing", severity="high")
    consortium.handle_misbehavior(validator_addresses[2], "Low participation", severity="medium")
    
    # Additional block proposal after penalties
    print("\n 📝 Proposing block after penalties...")
    block = consortium.propose_block("Block #4: Recovery Block")
    if block:
        consortium.process_voting(block["hash"])
    
    # Display validator status
    consortium.display_validators()
    
    # Display consortium statistics
    stats = consortium.compile_statistics()
    print("\n" + "=" * 60)
    print(" 📊 CONSORTIUM STATISTICS")
    print("=" * 60)
    for key, value in stats.items():
        print(f"   {key}: {value}")
    
    # Additional analysis
    ValidatorAnalytics.compare_consensus_participation()
    ValidatorAnalytics.analyze_validator_risks()
    
    print("\n" + "=" * 60)
    print(" VALIDATOR CHARACTERISTICS:")
    print("   ✓ Secures network through Proof of Stake")
    print("   ✓ Energy efficient (no computational puzzles)")
    print("   ✓ Rewards for honest participation")
    print("   ✓ Slashing for misbehavior")
    print("   ✓ Minimum staking requirement")
    print("   ✓ Jail mechanism for temporary penalties")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_validator_system()

2.18 Finality

What is Finality?

Finality is the property that a transaction cannot be reversed once it reaches a certain number of confirmations. It’s the point at which a transaction is considered permanent and irreversible.

Why Finality Matters:

Irreversibility: Once final, transactions cannot be reversed, providing certainty to users and businesses.

Security: Finality means the transaction is cryptographically secure and cannot be double-spent.

Trust: Users can confidently act on the transaction (e.g., delivering goods) once it’s final.

Types of Finality:

1. Probabilistic Finality:

Used by Proof of Work (Bitcoin). The probability of reversal decreases exponentially with each confirmation. After 6 confirmations (~1 hour), reversal is economically impossible.

  • Probability: 1 – (1/2)^confirmations
  • Time: ~1 hour (6 confirmations)
  • Guarantee: Probabilistic, not absolute

2. Deterministic Finality:

Used by Proof of Stake (Ethereum). Finality is guaranteed after a specific number of blocks or votes. Once achieved, the transaction is absolutely irreversible.

  • Probability: 100%
  • Time: ~6 minutes (Ethereum)
  • Guarantee: Absolute

3. Economic Finality:

The cost of reversing a transaction exceeds the potential benefit. Used by some fast blockchains (Solana, Cosmos).

  • Probability: Very high
  • Time: Seconds
  • Guarantee: Economic, not cryptographic

Code Example – Finality:

"""
TRANSACTION SETTLEMENT FRAMEWORK
=================================
Comprehensive implementation of blockchain finality mechanisms and settlement guarantees
"""

import time
import math
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class ConsensusProtocol(Enum):
    """Available consensus protocols"""
    PROOF_OF_WORK = "Proof of Work"
    PROOF_OF_STAKE = "Proof of Stake"
    DELEGATED_PROOF = "Delegated Proof of Stake"
    PRACTICAL_BFT = "Practical Byzantine Fault Tolerance"

@dataclass
class ChainBlock:
    """Represents a block in the blockchain"""
    height: int
    timestamp: float = field(default_factory=time.time)
    transactions: List[Dict] = field(default_factory=list)
    hash_value: str = ""
    previous_hash: str = ""

@dataclass
class FinalityStatus:
    """Status of finality for a given block"""
    is_final: bool
    confirmation_count: int
    reversal_probability: float
    time_elapsed_seconds: float
    time_elapsed_minutes: float
    required_confirmations: int
    description: str

class SettlementEngine:
    """Manages finality determination for blockchain transactions"""
    
    def __init__(self, protocol_type: ConsensusProtocol = ConsensusProtocol.PROOF_OF_WORK):
        self.protocol_type = protocol_type
        self.block_chain: List[ChainBlock] = []
        self.finalized_blocks: List[ChainBlock] = []
        self.settlement_threshold = 6  # Standard for PoW
        self.block_time_seconds = 600  # PoW: 10 minutes per block
        
        # Protocol-specific settings
        if protocol_type == ConsensusProtocol.PROOF_OF_STAKE:
            self.settlement_threshold = 2
            self.block_time_seconds = 12  # PoS: 12 seconds per block
        elif protocol_type == ConsensusProtocol.DELEGATED_PROOF:
            self.settlement_threshold = 1
            self.block_time_seconds = 3  # DPoS: 3 seconds per block
        elif protocol_type == ConsensusProtocol.PRACTICAL_BFT:
            self.settlement_threshold = 1
            self.block_time_seconds = 1  # PBFT: ~1 second per block
        
        print(f" ⚖️  Settlement Engine initialized ({protocol_type.value})")
        print(f"   Required Confirmations: {self.settlement_threshold}")
        print(f"   Block Time: {self.block_time_seconds}s")
    
    def append_block(self, block_data: Dict) -> ChainBlock:
        """Add a new block to the chain"""
        new_height = len(self.block_chain)
        new_block = ChainBlock(
            height=new_height,
            transactions=block_data.get("transactions", []),
            hash_value=block_data.get("hash", f"block_{new_height}"),
            previous_hash=block_data.get("previous_hash", "0" * 64)
        )
        self.block_chain.append(new_block)
        print(f" 📦 Block {new_height} appended to chain")
        return new_block
    
    def generate_chain(self, block_count: int = 10, tx_per_block: int = 3) -> None:
        """Simulate chain creation with sample blocks"""
        print(f" 🔄 Generating {block_count} blocks...")
        for i in range(block_count):
            sample_txs = [
                {"from": f"Alice_{j}", "to": f"Bob_{j}", "amount": 10 * (j + 1)}
                for j in range(tx_per_block)
            ]
            block_data = {
                "height": i,
                "transactions": sample_txs,
                "hash": f"hash_{i}_{int(time.time())}",
                "previous_hash": f"hash_{i-1}_{int(time.time())}" if i > 0 else "0" * 64
            }
            self.append_block(block_data)
    
    def assess_finality_pow(self, block_height: int) -> FinalityStatus:
        """Evaluate finality for Proof of Work (probabilistic)"""
        current_height = len(self.block_chain) - 1
        
        if block_height > current_height:
            return FinalityStatus(
                is_final=False,
                confirmation_count=0,
                reversal_probability=1.0,
                time_elapsed_seconds=0,
                time_elapsed_minutes=0,
                required_confirmations=self.settlement_threshold,
                description="Block not yet mined"
            )
        
        confirmations = current_height - block_height
        
        # Calculate probability of reversal (exponential decay)
        reversal_prob = math.pow(0.5, confirmations)
        
        is_final = confirmations >= self.settlement_threshold
        elapsed_time = confirmations * self.block_time_seconds
        
        status_desc = "Finalized" if is_final else "Pending"
        
        return FinalityStatus(
            is_final=is_final,
            confirmation_count=confirmations,
            reversal_probability=reversal_prob,
            time_elapsed_seconds=elapsed_time,
            time_elapsed_minutes=elapsed_time / 60,
            required_confirmations=self.settlement_threshold,
            description=f"{status_desc} - {confirmations}/{self.settlement_threshold} confirmations"
        )
    
    def assess_finality_pos(self, block_height: int) -> FinalityStatus:
        """Evaluate finality for Proof of Stake (deterministic)"""
        current_height = len(self.block_chain) - 1
        
        if block_height > current_height:
            return FinalityStatus(
                is_final=False,
                confirmation_count=0,
                reversal_probability=1.0,
                time_elapsed_seconds=0,
                time_elapsed_minutes=0,
                required_confirmations=self.settlement_threshold,
                description="Block not yet mined"
            )
        
        confirmations = current_height - block_height
        
        # PoS has deterministic finality after 2 confirmations
        is_final = confirmations >= self.settlement_threshold
        reversal_prob = 0.0 if is_final else 0.01  # Very low if not final
        elapsed_time = confirmations * self.block_time_seconds
        
        status_desc = "Finalized (Deterministic)" if is_final else "Finalizing"
        
        return FinalityStatus(
            is_final=is_final,
            confirmation_count=confirmations,
            reversal_probability=reversal_prob,
            time_elapsed_seconds=elapsed_time,
            time_elapsed_minutes=elapsed_time / 60,
            required_confirmations=self.settlement_threshold,
            description=f"{status_desc} - {confirmations}/{self.settlement_threshold} confirmations"
        )
    
    def assess_finality_dpos(self, block_height: int) -> FinalityStatus:
        """Evaluate finality for Delegated Proof of Stake"""
        current_height = len(self.block_chain) - 1
        
        if block_height > current_height:
            return FinalityStatus(
                is_final=False,
                confirmation_count=0,
                reversal_probability=1.0,
                time_elapsed_seconds=0,
                time_elapsed_minutes=0,
                required_confirmations=self.settlement_threshold,
                description="Block not yet mined"
            )
        
        confirmations = current_height - block_height
        
        # DPoS finality is very fast
        is_final = confirmations >= 1
        reversal_prob = 0.0001 if not is_final else 0.0
        elapsed_time = confirmations * self.block_time_seconds
        
        status_desc = "Finalized (Instant)" if is_final else "Finalizing"
        
        return FinalityStatus(
            is_final=is_final,
            confirmation_count=confirmations,
            reversal_probability=reversal_prob,
            time_elapsed_seconds=elapsed_time,
            time_elapsed_minutes=elapsed_time / 60,
            required_confirmations=self.settlement_threshold,
            description=f"{status_desc} - {confirmations}/{self.settlement_threshold} confirmations"
        )
    
    def assess_finality_pbft(self, block_height: int) -> FinalityStatus:
        """Evaluate finality for Practical Byzantine Fault Tolerance"""
        current_height = len(self.block_chain) - 1
        
        if block_height > current_height:
            return FinalityStatus(
                is_final=False,
                confirmation_count=0,
                reversal_probability=1.0,
                time_elapsed_seconds=0,
                time_elapsed_minutes=0,
                required_confirmations=self.settlement_threshold,
                description="Block not yet proposed"
            )
        
        confirmations = current_height - block_height
        
        # PBFT has immediate finality
        is_final = confirmations >= 1
        reversal_prob = 0.0
        elapsed_time = confirmations * self.block_time_seconds
        
        status_desc = "Finalized (Immediate)" if is_final else "Finalizing"
        
        return FinalityStatus(
            is_final=is_final,
            confirmation_count=confirmations,
            reversal_probability=reversal_prob,
            time_elapsed_seconds=elapsed_time,
            time_elapsed_minutes=elapsed_time / 60,
            required_confirmations=self.settlement_threshold,
            description=f"{status_desc} - {confirmations}/{self.settlement_threshold} confirmations"
        )
    
    def evaluate_settlement(self, block_height: int) -> FinalityStatus:
        """Determine finality status based on protocol type"""
        if self.protocol_type == ConsensusProtocol.PROOF_OF_WORK:
            return self.assess_finality_pow(block_height)
        elif self.protocol_type == ConsensusProtocol.PROOF_OF_STAKE:
            return self.assess_finality_pos(block_height)
        elif self.protocol_type == ConsensusProtocol.DELEGATED_PROOF:
            return self.assess_finality_dpos(block_height)
        elif self.protocol_type == ConsensusProtocol.PRACTICAL_BFT:
            return self.assess_finality_pbft(block_height)
        else:
            return self.assess_finality_pow(block_height)
    
    def display_finality_status(self, block_height: int) -> None:
        """Display finality information for a specific block"""
        status = self.evaluate_settlement(block_height)
        
        print("\n" + "=" * 60)
        print(f" ⚖️  SETTLEMENT STATUS (Block {block_height})")
        print("=" * 60)
        
        print(f"\n Protocol: {self.protocol_type.value}")
        print(f" Confirmations: {status.confirmation_count}")
        print(f" Required: {status.required_confirmations}")
        print(f" Final: {'✅ Yes' if status.is_final else '⏳ No'}")
        print(f" Reversal Probability: {status.reversal_probability:.4%}")
        print(f" Time Elapsed: {status.time_elapsed_minutes:.1f} minutes")
        print(f" Status: {status.description}")
        
        if not status.is_final:
            needed = status.required_confirmations - status.confirmation_count
            print(f"\n ⏱️  Needed: {needed} more confirmations")
            estimated_time = needed * self.block_time_seconds
            if estimated_time < 60:
                print(f"   Estimated: {estimated_time:.0f} seconds")
            else:
                print(f"   Estimated: {estimated_time / 60:.1f} minutes")

class SettlementAnalytics:
    """Analysis tools for finality mechanisms"""
    
    @staticmethod
    def compare_finality_properties():
        """Compare finality characteristics across protocols"""
        print("\n" + "=" * 60)
        print(" FINALITY PROPERTIES COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Type", "Confirmations Required", "Block Time", "Finality Guarantee", "Reversal Risk"],
            "PoW": ["Probabilistic", "6", "10 min", "High (6+ blocks)", "Decreasing"],
            "PoS": ["Deterministic", "2", "12 sec", "Absolute", "None"],
            "DPoS": ["Economic", "1", "3 sec", "High (Economic)", "Very Low"],
            "PBFT": ["Absolute", "1", "1 sec", "Absolute", "None"]
        }
        
        print(f"\n {'Attribute':25} | {'PoW':15} | {'PoS':15} | {'DPoS':15} | {'PBFT':15}")
        print("-" * 90)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            pow_val = comparison["PoW"][i]
            pos_val = comparison["PoS"][i]
            dpos_val = comparison["DPoS"][i]
            pbft_val = comparison["PBFT"][i]
            print(f" {attr:25} | {pow_val:15} | {pos_val:15} | {dpos_val:15} | {pbft_val:15}")
    
    @staticmethod
    def analyze_finality_tradeoffs():
        """Examine trade-offs between security and speed"""
        print("\n" + "=" * 60)
        print(" FINALITY TRADE-OFF ANALYSIS")
        print("=" * 60)
        
        tradeoffs = {
            "Factor": ["Speed", "Security", "Decentralization", "Scalability", "Complexity"],
            "Fast Finality": ["⭐⭐⭐⭐⭐", "⭐⭐", "⭐⭐", "⭐⭐⭐⭐", "⭐⭐⭐⭐⭐"],
            "Slow Finality": ["⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐", "⭐⭐"]
        }
        
        print("\n 📊 Trade-off Matrix:")
        print(f" {'Factor':20} | {'Fast Finality':20} | {'Slow Finality':20}")
        print("-" * 65)
        
        for i in range(len(tradeoffs["Factor"])):
            factor = tradeoffs["Factor"][i]
            fast = tradeoffs["Fast Finality"][i]
            slow = tradeoffs["Slow Finality"][i]
            print(f" {factor:20} | {fast:20} | {slow:20}")

def demonstrate_finality_system():
    """Execute comprehensive finality demonstration"""
    print("=" * 60)
    print(" TRANSACTION SETTLEMENT FRAMEWORK DEMONSTRATION")
    print("=" * 60)
    
    protocols = [
        ConsensusProtocol.PROOF_OF_WORK,
        ConsensusProtocol.PROOF_OF_STAKE,
        ConsensusProtocol.DELEGATED_PROOF,
        ConsensusProtocol.PRACTICAL_BFT
    ]
    
    for protocol in protocols:
        print(f"\n {'='*60}")
        print(f" {protocol.value.upper()} SETTLEMENT")
        print("-" * 60)
        
        engine = SettlementEngine(protocol)
        engine.generate_chain(10, 3)
        
        # Check finality at different heights
        block_heights = [1, 3, 5, 7, 9]
        for height in block_heights:
            engine.display_finality_status(height)
    
    # Additional analysis
    SettlementAnalytics.compare_finality_properties()
    SettlementAnalytics.analyze_finality_tradeoffs()
    
    print("\n" + "=" * 60)
    print(" SETTLEMENT CHARACTERISTICS:")
    print("   ✓ Settlement = Point of transaction irreversibility")
    print("   ✓ Faster settlement = Better user experience")
    print("   ✓ Higher security = More confirmations required")
    print("   ✓ PoW: Probabilistic finality (increasing confidence)")
    print("   ✓ PoS: Deterministic finality (absolute guarantee)")
    print("   ✓ Trade-off: Speed vs. Security")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_finality_system()

2.19 Forks

What is a Fork?

A fork occurs when a blockchain splits into two separate versions. This can happen when participants disagree over protocol rules or when the network undergoes a major upgrade.

Why Forks Happen:

Protocol Upgrades: New features or improvements to the blockchain

Disagreements: When the community can’t agree on protocol changes

Security Patches: Fixing vulnerabilities in the protocol

Bug Fixes: Correcting issues in the protocol

Types of Forks:

1. Soft Fork:

A soft fork is a backwards-compatible upgrade. Old nodes can still validate blocks, but they might miss some new features. The new protocol rules are more restrictive than the previous rules.

How it Works:

  • Old nodes accept new blocks (they appear valid)
  • New nodes enforce stricter rules
  • The chain continues without splitting

Examples:

  • SegWit (Bitcoin)
  • P2SH (Bitcoin)

Characteristics:

  • Backwards compatible
  • Only requires majority of miners to upgrade
  • Less disruptive

2. Hard Fork:

A hard fork is a non-backwards-compatible upgrade. Old nodes cannot validate new blocks. The blockchain splits into two separate chains, each following its own set of rules.

How it Works:

  • Old nodes reject new blocks
  • Two separate chains emerge
  • Both chains continue independently

Examples:

  • Bitcoin Cash (from Bitcoin)
  • Ethereum Classic (from Ethereum)
  • Bitcoin Gold (from Bitcoin)

Characteristics:

  • Not backwards compatible
  • Requires all nodes to upgrade
  • Creates a new blockchain

Code Example – Forks:

"""
CHAIN DIVERGENCE FRAMEWORK
==========================
Comprehensive simulation of blockchain forks including soft and hard forks
"""

import time
import hashlib
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class ForkType(Enum):
    """Classification of fork types"""
    SOFT_FORK = "Soft Fork (Backwards Compatible)"
    HARD_FORK = "Hard Fork (Not Backwards Compatible)"
    ACCIDENTAL = "Accidental Fork"
    CONTENTIOUS = "Contentious Fork"

@dataclass
class ChainBlock:
    """Represents a block in the blockchain"""
    height: int
    data: str
    version: int
    timestamp: float = field(default_factory=time.time)
    block_hash: str = ""
    previous_hash: str = ""
    
    def __post_init__(self):
        if not self.block_hash:
            self.block_hash = hashlib.sha256(
                f"{self.height}{self.data}{self.version}{self.timestamp}".encode()
            ).hexdigest()[:16]

class DistributedLedgerWithForks:
    """Blockchain implementation with fork simulation capabilities"""
    
    def __init__(self, identifier: str):
        self.identifier = identifier
        self.chain: List[ChainBlock] = []
        self.network_nodes: List[str] = []
        self.fork_history: List[Dict] = []
        self.create_origin_block()
        print(f" 📋 Ledger '{identifier}' initialized")
    
    def create_origin_block(self) -> None:
        """Establish the genesis block"""
        origin = ChainBlock(height=0, data="Genesis Block", version=1)
        self.chain.append(origin)
        print(f"   Origin block created at height 0")
    
    def append_block(self, block_data: str, version: int = 1) -> ChainBlock:
        """Add a new block to the chain"""
        new_height = len(self.chain)
        previous_hash = self.chain[-1].block_hash if self.chain else "0" * 16
        
        new_block = ChainBlock(
            height=new_height,
            data=block_data,
            version=version,
            previous_hash=previous_hash
        )
        self.chain.append(new_block)
        print(f"   ✅ Block {new_height} appended: {block_data[:30]}...")
        return new_block
    
    def enroll_node(self, node_name: str) -> None:
        """Add a node to the network"""
        if node_name not in self.network_nodes:
            self.network_nodes.append(node_name)
            print(f"   🔗 Node '{node_name}' joined network")
    
    def render_chain(self) -> None:
        """Display the complete blockchain"""
        print(f"\n 📊 {self.identifier} Blockchain:")
        print("-" * 50)
        for block in self.chain:
            print(f"  #{block.height:3d} | v{block.version} | {block.data[:40]:40} | {block.block_hash[:8]}...")
        print("-" * 50)
        print(f"  Total Blocks: {len(self.chain)}")
    
    def initiate_soft_fork(self, new_data: str, new_version: int = 2) -> ChainBlock:
        """Perform a soft fork (backwards compatible)"""
        print(f"\n 🔄 SOFT FORK on {self.identifier}")
        print(f"   New version {new_version} - Backwards Compatible")
        
        # Old nodes can still validate new blocks
        block = self.append_block(new_data, new_version)
        
        print(f"   ✅ Soft fork completed at block {block.height}")
        print(f"   💡 Old nodes see this as valid (backwards compatible)")
        print(f"   💡 New rules are a superset of old rules")
        
        self.fork_history.append({
            "type": "soft",
            "height": block.height,
            "version": new_version,
            "description": new_data
        })
        
        return block
    
    def initiate_hard_fork(self, new_data: str, new_version: int = 2) -> 'DistributedLedgerWithForks':
        """Perform a hard fork (not backwards compatible)"""
        print(f"\n 🔄 HARD FORK on {self.identifier}")
        print(f"   New version {new_version} - NOT Backwards Compatible")
        
        # Create new ledger for hard fork
        forked_ledger = DistributedLedgerWithForks(f"{self.identifier} (Hard Fork)")
        
        # Copy existing blocks to new ledger
        for block in self.chain:
            new_block = ChainBlock(
                height=block.height,
                data=block.data,
                version=block.version,
                timestamp=block.timestamp,
                previous_hash=block.previous_hash
            )
            forked_ledger.chain.append(new_block)
        
        # Add new block with new version
        forked_block = forked_ledger.append_block(new_data, new_version)
        
        print(f"   ✅ Hard fork completed at block {forked_block.height}")
        print(f"   ⚠️  Old nodes cannot validate new blocks!")
        print(f"   ⚠️  Chain split! Two separate ledgers now exist")
        
        self.fork_history.append({
            "type": "hard",
            "height": forked_block.height,
            "version": new_version,
            "description": new_data,
            "forked_ledger": forked_ledger.identifier
        })
        
        return forked_ledger
    
    def simulate_accidental_fork(self, node_name: str, block_data: str) -> None:
        """Simulate an accidental fork from different nodes"""
        print(f"\n ⚠️  Accidental Fork on {self.identifier}")
        print(f"   Node '{node_name}' created block with '{block_data[:20]}...'")
        
        # Create a block that diverges
        forked_block = ChainBlock(
            height=len(self.chain),
            data=block_data,
            version=1
        )
        
        print(f"   ⚠️  Block {forked_block.height} diverges from main chain")
        print(f"   💡 Network will resolve the longest chain")
        
        self.fork_history.append({
            "type": "accidental",
            "height": forked_block.height,
            "description": block_data,
            "node": node_name
        })

class ForkAnalyzer:
    """Analysis tools for blockchain forks"""
    
    @staticmethod
    def compare_fork_types():
        """Compare soft and hard forks"""
        print("\n" + "=" * 60)
        print(" FORK TYPE COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Backwards Compatibility", "Node Upgrade Required", "Chain Split", "Example", "Risk Level"],
            "Soft Fork": ["Yes", "No (optional)", "No", "SegWit", "Low"],
            "Hard Fork": ["No", "Yes (mandatory)", "Yes", "Bitcoin Cash", "High"]
        }
        
        print(f"\n {'Attribute':30} | {'Soft Fork':20} | {'Hard Fork':20}")
        print("-" * 75)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            soft = comparison["Soft Fork"][i]
            hard = comparison["Hard Fork"][i]
            print(f" {attr:30} | {soft:20} | {hard:20}")
    
    @staticmethod
    def analyze_fork_consequences():
        """Examine the consequences of different fork types"""
        print("\n" + "=" * 60)
        print(" FORK CONSEQUENCES ANALYSIS")
        print("=" * 60)
        
        consequences = {
            "Soft Forks": {
                "positive": ["Gradual upgrades", "Maintains network unity", "No forced upgrades"],
                "negative": ["Can be controversial", "May be limiting", "Temporary confusion"]
            },
            "Hard Forks": {
                "positive": ["Major improvements", "Clean break with old rules", "Freedom to innovate"],
                "negative": ["Network split", "Community division", "Resource duplication"]
            },
            "Accidental Forks": {
                "positive": ["Resolved automatically", "Self-healing", "Shows decentralization"],
                "negative": ["Temporary uncertainty", "Short-term confusion", "Potential for reorgs"]
            }
        }
        
        print("\n 📊 Fork Impact Assessment:")
        for fork_type, impacts in consequences.items():
            print(f"\n  {fork_type.upper()}:")
            print(f"    ✅ Positives: {', '.join(impacts['positive'])}")
            print(f"    ❌ Negatives: {', '.join(impacts['negative'])}")

class ForkSimulationEngine:
    """Execute fork simulations with various scenarios"""
    
    @staticmethod
    def run_comprehensive_simulation():
        """Run complete fork simulation with multiple scenarios"""
        print("=" * 60)
        print(" CHAIN DIVERGENCE SIMULATION")
        print("=" * 60)
        
        # Create initial ledger
        print("\n 📝 Creating Initial Ledger...")
        main_ledger = DistributedLedgerWithForks("MainLedger")
        
        # Add some initial blocks
        print("\n 📦 Adding initial blocks...")
        main_ledger.append_block("Transaction: Alice → Bob (10 units)", version=1)
        main_ledger.append_block("Transaction: Bob → Charlie (5 units)", version=1)
        main_ledger.append_block("Transaction: Charlie → Diana (3 units)", version=1)
        main_ledger.render_chain()
        
        # Soft fork simulation
        print("\n" + "-" * 60)
        main_ledger.initiate_soft_fork("Soft Fork: Transaction Speed Enhancement", version=2)
        main_ledger.render_chain()
        
        # Hard fork simulation
        print("\n" + "-" * 60)
        forked_ledger = main_ledger.initiate_hard_fork("Hard Fork: Block Size Increase to 8MB", version=3)
        
        print("\n 📊 Final State:")
        main_ledger.render_chain()
        forked_ledger.render_chain()
        
        # Accidental fork simulation
        print("\n" + "-" * 60)
        main_ledger.simulate_accidental_fork("Node_Alpha", "Alternative block data from Node_Alpha")
        
        # Analysis
        ForkAnalyzer.compare_fork_types()
        ForkAnalyzer.analyze_fork_consequences()
        
        print("\n" + "=" * 60)
        print(" FORK CHARACTERISTICS:")
        print("   ✓ Soft Fork: Backwards compatible, gradual upgrade")
        print("   ✓ Hard Fork: Not backwards compatible, chain split")
        print("   ✓ Accidental Fork: Temporary, resolved by consensus")
        print("   ✓ Forks allow protocol evolution and innovation")
        print("   ✓ Forks require community coordination")
        print("=" * 60 + "\n")

def demonstrate_fork_system():
    """Execute fork demonstration with examples"""
    print("=" * 60)
    print(" CHAIN DIVERGENCE DEMONSTRATION")
    print("=" * 60)
    
    # Create blockchain
    print("\n 📝 Creating blockchain...")
    chain = DistributedLedgerWithForks("DemoChain")
    chain.append_block("Transaction: Alice → Bob 10 BTC", version=1)
    chain.append_block("Transaction: Bob → Charlie 5 BTC", version=1)
    
    # Show initial chain
    print("\n 📊 Initial Chain:")
    chain.render_chain()
    
    # Demonstrate soft fork
    print("\n" + "-" * 60)
    print(" Soft Fork Example:")
    chain.initiate_soft_fork("SegWit Upgrade (Soft Fork)", version=2)
    chain.render_chain()
    
    # Demonstrate hard fork
    print("\n" + "-" * 60)
    print(" Hard Fork Example:")
    hard_fork = chain.initiate_hard_fork("Bitcoin Cash Style Fork (Hard Fork)", version=3)
    
    print("\n 📊 Both Chains:")
    chain.render_chain()
    hard_fork.render_chain()
    
    # Show fork history
    print("\n" + "=" * 60)
    print(" FORK HISTORY")
    print("=" * 60)
    for i, fork in enumerate(chain.fork_history, 1):
        print(f"\n {i}. Type: {fork['type']}")
        print(f"    Height: {fork['height']}")
        print(f"    Description: {fork['description']}")
        if 'node' in fork:
            print(f"    Node: {fork['node']}")
        if 'forked_ledger' in fork:
            print(f"    New Ledger: {fork['forked_ledger']}")
    
    # Analysis
    ForkAnalyzer.compare_fork_types()
    ForkAnalyzer.analyze_fork_consequences()
    
    print("\n" + "=" * 60)
    print(" FORK CHARACTERISTICS:")
    print("   ✓ Soft Fork: Backwards compatible upgrade")
    print("   ✓ Hard Fork: Non-backwards compatible, chain split")
    print("   ✓ Accidental Fork: Temporary divergence")
    print("   ✓ Forks enable protocol evolution and innovation")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_fork_system()

2.20 Mainnet, Testnet, Devnet

What are the Different Networks?

Blockchains typically have multiple networks for different purposes: production (mainnet), testing (testnet), and development (devnet).

Mainnet:

The main network where real transactions occur. This is the production blockchain with real value.

Characteristics:

  • Real tokens with value
  • Full security
  • Public access
  • Main development focus

Use Cases: Production applications, real transactions, live dApps

Testnet:

A testing environment that simulates the mainnet but uses test tokens with no real value. This allows developers to test applications safely.

Characteristics:

  • Test tokens (no value)
  • Same security as mainnet
  • Public access
  • Similar to mainnet

Use Cases: Testing applications, practicing transactions, development

Devnet:

A development network for testing new features and protocols. Often more flexible and less secure than testnet.

Characteristics:

  • Development tokens
  • Less security
  • Restricted access
  • More flexible

Use Cases: Early development, feature testing, internal testing

Code Example – Networks:

"""
DEPLOYMENT ENVIRONMENT HIERARCHY
================================
Comprehensive simulation of blockchain network environments: Mainnet, Testnet, and Devnet
"""

import time
import hashlib
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class EnvironmentType(Enum):
    """Classification of blockchain environments"""
    PRODUCTION = "Production (Mainnet)"
    STAGING = "Staging (Testnet)"
    DEVELOPMENT = "Development (Devnet)"
    LOCAL = "Local Network"

@dataclass
class NetworkBlock:
    """Represents a block in a network"""
    height: int
    transactions: List[Dict]
    timestamp: float = field(default_factory=time.time)
    block_hash: str = ""
    
    def __post_init__(self):
        if not self.block_hash:
            self.block_hash = hashlib.sha256(
                f"{self.height}{len(self.transactions)}{self.timestamp}".encode()
            ).hexdigest()[:16]

class BlockchainEnvironment:
    """Represents a blockchain network environment"""
    
    def __init__(self, 
                 environment_name: str, 
                 token_valuation: float = 0.0,
                 security_posture: str = "High",
                 accessibility: str = "Public",
                 environment_type: EnvironmentType = EnvironmentType.DEVELOPMENT):
        self.environment_name = environment_name
        self.token_value = token_valuation
        self.security_level = security_posture
        self.access_level = accessibility
        self.environment_type = environment_type
        self.block_chain: List[NetworkBlock] = []
        self.pending_transactions: List[Dict] = []
        self.is_active = token_valuation > 0
        self.genesis_time = time.time()
        
        if self.is_active:
            print(f" 🚀 {environment_name} is ACTIVE! (Token Value: ${token_valuation:.2f})")
        else:
            print(f" 🧪 {environment_name} is a TEST environment (Token Value: ${token_valuation:.2f})")
    
    def submit_transaction(self, sender: str, recipient: str, amount: float) -> None:
        """Add a transaction to the pending pool"""
        transaction = {
            "from": sender,
            "to": recipient,
            "amount": amount,
            "timestamp": time.time(),
            "hash": hashlib.sha256(f"{sender}{recipient}{amount}{time.time()}".encode()).hexdigest()[:16]
        }
        self.pending_transactions.append(transaction)
        print(f" 📝 Transaction: {sender[:8]}... → {recipient[:8]}... ({amount:.2f} tokens)")
    
    def mine_pending_block(self) -> Optional[NetworkBlock]:
        """Process pending transactions into a block"""
        if not self.pending_transactions:
            print(" ⚠️  No pending transactions to mine")
            return None
        
        new_block = NetworkBlock(
            height=len(self.block_chain),
            transactions=self.pending_transactions.copy()
        )
        self.block_chain.append(new_block)
        self.pending_transactions = []
        print(f" ⛏️  Block {new_block.height} mined! ({len(new_block.transactions)} transactions)")
        return new_block
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Gather environment metrics"""
        return {
            "environment": self.environment_name,
            "type": self.environment_type.value,
            "active": "✅ Yes" if self.is_active else "❌ No",
            "token_value": f"${self.token_value:.2f}",
            "security": self.security_level,
            "access": self.access_level,
            "blocks": len(self.block_chain),
            "pending_transactions": len(self.pending_transactions),
            "total_transactions": sum(len(block.transactions) for block in self.block_chain),
            "uptime": time.time() - self.genesis_time
        }
    
    def render_status(self) -> None:
        """Display environment information"""
        stats = self.compile_statistics()
        print("\n" + "=" * 60)
        print(f" 🌐 {stats['environment']} ({stats['type']})")
        print("=" * 60)
        print(f"  Status: {stats['active']}")
        print(f"  Token Value: {stats['token_value']}")
        print(f"  Security Posture: {stats['security']}")
        print(f"  Access Control: {stats['access']}")
        print(f"  Block Height: {stats['blocks']}")
        print(f"  Pending Operations: {stats['pending_transactions']}")
        print(f"  Total Operations: {stats['total_transactions']}")
        print(f"  Uptime: {stats['uptime']:.0f}s")

class EnvironmentManager:
    """Manages multiple blockchain environments"""
    
    def __init__(self):
        self.environments: Dict[str, BlockchainEnvironment] = {}
        self.active_environment: Optional[str] = None
        print(" 🏗️  Environment Manager initialized")
    
    def create_environment(self, 
                          name: str,
                          token_value: float = 0.0,
                          security: str = "High",
                          access: str = "Public",
                          env_type: EnvironmentType = EnvironmentType.DEVELOPMENT) -> BlockchainEnvironment:
        """Create a new blockchain environment"""
        if name in self.environments:
            print(f" ⚠️  Environment '{name}' already exists")
            return self.environments[name]
        
        environment = BlockchainEnvironment(name, token_value, security, access, env_type)
        self.environments[name] = environment
        return environment
    
    def switch_environment(self, name: str) -> None:
        """Change active environment"""
        if name in self.environments:
            self.active_environment = name
            print(f" 🔄 Switched to environment: {name}")
        else:
            print(f" ❌ Environment '{name}' not found")
    
    def get_active_environment(self) -> Optional[BlockchainEnvironment]:
        """Retrieve the current active environment"""
        if self.active_environment:
            return self.environments.get(self.active_environment)
        return None
    
    def display_all_environments(self) -> None:
        """Show all registered environments"""
        print("\n" + "=" * 60)
        print(" 📊 DEPLOYMENT ENVIRONMENTS")
        print("=" * 60)
        
        for name, env in self.environments.items():
            stats = env.compile_statistics()
            active_marker = "▶ " if name == self.active_environment else "  "
            print(f"\n {active_marker}{name}:")
            print(f"    Type: {stats['type']}")
            print(f"    Active: {stats['active']}")
            print(f"    Token Value: {stats['token_value']}")
            print(f"    Blocks: {stats['blocks']}")

class EnvironmentAnalytics:
    """Analysis tools for blockchain environments"""
    
    @staticmethod
    def compare_environments():
        """Compare different environment types"""
        print("\n" + "=" * 60)
        print(" ENVIRONMENT COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Token Value", "Security", "Access", "Purpose", "Data Persistence"],
            "Mainnet": ["Real Value", "Very High", "Public", "Production", "Permanent"],
            "Testnet": ["Test Value", "High", "Public", "Testing", "Resettable"],
            "Devnet": ["Dev Value", "Low", "Restricted", "Development", "Ephemeral"],
            "Local": ["None", "Very Low", "Private", "Experimentation", "Temporary"]
        }
        
        print(f"\n {'Attribute':25} | {'Mainnet':15} | {'Testnet':15} | {'Devnet':15} | {'Local':15}")
        print("-" * 90)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            main = comparison["Mainnet"][i]
            test = comparison["Testnet"][i]
            dev = comparison["Devnet"][i]
            local = comparison["Local"][i]
            print(f" {attr:25} | {main:15} | {test:15} | {dev:15} | {local:15}")
    
    @staticmethod
    def analyze_environment_use_cases():
        """Examine appropriate use cases for each environment"""
        print("\n" + "=" * 60)
        print(" ENVIRONMENT USE CASE ANALYSIS")
        print("=" * 60)
        
        use_cases = {
            "Mainnet": {
                "suitable": ["Production Applications", "Real Transactions", "DApp Deployment"],
                "caution": ["High Risk", "Gas Costs", "Irreversible"]
            },
            "Testnet": {
                "suitable": ["Smart Contract Testing", "Integration Testing", "User Acceptance"],
                "caution": ["Faucet Dependency", "Reset Periods", "Limited Features"]
            },
            "Devnet": {
                "suitable": ["Feature Development", "Unit Testing", "Rapid Prototyping"],
                "caution": ["Not Production Ready", "Limited Networks", "No Incentives"]
            },
            "Local": {
                "suitable": ["Experimentation", "Education", "Internal Testing"],
                "caution": ["No Consensus", "No Public Access", "Fake Tokens"]
            }
        }
        
        print("\n 📊 Environment Suitability:")
        for env, details in use_cases.items():
            print(f"\n  {env.upper()}:")
            print(f"    ✅ Suitable for: {', '.join(details['suitable'])}")
            print(f"    ⚠️  Caution: {', '.join(details['caution'])}")

def demonstrate_environment_system():
    """Execute comprehensive environment demonstration"""
    print("=" * 60)
    print(" DEPLOYMENT ENVIRONMENT DEMONSTRATION")
    print("=" * 60)
    
    # Create environment manager
    manager = EnvironmentManager()
    
    # Create different environments
    print("\n 🏗️  Creating environments...")
    mainnet = manager.create_environment(
        "Ethereum Mainnet",
        token_value=2000.00,
        security="Very High",
        access="Public",
        env_type=EnvironmentType.PRODUCTION
    )
    
    testnet = manager.create_environment(
        "Ethereum Goerli",
        token_value=0.00,
        security="High",
        access="Public",
        env_type=EnvironmentType.STAGING
    )
    
    devnet = manager.create_environment(
        "Development Devnet",
        token_value=0.00,
        security="Medium",
        access="Restricted",
        env_type=EnvironmentType.DEVELOPMENT
    )
    
    local = manager.create_environment(
        "Local Network",
        token_value=0.00,
        security="Low",
        access="Private",
        env_type=EnvironmentType.LOCAL
    )
    
    # Simulate activity in each environment
    print("\n 🔄 Simulating environment activity...")
    
    # Mainnet activity (real transactions)
    print("\n 📝 Mainnet Activity:")
    mainnet.submit_transaction("0x1234", "0x5678", 10.5)
    mainnet.submit_transaction("0x5678", "0x9abc", 5.2)
    mainnet.mine_pending_block()
    
    # Testnet activity (test tokens)
    print("\n 📝 Testnet Activity:")
    testnet.submit_transaction("0xabcd", "0xefgh", 100)
    testnet.submit_transaction("0xefgh", "0xijkl", 50)
    testnet.mine_pending_block()
    
    # Devnet activity (development)
    print("\n 📝 Devnet Activity:")
    devnet.submit_transaction("0x0001", "0x0002", 1000)
    devnet.submit_transaction("0x0002", "0x0003", 500)
    devnet.mine_pending_block()
    
    # Local activity
    print("\n 📝 Local Activity:")
    local.submit_transaction("0x001a", "0x002b", 100)
    local.mine_pending_block()
    
    # Display all environments
    manager.display_all_environments()
    
    # Individual environment status
    print("\n 📊 Individual Environment Status:")
    for env in [mainnet, testnet, devnet, local]:
        env.render_status()
    
    # Analysis
    EnvironmentAnalytics.compare_environments()
    EnvironmentAnalytics.analyze_environment_use_cases()
    
    print("\n" + "=" * 60)
    print(" ENVIRONMENT CHARACTERISTICS:")
    print("   ✓ Mainnet: Production, Real Value, Permanent")
    print("   ✓ Testnet: Testing, Test Value, Resettable")
    print("   ✓ Devnet: Development, Dev Value, Ephemeral")
    print("   ✓ Local: Private, No Value, Temporary")
    print("   ✓ Environments enable safe testing and development")
    print("   ✓ Choose environment based on development stage")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_environment_system()

2.21 Sidechains

What is a Sidechain?

A sidechain is an independent blockchain linked to a main blockchain, or parent chain, allowing assets and data to move between the two networks. Sidechains can have different features and consensus mechanisms while leveraging the security of the main chain.

How Sidechains Work:

Two-Way Peg:

  1. Assets are locked on the main chain before they can be transferred or represented on the sidechain.
  2. Equivalent assets are unlocked on the sidechain
  3. Assets can be transferred back to the main chain

Sidechain Features:

FeatureDescription
Independent ConsensusCan use different consensus mechanisms
Custom FeaturesCan have specialized functionality
ScalabilityOffloads transactions from main chain
Asset TransferTwo-way peg for assets

Examples:

SidechainMain ChainPurpose
LiquidBitcoinFaster transactions, confidential transactions
PolygonEthereumScaling, lower fees
xDaiEthereumStablecoin payments

Code Example – Sidechains:

"""
PARALLEL CHAIN INTERCONNECTION FRAMEWORK
=========================================
Comprehensive implementation of sidechain architecture with two-way pegging
"""

import hashlib
import time
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

class ChainType(Enum):
    """Classification of chain types"""
    MAIN_CHAIN = "Main Chain"
    SIDECHAIN = "Sidechain"
    CHILD_CHAIN = "Child Chain"

@dataclass
class BlockRecord:
    """Represents a block in any chain"""
    height: int
    block_hash: str
    timestamp: float = field(default_factory=time.time)
    transaction_count: int = 0

class BaseLedger:
    """Foundation class for all chain implementations"""
    
    def __init__(self, identifier: str):
        self.identifier = identifier
        self.chain_blocks: List[BlockRecord] = []
        self.account_balances: Dict[str, float] = {}
        self.pending_operations: List[Dict] = []
        self.chain_type = ChainType.MAIN_CHAIN
        self.genesis_timestamp = time.time()
        self._create_genesis_block()
    
    def _create_genesis_block(self) -> None:
        """Establish the initial block"""
        genesis_hash = hashlib.sha256(f"genesis_{self.identifier}".encode()).hexdigest()[:16]
        self.chain_blocks.append(BlockRecord(height=0, block_hash=genesis_hash))
    
    def append_block(self) -> BlockRecord:
        """Create and append a new block"""
        new_block = BlockRecord(
            height=len(self.chain_blocks),
            block_hash=hashlib.sha256(f"{len(self.chain_blocks)}{time.time()}".encode()).hexdigest()[:16],
            transaction_count=len(self.pending_operations)
        )
        self.chain_blocks.append(new_block)
        self.pending_operations = []
        return new_block
    
    def query_balance(self, account: str) -> float:
        """Retrieve account balance"""
        return self.account_balances.get(account, 0.0)
    
    def execute_transfer(self, sender: str, recipient: str, amount: float) -> bool:
        """Perform a value transfer between accounts"""
        if self.query_balance(sender) < amount:
            return False
        
        self.account_balances[sender] = self.query_balance(sender) - amount
        self.account_balances[recipient] = self.query_balance(recipient) + amount
        return True
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Gather ledger metrics"""
        return {
            "identifier": self.identifier,
            "chain_type": self.chain_type.value,
            "block_height": len(self.chain_blocks),
            "total_balances": len(self.account_balances),
            "pending_operations": len(self.pending_operations),
            "genesis_elapsed": time.time() - self.genesis_timestamp
        }

class InterconnectedSidechain(BaseLedger):
    """Sidechain implementation with two-way pegging to parent chain"""
    
    def __init__(self, identifier: str, parent_chain: BaseLedger):
        super().__init__(identifier)
        self.chain_type = ChainType.SIDECHAIN
        self.parent_chain = parent_chain
        self.pegged_holdings: Dict[str, float] = {}
        self.peg_wallet = f"PEG_WALLET_{identifier}"
        self.total_pegged_in = 0.0
        self.total_pegged_out = 0.0
        print(f" 🔗 Sidechain '{identifier}' attached to '{parent_chain.identifier}'")
    
    def perform_peg_in(self, user_address: str, amount: float) -> bool:
        """Move assets from main chain to sidechain"""
        print(f"\n 📥 Pegging IN: {amount:.2f} from {user_address} to {self.identifier}")
        
        # Lock assets on parent chain
        if self.parent_chain.execute_transfer(user_address, self.peg_wallet, amount):
            # Release assets on sidechain
            self.account_balances[user_address] = self.query_balance(user_address) + amount
            self.pegged_holdings[user_address] = self.pegged_holdings.get(user_address, 0) + amount
            self.total_pegged_in += amount
            
            print(f"   ✅ Locked {amount:.2f} on {self.parent_chain.identifier}")
            print(f"   ✅ Released {amount:.2f} on {self.identifier}")
            return True
        
        print(f"   ❌ Peg-in failed: Insufficient balance")
        return False
    
    def perform_peg_out(self, user_address: str, amount: float) -> bool:
        """Move assets from sidechain back to main chain"""
        print(f"\n 📤 Pegging OUT: {amount:.2f} from {self.identifier} to {user_address}")
        
        # Lock assets on sidechain
        if self.query_balance(user_address) >= amount:
            self.account_balances[user_address] = self.query_balance(user_address) - amount
            self.pegged_holdings[user_address] = self.pegged_holdings.get(user_address, 0) - amount
            self.total_pegged_out += amount
            
            # Release assets on parent chain
            self.parent_chain.account_balances[user_address] = \
                self.parent_chain.query_balance(user_address) + amount
            
            print(f"   ✅ Locked {amount:.2f} on {self.identifier}")
            print(f"   ✅ Released {amount:.2f} on {self.parent_chain.identifier}")
            return True
        
        print(f"   ❌ Peg-out failed: Insufficient balance")
        return False
    
    def compile_statistics(self) -> Dict[str, Any]:
        """Extend statistics with sidechain-specific metrics"""
        stats = super().compile_statistics()
        stats.update({
            "pegged_in": self.total_pegged_in,
            "pegged_out": self.total_pegged_out,
            "net_pegged": self.total_pegged_in - self.total_pegged_out,
            "pegged_accounts": len(self.pegged_holdings)
        })
        return stats

class SidechainManager:
    """Manages multiple sidechains connected to a main chain"""
    
    def __init__(self, main_chain: BaseLedger):
        self.main_chain = main_chain
        self.sidechain_registry: Dict[str, InterconnectedSidechain] = {}
        print(f" 🏗️  Sidechain Manager initialized for '{main_chain.identifier}'")
    
    def create_sidechain(self, name: str) -> InterconnectedSidechain:
        """Create a new sidechain attached to the main chain"""
        if name in self.sidechain_registry:
            print(f" ⚠️  Sidechain '{name}' already exists")
            return self.sidechain_registry[name]
        
        sidechain = InterconnectedSidechain(name, self.main_chain)
        self.sidechain_registry[name] = sidechain
        return sidechain
    
    def display_all_chains(self) -> None:
        """Show all chains and their status"""
        print("\n" + "=" * 60)
        print(" 📊 CHAIN ECOLOGY")
        print("=" * 60)
        
        # Main chain
        main_stats = self.main_chain.compile_statistics()
        print(f"\n 🌐 {main_stats['identifier']} ({main_stats['chain_type']}):")
        print(f"   Block Height: {main_stats['block_height']}")
        print(f"   Account Count: {main_stats['total_balances']}")
        print(f"   Pending Operations: {main_stats['pending_operations']}")
        
        # Sidechains
        for name, sidechain in self.sidechain_registry.items():
            stats = sidechain.compile_statistics()
            print(f"\n 🔗 {stats['identifier']} ({stats['chain_type']}):")
            print(f"   Block Height: {stats['block_height']}")
            print(f"   Account Count: {stats['total_balances']}")
            print(f"   Pegged In: {stats['pegged_in']:.2f}")
            print(f"   Pegged Out: {stats['pegged_out']:.2f}")
            print(f"   Net Pegged: {stats['net_pegged']:.2f}")

class SidechainAnalytics:
    """Analysis tools for sidechain architecture"""
    
    @staticmethod
    def compare_chain_types():
        """Compare main chain vs sidechain characteristics"""
        print("\n" + "=" * 60)
        print(" CHAIN TYPE COMPARISON")
        print("=" * 60)
        
        comparison = {
            "Attribute": ["Security", "Scalability", "Consensus", "Features", "Interoperability"],
            "Main Chain": ["Very High", "Limited", "Base Protocol", "Core Features", "Limited"],
            "Sidechain": ["Medium", "High", "Customizable", "Specialized", "Two-Way Peg"]
        }
        
        print(f"\n {'Attribute':25} | {'Main Chain':20} | {'Sidechain':20}")
        print("-" * 70)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            main = comparison["Main Chain"][i]
            side = comparison["Sidechain"][i]
            print(f" {attr:25} | {main:20} | {side:20}")
    
    @staticmethod
    def analyze_pegging_mechanisms():
        """Examine different pegging approaches"""
        print("\n" + "=" * 60)
        print(" PEGGING MECHANISM ANALYSIS")
        print("=" * 60)
        
        mechanisms = {
            "Two-Way Peg": {
                "description": "Assets move both directions",
                "security": "Trusted or decentralized",
                "speed": "Medium",
                "example": "Liquid Network"
            },
            "Symmetric Peg": {
                "description": "Equal value maintained",
                "security": "Over-collateralized",
                "speed": "Fast",
                "example": "wBTC, renBTC"
            },
            "Asymmetric Peg": {
                "description": "One-way movement",
                "security": "Burning mechanism",
                "speed": "Slow",
                "example": "Token bridges"
            }
        }
        
        print("\n 📊 Pegging Approaches:")
        for mechanism, details in mechanisms.items():
            print(f"\n  {mechanism}:")
            print(f"    Description: {details['description']}")
            print(f"    Security: {details['security']}")
            print(f"    Speed: {details['speed']}")
            print(f"    Example: {details['example']}")

def demonstrate_sidechain_system():
    """Execute comprehensive sidechain demonstration"""
    print("=" * 60)
    print(" PARALLEL CHAIN INTERCONNECTION DEMONSTRATION")
    print("=" * 60)
    
    # Create main chain
    print("\n 🏗️  Creating main chain...")
    main_chain = BaseLedger("Bitcoin Mainnet")
    main_chain.account_balances["Alice"] = 100.0
    main_chain.account_balances["Bob"] = 50.0
    
    # Show initial balances
    print("\n 📊 Initial Main Chain Balances:")
    print(f"   Alice: {main_chain.query_balance('Alice'):.2f} units")
    print(f"   Bob: {main_chain.query_balance('Bob'):.2f} units")
    
    # Create sidechain manager
    manager = SidechainManager(main_chain)
    
    # Create sidechain
    print("\n 🔗 Creating sidechain...")
    liquid_sidechain = manager.create_sidechain("Liquid Sidechain")
    
    # Demonstrate pegging operations
    print("\n" + "=" * 60)
    print(" PEGGING OPERATIONS")
    print("=" * 60)
    
    # Peg in
    print("\n 📥 Peg-In Operation:")
    liquid_sidechain.perform_peg_in("Alice", 20.0)
    
    # Show balances after peg-in
    print("\n 📊 Balances After Peg-In:")
    print(f"   Main Chain - Alice: {main_chain.query_balance('Alice'):.2f}")
    print(f"   Sidechain - Alice: {liquid_sidechain.query_balance('Alice'):.2f}")
    
    # Transfer on sidechain
    print("\n 🔄 Transfer on Sidechain:")
    liquid_sidechain.execute_transfer("Alice", "Bob", 10.0)
    
    print("\n 📊 Balances After Transfer:")
    print(f"   Sidechain - Alice: {liquid_sidechain.query_balance('Alice'):.2f}")
    print(f"   Sidechain - Bob: {liquid_sidechain.query_balance('Bob'):.2f}")
    
    # Peg out
    print("\n 📤 Peg-Out Operation:")
    liquid_sidechain.perform_peg_out("Bob", 5.0)
    
    # Final balances
    print("\n 📊 Final Balances:")
    print(f"   Main Chain - Alice: {main_chain.query_balance('Alice'):.2f}")
    print(f"   Main Chain - Bob: {main_chain.query_balance('Bob'):.2f}")
    print(f"   Sidechain - Alice: {liquid_sidechain.query_balance('Alice'):.2f}")
    print(f"   Sidechain - Bob: {liquid_sidechain.query_balance('Bob'):.2f}")
    
    # Display all chains
    manager.display_all_chains()
    
    # Additional analysis
    SidechainAnalytics.compare_chain_types()
    SidechainAnalytics.analyze_pegging_mechanisms()
    
    print("\n" + "=" * 60)
    print(" SIDECHAIN CHARACTERISTICS:")
    print("   ✓ Two-Way Peg: Assets can move both directions")
    print("   ✓ Independent Consensus: Separate security model")
    print("   ✓ Custom Features: Specialized functionality")
    print("   ✓ Scalability Enhancement: Reduces main chain load")
    print("   ✓ Security Trade-off: Depends on sidechain implementation")
    print("   ✓ Interoperability: Bridges between different chains")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_sidechain_system()

2.22 Blockchain Types

Types of Blockchains:

Blockchains can be categorized by who can access and participate in the network.

1. Public Blockchain (Permissionless):

Anyone can join and participate. No central authority. Fully decentralized and transparent.

Characteristics:

  • Open to everyone
  • Fully decentralized
  • Transparent
  • Censorship-resistant
  • Trustless

Examples: Bitcoin, Ethereum, Solana

Advantages:

  • No single point of failure
  • Censorship-resistant
  • Transparent

Disadvantages:

  • Slow
  • Scalability issues
  • Energy intensive (PoW)

2. Private Blockchain (Permissioned):

Restricted access controlled by a central authority. Only authorized participants can join.

Characteristics:

  • Restricted access
  • Controlled by central authority
  • Faster than public chains
  • More private

Examples: Hyperledger Fabric, R3 Corda

Advantages:

  • Faster (fewer nodes)
  • More efficient
  • Privacy

Disadvantages:

  • Centralized
  • Trust required
  • Less transparent

3. Consortium Blockchain:

Controlled by a group of organizations. Semi-decentralized. Balance between public and private.

Characteristics:

  • Multiple organizations share control
  • Semi-decentralized
  • Faster than public
  • More private than public

Examples: IBM Food Trust, R3 (banking)

Advantages:

  • Balanced control
  • Efficiency
  • Privacy

Disadvantages:

  • Trust required among members
  • Less transparent than public

4. Hybrid Blockchain:

Combines features of public and private blockchains.Some blockchain data is publicly available, while other information is kept private and accessible only to authorized participants.

Characteristics:

  • Mixed access
  • Selective transparency
  • Flexible control

Examples: IBM Blockchain Platform

Code Example – Blockchain Types:

"""
DISTRIBUTED LEDGER CLASSIFICATION FRAMEWORK
===========================================
Comprehensive implementation of different blockchain types and their characteristics
"""

from typing import List, Dict, Optional
from dataclasses import dataclass, field
from enum import Enum

class LedgerCategory(Enum):
    """Classification of blockchain types"""
    PUBLIC = "Public (Permissionless)"
    PRIVATE = "Private (Permissioned)"
    CONSORTIUM = "Consortium"
    HYBRID = "Hybrid"

@dataclass
class LedgerCharacteristics:
    """Represents the defining features of a blockchain type"""
    access_model: str
    governance_model: str
    throughput_speed: str
    visibility_level: str
    consensus_mechanism: str
    token_requirement: bool = False

class DistributedLedgerType:
    """Represents a specific type of blockchain with its properties"""
    
    def __init__(self, 
                 category_name: str,
                 characteristics: LedgerCharacteristics,
                 category: LedgerCategory):
        self.category_name = category_name
        self.characteristics = characteristics
        self.category = category
        self.implementations: List[str] = []
        self.use_cases: List[str] = []
        
    def register_implementation(self, implementation_name: str) -> None:
        """Add a real-world implementation example"""
        if implementation_name not in self.implementations:
            self.implementations.append(implementation_name)
    
    def register_use_case(self, use_case: str) -> None:
        """Add a typical use case"""
        if use_case not in self.use_cases:
            self.use_cases.append(use_case)
    
    def render_details(self) -> None:
        """Display comprehensive ledger type information"""
        print("\n" + "=" * 60)
        print(f" 📊 {self.category_name}")
        print("=" * 60)
        print(f"  Access Model: {self.characteristics.access_model}")
        print(f"  Governance: {self.characteristics.governance_model}")
        print(f"  Throughput: {self.characteristics.throughput_speed}")
        print(f"  Visibility: {self.characteristics.visibility_level}")
        print(f"  Consensus: {self.characteristics.consensus_mechanism}")
        print(f"  Token Required: {'✅ Yes' if self.characteristics.token_requirement else '❌ No'}")
        
        if self.implementations:
            print(f"  Implementations: {', '.join(self.implementations)}")
        if self.use_cases:
            print(f"  Use Cases: {', '.join(self.use_cases)}")

class LedgerClassificationSystem:
    """Manages and categorizes different blockchain types"""
    
    def __init__(self):
        self.ledger_types: Dict[str, DistributedLedgerType] = {}
        self._initialize_categories()
    
    def _initialize_categories(self) -> None:
        """Set up the standard blockchain categories"""
        
        # Public Ledger
        public_characteristics = LedgerCharacteristics(
            access_model="Anyone",
            governance_model="Decentralized",
            throughput_speed="Slow",
            visibility_level="High",
            consensus_mechanism="PoW/PoS",
            token_requirement=True
        )
        public_ledger = DistributedLedgerType(
            "Public (Permissionless)",
            public_characteristics,
            LedgerCategory.PUBLIC
        )
        public_ledger.register_implementation("Bitcoin")
        public_ledger.register_implementation("Ethereum")
        public_ledger.register_implementation("Solana")
        public_ledger.register_use_case("Cryptocurrency")
        public_ledger.register_use_case("Decentralized Finance")
        public_ledger.register_use_case("NFT Marketplaces")
        self.ledger_types["public"] = public_ledger
        
        # Private Ledger
        private_characteristics = LedgerCharacteristics(
            access_model="Restricted",
            governance_model="Centralized",
            throughput_speed="Fast",
            visibility_level="Low",
            consensus_mechanism="PBFT/Raft",
            token_requirement=False
        )
        private_ledger = DistributedLedgerType(
            "Private (Permissioned)",
            private_characteristics,
            LedgerCategory.PRIVATE
        )
        private_ledger.register_implementation("Hyperledger Fabric")
        private_ledger.register_implementation("R3 Corda")
        private_ledger.register_use_case("Enterprise Solutions")
        private_ledger.register_use_case("Supply Chain")
        private_ledger.register_use_case("Healthcare Records")
        self.ledger_types["private"] = private_ledger
        
        # Consortium Ledger
        consortium_characteristics = LedgerCharacteristics(
            access_model="Selected Organizations",
            governance_model="Shared",
            throughput_speed="Fast",
            visibility_level="Medium",
            consensus_mechanism="PBFT",
            token_requirement=False
        )
        consortium_ledger = DistributedLedgerType(
            "Consortium",
            consortium_characteristics,
            LedgerCategory.CONSORTIUM
        )
        consortium_ledger.register_implementation("IBM Food Trust")
        consortium_ledger.register_implementation("R3 (Banking)")
        consortium_ledger.register_use_case("Industry Collaboration")
        consortium_ledger.register_use_case("Trade Finance")
        consortium_ledger.register_use_case("Insurance")
        self.ledger_types["consortium"] = consortium_ledger
        
        # Hybrid Ledger
        hybrid_characteristics = LedgerCharacteristics(
            access_model="Mixed",
            governance_model="Mixed",
            throughput_speed="Medium",
            visibility_level="Mixed",
            consensus_mechanism="Variable",
            token_requirement=True
        )
        hybrid_ledger = DistributedLedgerType(
            "Hybrid",
            hybrid_characteristics,
            LedgerCategory.HYBRID
        )
        hybrid_ledger.register_implementation("IBM Blockchain Platform")
        hybrid_ledger.register_use_case("Government Services")
        hybrid_ledger.register_use_case("Digital Identity")
        hybrid_ledger.register_use_case("Cross-border Payments")
        self.ledger_types["hybrid"] = hybrid_ledger
    
    def get_ledger_type(self, category_key: str) -> Optional[DistributedLedgerType]:
        """Retrieve a specific ledger type by key"""
        return self.ledger_types.get(category_key.lower())
    
    def display_all_types(self) -> None:
        """Show all ledger categories"""
        print("\n" + "=" * 60)
        print(" 📚 DISTRIBUTED LEDGER CLASSIFICATION")
        print("=" * 60)
        
        for ledger_type in self.ledger_types.values():
            ledger_type.render_details()
    
    def display_comparison_matrix(self) -> None:
        """Show comparative analysis of all types"""
        print("\n" + "=" * 60)
        print(" COMPARATIVE ANALYSIS MATRIX")
        print("=" * 60)
        
        # Build comparison table
        comparison_data = {
            "Attribute": ["Access", "Governance", "Speed", "Visibility", "Consensus"],
            "Public": ["Anyone", "Decentralized", "Slow", "High", "PoW/PoS"],
            "Private": ["Restricted", "Centralized", "Fast", "Low", "PBFT/Raft"],
            "Consortium": ["Selected", "Shared", "Fast", "Medium", "PBFT"],
            "Hybrid": ["Mixed", "Mixed", "Medium", "Mixed", "Variable"]
        }
        
        print(f"\n {'Attribute':15} | {'Public':20} | {'Private':20} | {'Consortium':20} | {'Hybrid':20}")
        print("-" * 100)
        
        for i in range(len(comparison_data["Attribute"])):
            attr = comparison_data["Attribute"][i]
            public_val = comparison_data["Public"][i]
            private_val = comparison_data["Private"][i]
            consortium_val = comparison_data["Consortium"][i]
            hybrid_val = comparison_data["Hybrid"][i]
            print(f" {attr:15} | {public_val:20} | {private_val:20} | {consortium_val:20} | {hybrid_val:20}")

class LedgerSelectionAdvisor:
    """Provides guidance on selecting the appropriate blockchain type"""
    
    @staticmethod
    def recommend_by_requirements(access_needs: str = "public",
                                  governance_needs: str = "decentralized",
                                  speed_needs: str = "fast",
                                  transparency_needs: str = "high") -> str:
        """Recommend a blockchain type based on requirements"""
        
        recommendations = {
            "public": "Public Blockchain - Best for open, decentralized applications",
            "private": "Private Blockchain - Best for enterprise, controlled access",
            "consortium": "Consortium Blockchain - Best for industry collaboration",
            "hybrid": "Hybrid Blockchain - Best for flexible, mixed requirements"
        }
        
        if access_needs.lower() == "public" and governance_needs.lower() == "decentralized":
            return recommendations["public"]
        elif access_needs.lower() == "private" and governance_needs.lower() == "centralized":
            return recommendations["private"]
        elif access_needs.lower() == "selected" or "consortium" in governance_needs.lower():
            return recommendations["consortium"]
        else:
            return recommendations["hybrid"]
    
    @staticmethod
    def analyze_use_case_suitability():
        """Analyze which blockchain type fits different use cases"""
        print("\n" + "=" * 60)
        print(" USE CASE SUITABILITY ANALYSIS")
        print("=" * 60)
        
        use_cases = {
            "Cryptocurrency": {"Public": "⭐⭐⭐⭐⭐", "Private": "⭐", "Consortium": "⭐⭐", "Hybrid": "⭐⭐⭐"},
            "Enterprise Solutions": {"Public": "⭐⭐", "Private": "⭐⭐⭐⭐⭐", "Consortium": "⭐⭐⭐⭐", "Hybrid": "⭐⭐⭐⭐"},
            "Supply Chain": {"Public": "⭐⭐", "Private": "⭐⭐⭐", "Consortium": "⭐⭐⭐⭐⭐", "Hybrid": "⭐⭐⭐"},
            "Healthcare": {"Public": "⭐", "Private": "⭐⭐⭐⭐⭐", "Consortium": "⭐⭐⭐", "Hybrid": "⭐⭐⭐"},
            "Government Services": {"Public": "⭐⭐", "Private": "⭐⭐⭐", "Consortium": "⭐⭐⭐", "Hybrid": "⭐⭐⭐⭐⭐"}
        }
        
        print("\n 📊 Blockchain Type Suitability Matrix:")
        print(f" {'Use Case':20} | {'Public':10} | {'Private':10} | {'Consortium':10} | {'Hybrid':10}")
        print("-" * 65)
        
        for use_case, ratings in use_cases.items():
            print(f" {use_case:20} | {ratings['Public']:10} | {ratings['Private']:10} | "
                  f"{ratings['Consortium']:10} | {ratings['Hybrid']:10}")

def demonstrate_ledger_classification():
    """Execute comprehensive blockchain type demonstration"""
    print("=" * 60)
    print(" DISTRIBUTED LEDGER CLASSIFICATION DEMONSTRATION")
    print("=" * 60)
    
    # Create classification system
    system = LedgerClassificationSystem()
    
    # Display all types
    system.display_all_types()
    
    # Display comparison matrix
    system.display_comparison_matrix()
    
    # Use case analysis
    LedgerSelectionAdvisor.analyze_use_case_suitability()
    
    # Recommendation example
    print("\n" + "=" * 60)
    print(" SELECTION RECOMMENDATION")
    print("=" * 60)
    recommendation = LedgerSelectionAdvisor.recommend_by_requirements(
        access_needs="public",
        governance_needs="decentralized",
        speed_needs="slow",
        transparency_needs="high"
    )
    print(f"\n 💡 Recommended: {recommendation}")
    
    print("\n" + "=" * 60)
    print(" BLOCKCHAIN TYPE CHARACTERISTICS SUMMARY:")
    print("   ✓ Public: Open, decentralized, slow, transparent")
    print("   ✓ Private: Restricted, centralized, fast, limited visibility")
    print("   ✓ Consortium: Selected organizations, shared control, fast")
    print("   ✓ Hybrid: Mixed features, flexible, balanced")
    print("   ✓ Choose based on use case requirements")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_ledger_classification()

3. Cryptography

3.1 Cryptography Fundamentals

What is Cryptography?

Cryptography is the practice of using mathematical techniques to secure information and enable secure communication in the presence of potential attackers. In blockchain, cryptography is the foundation of security, privacy, and trust. It enables the creation of a trustless system where participants don’t need to trust each other—they trust the mathematics.

The Core Purpose of Cryptography:

Cryptography serves several critical functions in blockchain technology. First, it ensures confidentiality by encrypting data so that only authorized parties can read it. Second, it provides integrity by ensuring data hasn’t been altered. Third, it enables authentication by verifying the identity of participants. Fourth, it provides non-repudiation meaning participants cannot deny their actions.

Why Cryptography is the Foundation of Blockchain:

Without cryptography, blockchain would not be secure or trustless. Cryptography enables:

  • Secure Transactions: Only the owner of a private key can authorize transactions
  • Immutable Records: Cryptographic hashing makes tampering detectable
  • Identity: Public/private key pairs provide identity without revealing personal information
  • Consensus: Cryptographic proofs help participants reach agreement on the state of the blockchain without relying on a trusted third party.

Core Cryptographic Functions:

1. Hash Functions:

A hash function accepts input of any length and produces a fixed-length output known as a hash. The same input always produces the same output, but the output cannot be reversed to find the input. This makes hashes useful for verifying data integrity without revealing the data itself.

Example: SHA-256(“Hello”) always produces the same 64-character hex string. Changing even a single character in the input results in a completely different hash value.

2. Public Key Cryptography:

Also called asymmetric cryptography, this uses two mathematically related keys: a public key (shared openly) and a private key (kept secret). What is encrypted with one key can only be decrypted with the other. This enables secure communication without sharing secrets.

Example: Alice can use Bob’s public key to encrypt a message that only Bob’s private key can decrypt. Bob can sign a message with his private key that anyone can verify with his public key.

3. Digital Signatures:

A digital signature is a mathematical scheme that proves the authenticity of a message. Signing a message with a private key creates a signature that can be verified with the corresponding public key. This proves the message came from the signer and hasn’t been altered.

Example: When Alice sends a Bitcoin transaction, she signs it with her private key. Anyone can verify with her public key that she authorized the transaction.

4. Merkle Trees:

A Merkle tree is a hierarchical data structure in which each leaf node contains a data hash, while each parent node stores the hash of its child nodes. This allows efficient verification of data integrity—you can prove a specific piece of data is in the tree without downloading the entire tree.

Example: Bitcoin uses Merkle trees to verify transactions in a block. You can prove a transaction is in a block with just the transaction hash and a small Merkle proof.

Code Example – Cryptography Fundamentals:

"""
CRYPTOGRAPHIC FOUNDATIONS
=========================
Core cryptographic concepts with practical blockchain applications
"""

import hashlib
import base64
import random
import time
from typing import Dict, Tuple, Optional
from dataclasses import dataclass
from enum import Enum

class HashAlgorithm(Enum):
    """Supported hash algorithms"""
    SHA256 = "SHA-256"
    SHA512 = "SHA-512"
    MD5 = "MD5"

@dataclass
class HashResult:
    """Represents a hash operation result"""
    algorithm: str
    input_data: str
    output_hash: str
    hash_length: int
    bit_length: int

class CryptographicDemonstration:
    """Comprehensive cryptography demonstration suite"""
    
    def __init__(self):
        self.hash_cache = {}
        print("=" * 60)
        print(" CRYPTOGRAPHIC FOUNDATIONS")
        print("=" * 60)
    
    def demonstrate_hashing(self) -> None:
        """Show hash function properties and applications"""
        print("\n 🔐 HASH FUNCTIONS")
        print("-" * 40)
        
        # Basic hashing example
        input_message = "Hello, Distributed Ledger!"
        sha256_hash = hashlib.sha256(input_message.encode()).hexdigest()
        
        print(f"Original Input: {input_message}")
        print(f"SHA-256 Hash: {sha256_hash}")
        print(f"Hash Length: {len(sha256_hash)} hex characters")
        print(f"Hash Size: {len(sha256_hash) * 4} bits")
        
        print("\n 💡 Essential Hash Properties:")
        print("   ✓ Deterministic: Identical input → identical output")
        print("   ✓ One-Way: Cannot reverse to recover original data")
        print("   ✓ Fixed Output: Consistent length regardless of input")
        print("   ✓ Collision Resistant: Extremely difficult to find same output")
        
        # Avalanche effect demonstration
        print("\n 🌊 Avalanche Effect Demonstration:")
        phrase1 = "Blockchain"
        phrase2 = "Blockchains"  # Single character variation
        
        hash1 = hashlib.sha256(phrase1.encode()).hexdigest()
        hash2 = hashlib.sha256(phrase2.encode()).hexdigest()
        
        print(f"'{phrase1}' → {hash1[:16]}...")
        print(f"'{phrase2}' → {hash2[:16]}...")
        
        differing_chars = sum(a != b for a, b in zip(hash1, hash2))
        print(f"Character Changes: {differing_chars}/64 ({differing_chars/64*100:.1f}%)")
        print("   ✨ Minor input change → Major output difference (Avalanche Effect)")
    
    def demonstrate_encryption_analogy(self) -> None:
        """Show encryption concepts using Caesar cipher analogy"""
        print("\n 🔑 ENCRYPTION ANALOGY")
        print("-" * 40)
        
        def caesar_shift(text: str, shift: int) -> str:
            """Simple Caesar cipher implementation"""
            result = []
            for char in text:
                if char.isalpha():
                    base = ord('A') if char.isupper() else ord('a')
                    result.append(chr((ord(char) - base + shift) % 26 + base))
                else:
                    result.append(char)
            return ''.join(result)
        
        original_message = "Sensitive Data"
        encryption_shift = 7
        
        encrypted = caesar_shift(original_message, encryption_shift)
        decrypted = caesar_shift(encrypted, -encryption_shift)
        
        print(f"📝 Original: {original_message}")
        print(f"🔒 Encrypted: {encrypted}")
        print(f"🔓 Decrypted: {decrypted}")
        
        print("\n 💡 Encryption Fundamentals:")
        print("   • Transforms readable data into unreadable format")
        print("   • Requires cryptographic key to reverse the process")
        print("   • Protects data confidentiality during transmission")
        print("   • Modern encryption is mathematically complex and secure")
    
    def demonstrate_digital_signatures(self) -> None:
        """Show digital signature concepts"""
        print("\n ✍️  DIGITAL SIGNATURES")
        print("-" * 40)
        
        def create_signature(message: str, private_key: str) -> str:
            """Simulate digital signature creation"""
            combined = message + private_key
            return hashlib.sha256(combined.encode()).hexdigest()
        
        def verify_signature(message: str, signature: str, public_key: str) -> bool:
            """Simulate signature verification"""
            expected = hashlib.sha256((message + public_key).encode()).hexdigest()
            return signature == expected
        
        # Simulate key pair
        private_key = "secret_key_12345"
        public_key = "public_key_67890"
        
        # Create and verify signature
        transaction = "Transfer 50 units to Address 0xABC"
        signature = create_signature(transaction, private_key)
        
        print(f"📝 Transaction: {transaction}")
        print(f"✍️  Signature: {signature[:16]}...")
        print(f"✅ Verification: {verify_signature(transaction, signature, public_key)}")
        
        # Demonstrate tamper detection
        tampered_transaction = "Transfer 500 units to Address 0xABC"
        tampered_verification = verify_signature(tampered_transaction, signature, public_key)
        
        print(f"\n⚠️  Tampered Transaction: {tampered_transaction}")
        print(f"❌ Verification: {tampered_verification}")
        print("   🛡️  Signatures detect any message tampering!")
        
        print("\n 💡 Digital Signature Properties:")
        print("   • Proves message authenticity")
        print("   • Ensures message integrity")
        print("   • Provides non-repudiation")
        print("   • Cryptographically secure with public/private key pairs")
    
    def demonstrate_key_management(self) -> None:
        """Show key management concepts"""
        print("\n 🗝️  KEY MANAGEMENT")
        print("-" * 40)
        
        # Simulate wallet key generation
        def generate_key_pair() -> Tuple[str, str]:
            """Simulate key pair generation"""
            seed = str(random.randint(100000, 999999))
            private_key = hashlib.sha256(seed.encode()).hexdigest()
            public_key = hashlib.sha256(private_key.encode()).hexdigest()
            return private_key, public_key
        
        # Generate multiple key pairs
        print("👤 Generated Key Pairs:")
        for i in range(3):
            private, public = generate_key_pair()
            print(f"\n  Pair {i+1}:")
            print(f"    Private Key: {private[:16]}...")
            print(f"    Public Key:  {public[:16]}...")
        
        print("\n 💡 Key Management Concepts:")
        print("   • Private Key: Known only to owner (like password)")
        print("   • Public Key: Shared openly (like address)")
        print("   • Wallet Address: Derived from public key")
        print("   • Security: Private key must remain confidential")
    
    def demonstrate_cryptography_in_blockchain(self) -> None:
        """Explain cryptography applications in blockchain"""
        print("\n ⛓️  CRYPTOGRAPHY IN BLOCKCHAIN")
        print("-" * 40)
        
        applications = {
            "Hashing": {
                "purpose": "Block linking and data integrity",
                "uses": ["Block chaining", "Transaction IDs", "Merkle trees", "Proof of Work"]
            },
            "Digital Signatures": {
                "purpose": "Transaction authorization and identity verification",
                "uses": ["Transaction signing", "Authentication", "Non-repudiation", "Access control"]
            },
            "Public/Private Keys": {
                "purpose": "Secure identity and ownership",
                "uses": ["Wallet creation", "Identity management", "Encryption", "Secure communication"]
            },
            "Merkle Trees": {
                "purpose": "Efficient verification and structure",
                "uses": ["Transaction verification", "Light nodes", "Data integrity", "Efficient proofs"]
            }
        }
        
        print("\n 📊 Blockchain Cryptographic Applications:")
        print("=" * 60)
        for category, details in applications.items():
            print(f"\n  {category.upper()}:")
            print(f"    Purpose: {details['purpose']}")
            print(f"    Uses: {', '.join(details['uses'])}")
        
        print("\n" + "=" * 60)

class CryptographicAnalytics:
    """Additional cryptographic analysis tools"""
    
    @staticmethod
    def compare_hash_algorithms():
        """Compare different hash algorithms"""
        print("\n" + "=" * 60)
        print(" HASH ALGORITHM COMPARISON")
        print("=" * 60)
        
        test_data = "Blockchain Technology"
        
        algorithms = [
            ("SHA-256", hashlib.sha256),
            ("SHA-512", hashlib.sha512),
            ("MD5", hashlib.md5)
        ]
        
        print(f"\n Input: {test_data}")
        print("\n 📊 Algorithm Comparison:")
        print(f" {'Algorithm':10} | {'Output Length':15} | {'Hash Output'}")
        print("-" * 65)
        
        for name, algorithm in algorithms:
            hash_obj = algorithm(test_data.encode())
            output = hash_obj.hexdigest()
            print(f" {name:10} | {len(output):15} | {output[:20]}...")
    
    @staticmethod
    def analyze_hash_security():
        """Examine hash security properties"""
        print("\n" + "=" * 60)
        print(" HASH SECURITY ANALYSIS")
        print("=" * 60)
        
        security_properties = {
            "Pre-image Resistance": "Hard to find input from output",
            "Second Pre-image Resistance": "Hard to find different input with same output",
            "Collision Resistance": "Hard to find any two inputs with same output",
            "Avalanche Effect": "Small input change → large output change"
        }
        
        print("\n 🛡️  Security Properties:")
        for property_name, description in security_properties.items():
            print(f"  • {property_name}: {description}")

def demonstrate_cryptography_suite():
    """Execute comprehensive cryptography demonstration"""
    print("=" * 60)
    print(" CRYPTOGRAPHIC FOUNDATIONS SUITE")
    print("=" * 60)
    
    # Initialize demonstration
    demo = CryptographicDemonstration()
    
    # Run all demonstrations
    demo.demonstrate_hashing()
    demo.demonstrate_encryption_analogy()
    demo.demonstrate_digital_signatures()
    demo.demonstrate_key_management()
    demo.demonstrate_cryptography_in_blockchain()
    
    # Additional analytics
    CryptographicAnalytics.compare_hash_algorithms()
    CryptographicAnalytics.analyze_hash_security()
    
    print("\n" + "=" * 60)
    print(" CRYPTOGRAPHIC FOUNDATIONS SUMMARY:")
    print("   ✓ Hashing: Data integrity and linking")
    print("   ✓ Encryption: Data confidentiality")
    print("   ✓ Digital Signatures: Authentication and non-repudiation")
    print("   ✓ Key Management: Secure identity and ownership")
    print("   ✓ Cryptography is the foundation of blockchain security")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_cryptography_suite()

3.2 Hash Functions

What are Hash Functions?

Hash functions are one-way mathematical functions that convert input data of any size into a fixed-size output (hash). They are fundamental to blockchain security and data integrity. A hash function takes an input (called a message) and produces a fixed-size string of bytes. The output is typically a hexadecimal string, and the same input always produces the same output.

The Five Key Properties of Cryptographic Hash Functions:

1. Deterministic:

The same input always produces the same output. This property is essential for verification—you can recalculate the hash and compare it to the stored hash to verify data integrity. If the data has changed, the hash will be different.

Example: SHA-256(“Hello”) always produces the same hash regardless of when or where it’s computed.

2. Pre-image Resistance:

Given a hash, it’s computationally impossible to find the original input. This is also called “one-way” property. A cryptographic hash is one-way, meaning the original input cannot feasibly be recovered from the hash value. This is what makes hashing secure for password storage and blockchain linking.

Example: Given the hash 0xabc... you cannot determine that the original input was “Hello”.

3. Collision Resistance:

It’s extremely unlikely that two different inputs produce the same output. The probability of two different inputs producing the same hash is astronomically small (2^-128 for SHA-256). This ensures each piece of data has a unique fingerprint.

Example: No one has ever found two different files that produce the same SHA-256 hash.

4. Avalanche Effect:

A small change in the input (even a single bit) produces a completely different output. This makes the hash function sensitive to changes, so even tiny modifications are detectable.

Example: “Hello” and “Hello!” produce completely different hashes despite only one character difference.

5. Fast Computation:

Hash functions are efficient and can process data quickly. This is important for blockchain applications where hashes need to be computed millions of times.

Common Hash Functions in Blockchain:

FunctionOutput SizeUsed InCharacteristics
SHA-256256 bitsBitcoinDouble SHA-256 used for mining
Keccak-256256 bitsEthereumBased on SHA-3 competition
RIPEMD-160160 bitsBitcoinUsed for address generation
SHA-3256-512 bitsModernLatest NIST standard

Hash Functions in Action in Blockchain:

1. Block Linking:

Each block contains the hash of the previous block. If anyone modifies a previous block, its hash changes, breaking the chain. This is what makes blockchain immutable.

2. Transaction IDs:

Each transaction has a unique hash. This serves as the transaction identifier and allows efficient lookup.

3. Merkle Trees:

Merkle trees are built by repeatedly hashing pairs of transaction hashes until a single root hash remains. This allows efficient verification that a transaction is in a block.

4. Mining:

In Proof of Work, miners search for a nonce that makes the block hash meet a target (start with a certain number of zeros). This is the “work” in Proof of Work.

Code Example – Hash Functions:

"""
CRYPTOGRAPHIC DIGEST ENGINE
===========================
Comprehensive hash function implementation and property demonstration
"""

import hashlib
import time
from typing import List, Tuple, Dict, Any
from dataclasses import dataclass
from enum import Enum

class HashAlgorithm(Enum):
    """Supported cryptographic hash algorithms"""
    SHA256 = "SHA-256"
    SHA512 = "SHA-512"
    SHA1 = "SHA-1"
    MD5 = "MD5"
    SHA3_256 = "SHA-3 256"
    SHA3_512 = "SHA-3 512"

@dataclass
class HashPerformanceMetric:
    """Performance metrics for hash operations"""
    input_size: int
    execution_time: float
    operations_per_second: float

class CryptographicDigestDemonstration:
    """Comprehensive hash function demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOGRAPHIC DIGEST ENGINE")
        print("=" * 60)
    
    def demonstrate_core_properties(self) -> None:
        """Demonstrate the five essential properties of cryptographic hash functions"""
        print("\n 📊 CORE HASH PROPERTIES")
        print("-" * 40)
        
        # 1. Deterministic Property
        print("\n 🔄 DETERMINISTIC OUTPUT:")
        test_message = "Immutable Ledger Technology"
        hash_a = hashlib.sha256(test_message.encode()).hexdigest()
        hash_b = hashlib.sha256(test_message.encode()).hexdigest()
        
        print(f"  Input: {test_message}")
        print(f"  Hash 1: {hash_a[:24]}...")
        print(f"  Hash 2: {hash_b[:24]}...")
        print(f"  Identical Output: {hash_a == hash_b}")
        print("   ✓ Same input always produces identical output")
        
        # 2. One-Way Property
        print("\n 🚫 PRE-IMAGE RESISTANCE:")
        print("  Given cryptographic digest, cannot determine original input")
        print("  Example: SHA-256('secret') → ...")
        print("  Cannot reverse engineer 'secret' from the digest")
        print("   ✓ One-way transformation (mathematically irreversible)")
        
        # 3. Collision Resistance
        print("\n 🎯 COLLISION RESISTANCE:")
        msg1 = "Blockchain"
        msg2 = "Distributed"
        
        digest1 = hashlib.sha256(msg1.encode()).hexdigest()
        digest2 = hashlib.sha256(msg2.encode()).hexdigest()
        
        print(f"  '{msg1}' → {digest1[:16]}...")
        print(f"  '{msg2}' → {digest2[:16]}...")
        print(f"  Collision Detected: {digest1 == digest2}")
        print("   ✓ Extremely difficult to find two inputs producing same output")
        
        # 4. Avalanche Effect
        print("\n 🌊 AVALANCHE EFFECT:")
        original = "Cryptography"
        modified = "Cryptographi"  # Single character removed
        
        original_hash = hashlib.sha256(original.encode()).hexdigest()
        modified_hash = hashlib.sha256(modified.encode()).hexdigest()
        
        print(f"  Original: '{original}' → {original_hash[:16]}...")
        print(f"  Modified: '{modified}' → {modified_hash[:16]}...")
        
        bit_diff = sum(a != b for a, b in zip(original_hash, modified_hash))
        print(f"  Character Differences: {bit_diff}/64 ({bit_diff/64*100:.1f}%)")
        print("   ✓ Minor input change → Dramatic output change")
        
        # 5. Computational Efficiency
        print("\n ⚡ COMPUTATIONAL EFFICIENCY:")
        input_sizes = [100, 1000, 10000, 100000]
        print(f"  {'Input Size':>12} | {'Processing Time':>16} | {'Speed':>12}")
        print("-" * 45)
        
        for size in input_sizes:
            data = "X" * size
            start_time = time.time()
            hashlib.sha256(data.encode()).digest()
            elapsed = time.time() - start_time
            speed = size / elapsed if elapsed > 0 else 0
            print(f"  {size:>10} bytes | {elapsed:>14.6f}s | {speed:>10.0f} B/s")
    
    def demonstrate_blockchain_applications(self) -> None:
        """Show hash function applications in blockchain technology"""
        print("\n ⛓️  BLOCKCHAIN HASH APPLICATIONS")
        print("-" * 40)
        
        # Block structure hashing
        block_structure = {
            "height": 42,
            "transactions": ["Tx1: Alice→Bob (10 units)", "Tx2: Bob→Charlie (5 units)"],
            "timestamp": "2024-08-07 14:30:00",
            "previous_digest": "0000000000000000000000000000000000000000000000000000000000000000",
            "nonce": 123456
        }
        
        block_text = str(block_structure)
        block_digest = hashlib.sha256(block_text.encode()).hexdigest()
        
        print(f"📦 Block Data: {block_text[:80]}...")
        print(f"🔐 Block Digest: {block_digest}")
        
        # Tampering demonstration
        print("\n 🔍 TAMPER DETECTION:")
        corrupted_block = block_structure.copy()
        corrupted_block["transactions"][0] = "Tx1: Alice→Bob (1000 units)"
        corrupted_text = str(corrupted_block)
        corrupted_digest = hashlib.sha256(corrupted_text.encode()).hexdigest()
        
        print(f"  Original Digest: {block_digest[:20]}...")
        print(f"  Modified Digest: {corrupted_digest[:20]}...")
        print(f"  Integrity Intact: {block_digest == corrupted_digest}")
        print("   ✓ Any modification → Different hash (tamper evident)")
    
    def compare_hash_algorithms(self) -> None:
        """Compare different hash algorithm characteristics"""
        print("\n 📊 HASH ALGORITHM COMPARISON")
        print("-" * 40)
        
        test_data = "The quick brown fox jumps over the lazy dog"
        
        algorithms = [
            ("SHA-256", hashlib.sha256),
            ("SHA-512", hashlib.sha512),
            ("SHA-1", hashlib.sha1),
            ("MD5", hashlib.md5),
            ("SHA3-256", hashlib.sha3_256),
        ]
        
        print(f"Test Input: {test_data}\n")
        print(f" {'Algorithm':>10} | {'Digest Length':>14} | {'Output (First 16)'}")
        print("-" * 60)
        
        for name, algorithm in algorithms:
            digest = algorithm(test_data.encode()).hexdigest()
            print(f" {name:>10} | {len(digest):>14} | {digest[:16]}...")
        
        print("\n 💡 Algorithm Selection Guide:")
        print("  • SHA-256: Industry standard, Bitcoin, general security")
        print("  • SHA-512: Higher security, longer digest")
        print("  • SHA3-256: NIST standard, modern alternative")
        print("  • Avoid: MD5, SHA-1 (cryptographically broken)")

class HashAnalyticsEngine:
    """Advanced hash analysis and benchmarking tools"""
    
    @staticmethod
    def benchmark_performance(iterations: int = 10000) -> Dict[str, Any]:
        """Benchmark hash algorithm performance"""
        test_data = "Benchmark Test Data " * 100
        
        results = {}
        algorithms = [
            ("SHA-256", hashlib.sha256),
            ("SHA-512", hashlib.sha512),
            ("SHA3-256", hashlib.sha3_256),
        ]
        
        print("\n 🚀 PERFORMANCE BENCHMARK")
        print("-" * 40)
        
        for name, algorithm in algorithms:
            start_time = time.time()
            for _ in range(iterations):
                algorithm(test_data.encode()).hexdigest()
            elapsed = time.time() - start_time
            
            results[name] = {
                "iterations": iterations,
                "total_time": elapsed,
                "ops_per_second": iterations / elapsed
            }
            
            print(f"  {name}: {iterations} operations in {elapsed:.2f}s "
                  f"({iterations/elapsed:.0f} ops/s)")
        
        return results
    
    @staticmethod
    def analyze_collision_resistance() -> None:
        """Analyze collision resistance properties"""
        print("\n 🎯 COLLISION RESISTANCE ANALYSIS")
        print("-" * 40)
        
        # Generate many hashes and check for duplicates
        test_count = 5000
        hash_set = set()
        collisions = 0
        
        print(f"Testing {test_count} random inputs for collisions...")
        
        for i in range(test_count):
            input_data = f"Test_{i}_{time.time()}"
            digest = hashlib.sha256(input_data.encode()).hexdigest()
            
            if digest in hash_set:
                collisions += 1
            else:
                hash_set.add(digest)
        
        print(f"  Total Hashes Generated: {test_count}")
        print(f"  Collisions Detected: {collisions}")
        print(f"  Unique Hashes: {len(hash_set)}")
        print("   ✓ No collisions found (expected for cryptographic hashes)")

def demonstrate_hash_engine():
    """Execute comprehensive hash function demonstration"""
    print("=" * 60)
    print(" CRYPTOGRAPHIC DIGEST ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize demonstration
    demo = CryptographicDigestDemonstration()
    
    # Run all demonstrations
    demo.demonstrate_core_properties()
    demo.demonstrate_blockchain_applications()
    demo.compare_hash_algorithms()
    
    # Advanced analytics
    HashAnalyticsEngine.benchmark_performance(5000)
    HashAnalyticsEngine.analyze_collision_resistance()
    
    print("\n" + "=" * 60)
    print(" HASH FUNCTION SUMMARY:")
    print("   ✓ Deterministic: Same input → Identical output")
    print("   ✓ One-Way: Cannot reverse the transformation")
    print("   ✓ Collision Resistant: No two inputs produce same output")
    print("   ✓ Avalanche Effect: Small change → Big difference")
    print("   ✓ Efficient: Fast to compute")
    print("   ✓ Hashes are the foundation of blockchain integrity")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_hash_engine()

3.3 SHA-256

What is SHA-256?

SHA-256 (Secure Hash Algorithm 256-bit) is a cryptographic hash function that generates a fixed-length 256-bit (32-byte) hash value from input data. It’s one of the most widely used hash functions in blockchain technology and is the foundation of Bitcoin’s security.

SHA-256 Overview:

SHA-256 was developed by the National Security Agency (NSA) and published by the National Institute of Standards and Technology (NIST) as part of the SHA-2 family. It’s a Merkle-Damgård construction with a 512-bit block size and 256-bit output size.

Why SHA-256 is Important in Blockchain:

Bitcoin’s Choice: Bitcoin uses SHA-256 extensively:

  • Block Hashing: SHA-256 is used to hash block headers
  • Mining: Proof of Work uses SHA-256 (double SHA-256)
  • Transaction IDs: Each transaction has a SHA-256 hash
  • Merkle Trees: SHA-256 is used to build Merkle trees

The SHA-256 Algorithm Process:

  1. Padding: The input message is padded so its length is 448 mod 512 bits (leaving 64 bits for length)
  2. Length: The original length of the message is appended as a 64-bit integer
  3. Initialization: Eight 32-bit state variables are initialized with specific constants
  4. Processing: The message is processed in 512-bit chunks through 64 rounds of operations
  5. Output: The final state is concatenated to produce the 256-bit hash

SHA-256 Properties:

PropertyValue
Output Size256 bits (32 bytes, 64 hex characters)
Block Size512 bits (64 bytes)
Security Level128-bit collision resistance
PerformanceFast and efficient
Rounds64 rounds of compression

Double SHA-256 in Bitcoin:

Bitcoin uses double SHA-256 (SHA-256 applied twice) for block hashing:

Double SHA-256 = SHA-256(SHA-256(data))

This provides extra security and is used in the mining process where miners search for a nonce that makes the double SHA-256 hash meet the difficulty target.

Code Example – SHA-256:

"""
SECURE HASH ALGORITHM 256-BIT IMPLEMENTATION
============================================
Comprehensive SHA-256 demonstration with mining simulation and blockchain applications
"""

import hashlib
import time
from typing import List, Dict, Tuple
from dataclasses import dataclass

@dataclass
class MiningResult:
    """Represents the result of a mining attempt"""
    nonce: int
    hash_value: str
    attempts: int
    time_elapsed: float
    hash_rate: float

class SHA256Engine:
    """Complete SHA-256 demonstration and analysis suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" SHA-256 SECURE HASH ALGORITHM ENGINE")
        print("=" * 60)
    
    def demonstrate_basic_hashing(self) -> None:
        """Show basic SHA-256 hashing examples"""
        print("\n 📝 BASIC SHA-256 HASHING")
        print("-" * 40)
        
        test_messages = [
            "Hello, Decentralized World!",
            "Blockchain Technology",
            "The cryptographic foundation of trust",
            "Satoshi Nakamoto",
            "Proof of Work consensus mechanism"
        ]
        
        print(f"{'Input (First 30 chars)':<35} | {'SHA-256 Digest (First 16)'}")
        print("-" * 65)
        
        for message in test_messages:
            digest = hashlib.sha256(message.encode()).hexdigest()
            print(f"{message[:30]:<35} | {digest[:16]}...")
        
        print(f"\n 📊 Hash Properties:")
        print(f"   • Output Size: 256 bits (32 bytes)")
        print(f"   • Hex Representation: {len(digest)} characters")
        print(f"   • Security Level: 128-bit collision resistance")
    
    def demonstrate_double_hashing(self) -> None:
        """Show double SHA-256 (Bitcoin-style)"""
        print("\n 🔄 DOUBLE SHA-256 (BITCOIN)")
        print("-" * 40)
        
        original_data = "Bitcoin Block Header Example"
        single_hash = hashlib.sha256(original_data.encode()).hexdigest()
        double_hash = hashlib.sha256(original_data.encode()).hexdigest()
        
        print(f"Original Data: {original_data}")
        print(f"Single SHA-256: {single_hash[:32]}...")
        print(f"Double SHA-256: {double_hash[:32]}...")
        
        print("\n 💡 Bitcoin Double SHA-256 Applications:")
        print("   • Block Header Hashing")
        print("   • Proof of Work Target")
        print("   • Enhanced Collision Resistance")
        print("   • Standard Security Practice")
    
    def perform_mining_simulation(self) -> None:
        """Simulate SHA-256 mining with varying difficulties"""
        print("\n ⛏️  SHA-256 MINING SIMULATION")
        print("-" * 40)
        
        block_data = "Block #12345: Transactions and Data"
        difficulties = [2, 3, 4]
        
        print(f"Mining Block: {block_data[:40]}...")
        print("=" * 50)
        
        for difficulty in difficulties:
            print(f"\n 📊 Difficulty Level: {difficulty}")
            print(f"   Target Pattern: {'0' * difficulty}...")
            
            result = self._mine_hash(block_data, difficulty)
            
            print(f"   ✅ Block Found!")
            print(f"   🔑 Hash: {result.hash_value}")
            print(f"   🔢 Nonce: {result.nonce}")
            print(f"   ⏱️  Time: {result.time_elapsed:.3f}s")
            print(f"   🔄 Attempts: {result.attempts:,}")
            print(f"   📈 Hash Rate: {result.hash_rate:.0f} H/s")
    
    def _mine_hash(self, block_data: str, difficulty: int) -> MiningResult:
        """Internal mining simulation"""
        target_pattern = "0" * difficulty
        nonce = 0
        start_time = time.time()
        
        while True:
            combined = f"{block_data}{nonce}"
            hash_value = hashlib.sha256(combined.encode()).hexdigest()
            
            if hash_value[:difficulty] == target_pattern:
                elapsed = time.time() - start_time
                return MiningResult(
                    nonce=nonce,
                    hash_value=hash_value,
                    attempts=nonce + 1,
                    time_elapsed=elapsed,
                    hash_rate=(nonce + 1) / elapsed if elapsed > 0 else 0
                )
            
            nonce += 1
            
            # Progress indicator for long mining attempts
            if nonce % 10000 == 0:
                print(f"   Searching... {nonce:,} attempts", end="\r")
    
    def analyze_hash_properties(self) -> None:
        """Analyze SHA-256 cryptographic properties"""
        print("\n 🔐 SHA-256 CRYPTOGRAPHIC PROPERTIES")
        print("-" * 40)
        
        properties = {
            "Algorithm Family": "SHA-2 (Secure Hash Algorithm 2)",
            "Output Size": "256 bits (32 bytes)",
            "Block Size": "512 bits (64 bytes)",
            "Message Padding": "Merkle-Damgård construction",
            "Rounds": "64 compression rounds",
            "Security Level": "128-bit collision resistance",
            "Developer": "NSA (National Security Agency)",
            "Publication Year": "2001",
            "Status": "Cryptographically secure",
            "Primary Use": "Blockchain, digital signatures, password hashing"
        }
        
        print(" 📊 Algorithm Specifications:")
        for property_name, value in properties.items():
            print(f"   • {property_name}: {value}")

class SHA256Analytics:
    """Additional analysis tools for SHA-256"""
    
    @staticmethod
    def compare_hash_performance() -> None:
        """Compare SHA-256 with other hash algorithms"""
        print("\n ⚡ HASH PERFORMANCE COMPARISON")
        print("-" * 40)
        
        test_data = "Performance Test Data " * 1000
        iterations = 10000
        
        algorithms = [
            ("SHA-256", hashlib.sha256),
            ("SHA-512", hashlib.sha512),
            ("SHA-1", hashlib.sha1),
            ("MD5", hashlib.md5)
        ]
        
        print(f"Test Data Size: {len(test_data)} bytes")
        print(f"Iterations: {iterations:,}")
        print(f"\n {'Algorithm':>10} | {'Time (s)':>10} | {'Ops/sec':>10}")
        print("-" * 40)
        
        for name, algorithm in algorithms:
            start_time = time.time()
            for _ in range(iterations):
                algorithm(test_data.encode()).digest()
            elapsed = time.time() - start_time
            ops_per_sec = iterations / elapsed
            
            print(f" {name:>10} | {elapsed:>10.3f} | {ops_per_sec:>10.0f}")
    
    @staticmethod
    def analyze_collision_resistance() -> None:
        """Demonstrate collision resistance property"""
        print("\n 🎯 COLLISION RESISTANCE DEMONSTRATION")
        print("-" * 40)
        
        messages = [
            "The quick brown fox jumps over the lazy dog",
            "The quick brown fox jumps over the lazy dog!",  # Exclamation mark added
            "The quick brown fox jumps over the lazy dOg"   # Case changed
        ]
        
        print("Even Minor Variations Produce Completely Different Hashes:")
        print("-" * 50)
        
        for msg in messages:
            digest = hashlib.sha256(msg.encode()).hexdigest()
            print(f"\n  Input: {msg[:40]}...")
            print(f"  Hash:  {digest[:20]}...")
        
        print("\n 💡 Key Observation:")
        print("   • Adding a single character completely changes the hash")
        print("   • The avalanche effect provides strong security")

def demonstrate_sha256_engine():
    """Execute comprehensive SHA-256 demonstration"""
    print("=" * 60)
    print(" SHA-256 SECURE HASH ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = SHA256Engine()
    
    # Run demonstrations
    engine.demonstrate_basic_hashing()
    engine.demonstrate_double_hashing()
    engine.perform_mining_simulation()
    engine.analyze_hash_properties()
    
    # Additional analytics
    SHA256Analytics.compare_hash_performance()
    SHA256Analytics.analyze_collision_resistance()
    
    print("\n" + "=" * 60)
    print(" SHA-256 CHARACTERISTICS SUMMARY:")
    print("   ✓ Output: 256 bits (32 bytes, 64 hex characters)")
    print("   ✓ Security: 128-bit collision resistance")
    print("   ✓ Speed: Efficient and optimized")
    print("   ✓ Usage: Bitcoin, Ethereum, and many blockchains")
    print("   ✓ Double SHA-256: Bitcoin's standard practice")
    print("   ✓ Mining: Proof of Work target finding")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_sha256_engine()

3.4 Keccak-256

What is Keccak-256?

Keccak-256 is a cryptographic hash function that was selected as the winner of the NIST SHA-3 competition. Ethereum uses Keccak-256 (not SHA-3) for its hashing needs, making it one of the most important hash functions in the blockchain ecosystem.

Keccak-256 vs SHA-3:

There is a common confusion between Keccak-256 and SHA-3. Keccak was the winning submission in the SHA-3 competition, but the NIST made some minor changes to the padding before standardizing SHA-3. Ethereum uses the original Keccak-256 (pre-NIST standardization), not SHA-3.

FeatureKeccak-256SHA-3
PaddingDifferent paddingNIST-standard padding
SecurityVery HighVery High
Used InEthereum, many dAppsGeneral use
StandardPre-SHA-3FIPS 202

Keccak-256 Properties:

PropertyDescription
Output Size256 bits (32 bytes, 64 hex characters)
ConstructionSponge construction (not Merkle-Damgård)
Security128-bit collision resistance
PerformanceFast and efficient
Used InEthereum, many dApps

Why Keccak-256 is Important in Blockchain:

Ethereum’s Choice: Ethereum uses Keccak-256 extensively:

  • Address Generation: Ethereum addresses are derived from Keccak-256 hashes
  • Block Hashing: Keccak-256 is used for block hashes
  • Transaction IDs: Transaction hashes use Keccak-256
  • Smart Contracts: Contract code hashing uses Keccak-256

The Sponge Construction:

Unlike SHA-256 (which uses Merkle-Damgård), Keccak uses a “sponge construction.” This means:

  1. Absorbing phase: Input data is absorbed into the state
  2. Squeezing Phase: The final output is generated by repeatedly extracting data from the internal state.

This construction provides additional security and flexibility.

Code Example – Keccak-256:

"""
KECCAK-256 CRYPTOGRAPHIC ENGINE
================================
Comprehensive implementation and demonstration of Ethereum's hash function
"""

import hashlib
import time
from typing import List, Dict, Tuple, Optional
from dataclasses import dataclass

@dataclass
class EthereumAddress:
    """Represents an Ethereum address derived from public key"""
    public_key: str
    keccak_hash: str
    address: str
    checksum_address: str

class Keccak256Engine:
    """Complete Keccak-256 demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" KECCAK-256 - ETHEREUM CRYPTOGRAPHIC ENGINE")
        print("=" * 60)
    
    def demonstrate_basic_hashing(self) -> None:
        """Show basic Keccak-256 hashing examples"""
        print("\n 📝 BASIC KECCAK-256 HASHING")
        print("-" * 40)
        
        test_messages = [
            "Hello, Ethereum World!",
            "Smart Contract Deployment",
            "Vitalik Buterin",
            "Decentralized Applications",
            "The Ethereum blockchain ecosystem"
        ]
        
        print(f"{'Input (First 30 chars)':<35} | {'Keccak-256 Digest (First 16)'}")
        print("-" * 65)
        
        for message in test_messages:
            # SHA3-256 is Keccak-256 with slight parameter difference
            # For demonstration, we use SHA3-256 (NIST standard)
            digest = hashlib.sha3_256(message.encode()).hexdigest()
            print(f"{message[:30]:<35} | {digest[:16]}...")
        
        print(f"\n 📊 Keccak-256 Properties:")
        print(f"   • Output Size: 256 bits (32 bytes)")
        print(f"   • Hex Length: {len(digest)} characters")
        print(f"   • Construction: Sponge (not Merkle-Damgård)")
        print(f"   • Security: 128-bit collision resistance")
        print(f"   • Status: Ethereum's primary hash function")
    
    def generate_ethereum_address(self) -> None:
        """Demonstrate Ethereum address generation from public key"""
        print("\n 🏛️  ETHEREUM ADDRESS GENERATION")
        print("-" * 40)
        
        # Sample public key (simplified for demonstration)
        sample_public_key = "0x04f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f9c4e2a2b6b5e5a5d5"
        print(f"Public Key: {sample_public_key[:20]}...")
        print(f"Public Key Length: {len(sample_public_key)} characters")
        
        # Convert to bytes and hash
        public_key_bytes = bytes.fromhex(sample_public_key.replace("0x", ""))
        keccak_hash = hashlib.sha3_256(public_key_bytes).hexdigest()
        
        # Extract last 20 bytes for address
        ethereum_address = f"0x{keccak_hash[-40:]}"
        
        print(f"\n 🔑 Keccak-256 Hash: {keccak_hash[:16]}...")
        print(f" 📍 Ethereum Address: {ethereum_address}")
        print(f" 📏 Address Length: {len(ethereum_address)} characters")
        
        print("\n 💡 Address Derivation Process:")
        print("   • Public Key (64 bytes)")
        print("   ↓ Keccak-256 Hashing")
        print("   • Hash (32 bytes)")
        print("   ↓ Extract Last 20 Bytes")
        print("   • Ethereum Address (20 bytes)")
    
    def compare_with_sha256(self) -> None:
        """Compare Keccak-256 with SHA-256"""
        print("\n 🔄 KECCAK-256 VS SHA-256 COMPARISON")
        print("-" * 40)
        
        test_data = "Ethereum Blockchain"
        
        sha256_hash = hashlib.sha256(test_data.encode()).hexdigest()
        keccak_hash = hashlib.sha3_256(test_data.encode()).hexdigest()
        
        print(f"Input Data: {test_data}\n")
        
        print(f"SHA-256:")
        print(f"  Hash: {sha256_hash}")
        print(f"  Length: {len(sha256_hash)} characters")
        print(f"  Algorithm: Merkle-Damgård construction")
        
        print(f"\nKeccak-256 (SHA-3):")
        print(f"  Hash: {keccak_hash}")
        print(f"  Length: {len(keccak_hash)} characters")
        print(f"  Algorithm: Sponge construction")
        
        print("\n 🆚 Key Differences:")
        print("   • Both produce 256-bit outputs (64 hex characters)")
        print("   • Different internal construction")
        print("   • Keccak-256 is more resistant to length extension attacks")
        print("   • Ethereum uses Keccak-256, not standard SHA-3")
        print("   • SHA-3 is based on Keccak but with different padding")
    
    def demonstrate_ethereum_applications(self) -> None:
        """Show Ethereum-specific applications of Keccak-256"""
        print("\n ⛓️  ETHEREUM KECCAK-256 APPLICATIONS")
        print("-" * 40)
        
        applications = {
            "Address Generation": {
                "process": "Public key → Keccak-256 → Last 20 bytes",
                "example": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
                "purpose": "Unique account identifier"
            },
            "Block Hashing": {
                "process": "Block header → Keccak-256",
                "example": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
                "purpose": "Block integrity and linking"
            },
            "Transaction IDs": {
                "process": "Transaction RLP → Keccak-256",
                "example": "0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060",
                "purpose": "Unique transaction identifier"
            },
            "Contract Code Hashing": {
                "process": "Bytecode → Keccak-256",
                "example": "0x6080604052600080fd5b5060c9565b6000f...",
                "purpose": "Contract deployment verification"
            }
        }
        
        print(" 📊 Application Overview:")
        for app_name, details in applications.items():
            print(f"\n  {app_name}:")
            print(f"    Process: {details['process']}")
            print(f"    Example: {details['example'][:20]}...")
            print(f"    Purpose: {details['purpose']}")

class KeccakAnalytics:
    """Additional analysis tools for Keccak-256"""
    
    @staticmethod
    def compare_hash_performance() -> None:
        """Compare Keccak-256 performance with other hash functions"""
        print("\n ⚡ HASH PERFORMANCE COMPARISON")
        print("-" * 40)
        
        test_data = "Performance Comparison Data" * 100
        iterations = 10000
        
        algorithms = [
            ("Keccak-256", hashlib.sha3_256),
            ("SHA-256", hashlib.sha256),
            ("SHA-512", hashlib.sha512)
        ]
        
        print(f"Test Data Size: {len(test_data)} bytes")
        print(f"Iterations: {iterations:,}\n")
        
        results = []
        for name, algorithm in algorithms:
            start_time = time.time()
            for _ in range(iterations):
                algorithm(test_data.encode()).digest()
            elapsed = time.time() - start_time
            ops_per_sec = iterations / elapsed
            
            results.append((name, elapsed, ops_per_sec))
        
        print(f" {'Algorithm':>12} | {'Time (s)':>10} | {'Ops/sec':>10}")
        print("-" * 40)
        
        for name, elapsed, ops in results:
            print(f" {name:>12} | {elapsed:>10.3f} | {ops:>10.0f}")
    
    @staticmethod
    def analyze_hash_distribution() -> None:
        """Analyze hash distribution properties"""
        print("\n 📊 HASH DISTRIBUTION ANALYSIS")
        print("-" * 40)
        
        # Generate hashes and analyze distribution
        hash_count = 100
        prefix_counts = {}
        
        print(f"Generating {hash_count} hashes and analyzing first character distribution...")
        
        for i in range(hash_count):
            test_input = f"Test_{i}_{time.time()}"
            digest = hashlib.sha3_256(test_input.encode()).hexdigest()
            first_char = digest[0]
            
            prefix_counts[first_char] = prefix_counts.get(first_char, 0) + 1
        
        # Display distribution
        print("\n First Character Distribution:")
        for char, count in sorted(prefix_counts.items()):
            percentage = (count / hash_count) * 100
            bar = "█" * int(percentage / 2)
            print(f"  {char}: {count:3} ({percentage:5.1f}%) {bar}")
        
        print("\n 💡 Keccak-256 produces uniform distribution")
        print("   • Each character appears approximately equally")
        print("   • Good randomization property for cryptography")

def demonstrate_keccak_engine():
    """Execute comprehensive Keccak-256 demonstration"""
    print("=" * 60)
    print(" KECCAK-256 CRYPTOGRAPHIC ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = Keccak256Engine()
    
    # Run demonstrations
    engine.demonstrate_basic_hashing()
    engine.generate_ethereum_address()
    engine.compare_with_sha256()
    engine.demonstrate_ethereum_applications()
    
    # Additional analytics
    KeccakAnalytics.compare_hash_performance()
    KeccakAnalytics.analyze_hash_distribution()
    
    print("\n" + "=" * 60)
    print(" KECCAK-256 SUMMARY:")
    print("   ✓ Output: 256 bits (32 bytes, 64 hex characters)")
    print("   ✓ Construction: Sponge (more flexible)")
    print("   ✓ Security: 128-bit collision resistance")
    print("   ✓ Ethereum: Primary hash function")
    print("   ✓ Applications: Addresses, blocks, transactions, contracts")
    print("   ✓ Advantages: Resistance to length extension attacks")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_keccak_engine()

3.5 Public Key Cryptography

What is Public Key Cryptography?

Public key cryptography, also called asymmetric cryptography, uses two mathematically related keys: a public key (shared openly) and a private key (kept secret). What is encrypted with one key can only be decrypted with the other. This system was invented in the 1970s and revolutionized cryptography.

How Public Key Cryptography Works:

Key Generation:
A pair of keys (public and private) is generated using mathematical algorithms. The keys are mathematically linked but it’s computationally impossible to derive the private key from the public key.

Encryption:
Data encrypted with the public key can only be decrypted with the private key. This enables secure communication: anyone can encrypt a message with your public key, but only you can read it.

Signing:
Data signed with the private key can be verified with the public key. This proves that the message came from the owner of the private key and hasn’t been altered.

The Two Types of Keys:

Private Key:

  • Kept secret at all times
  • Used to sign transactions
  • Used to decrypt messages
  • Never shared with anyone
  • If lost, funds are lost forever
  • If compromised, funds can be stolen

Public Key:

  • Shared openly
  • Used to verify signatures
  • Used to encrypt messages
  • Can be shared without security risk
  • Derived from private key
  • Used to generate wallet addresses

Applications in Blockchain:

ApplicationHow It WorksPurpose
Address GenerationPublic key → Hash → AddressReceive funds
Transaction SigningPrivate key signs transactionProve ownership
Identity VerificationPublic key verifies signatureEstablish identity
Secure CommunicationPublic key encrypts messagesPrivate communication

Code Example – Public Key Cryptography:

"""
ASYMMETRIC CRYPTOGRAPHIC FRAMEWORK
==================================
Complete demonstration of public-private key cryptography with blockchain applications
"""

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
import hashlib
import base64
from typing import Tuple, Optional
from dataclasses import dataclass

@dataclass
class KeyPair:
    """Represents a cryptographic key pair"""
    private_key: ec.EllipticCurvePrivateKey
    public_key: ec.EllipticCurvePublicKey
    private_hex: str
    public_hex: str
    address: str

@dataclass
class SignatureResult:
    """Represents a signature verification result"""
    message: bytes
    signature: bytes
    is_valid: bool
    verification_time: float

class AsymmetricCryptographyEngine:
    """Comprehensive public key cryptography demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ASYMMETRIC CRYPTOGRAPHIC ENGINE")
        print("=" * 60)
    
    def generate_crypto_keys(self) -> KeyPair:
        """Generate secp256k1 public-private key pair"""
        print("\n 🔑 KEY GENERATION")
        print("-" * 40)
        
        # Generate key pair using SECP256K1 curve (Bitcoin/Ethereum standard)
        private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        public_key = private_key.public_key()
        
        # Extract numeric values
        private_numbers = private_key.private_numbers()
        public_numbers = public_key.public_numbers()
        
        print(f"Private Key (Hex): {private_numbers.private_value:x}")
        print(f"Private Key Length: {len(str(private_numbers.private_value))} digits")
        
        print(f"\nPublic Key Coordinates:")
        print(f"  X: {public_numbers.x:x}")
        print(f"  Y: {public_numbers.y:x}")
        print(f"  Curve: SECP256K1")
        
        # Serialize to PEM format
        private_pem = private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        )
        
        public_pem = public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )
        
        # Generate address
        address = self._generate_address(public_key)
        
        print(f"\n📁 Serialized Keys:")
        print(f"  Private Key (PEM): {private_pem[:40]}...")
        print(f"  Public Key (PEM):  {public_pem[:40]}...")
        print(f"  Address: {address}")
        
        return KeyPair(
            private_key=private_key,
            public_key=public_key,
            private_hex=hex(private_numbers.private_value),
            public_hex=f"0x{public_numbers.x:x}{public_numbers.y:x}",
            address=address
        )
    
    def _generate_address(self, public_key: ec.EllipticCurvePublicKey) -> str:
        """Generate Bitcoin-style address from public key"""
        # Get uncompressed public key bytes
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.UncompressedPoint
        )
        
        # Hash with SHA-256 and RIPEMD-160
        sha256_hash = hashlib.sha256(public_bytes).digest()
        ripemd160_hash = hashlib.new('ripemd160', sha256_hash).digest()
        
        # Add network byte (0x00 for Bitcoin mainnet)
        versioned_payload = b'\x00' + ripemd160_hash
        
        # Calculate checksum
        checksum = hashlib.sha256(hashlib.sha256(versioned_payload).digest()).digest()[:4]
        
        # Base58 encode
        import base58
        address = base58.b58encode(versioned_payload + checksum).decode()
        
        return address
    
    def demonstrate_digital_signatures(self, key_pair: KeyPair) -> None:
        """Show digital signature creation and verification"""
        print("\n ✍️  DIGITAL SIGNATURES")
        print("-" * 40)
        
        # Original message
        original_message = b"Transfer 50 tokens to Address 0xABC123"
        print(f"Original Message: {original_message.decode()}")
        
        # Create signature
        signature = key_pair.private_key.sign(
            original_message,
            ec.ECDSA(hashes.SHA256())
        )
        print(f"\nSignature: {signature.hex()[:32]}...")
        print(f"Signature Size: {len(signature)} bytes")
        
        # Verify original signature
        try:
            key_pair.public_key.verify(
                signature,
                original_message,
                ec.ECDSA(hashes.SHA256())
            )
            print("✅ Signature Verification: VALID")
        except Exception:
            print("❌ Signature Verification: INVALID")
        
        # Tampered message
        tampered_message = b"Transfer 500 tokens to Address 0xABC123"
        print(f"\nTampered Message: {tampered_message.decode()}")
        
        try:
            key_pair.public_key.verify(
                signature,
                tampered_message,
                ec.ECDSA(hashes.SHA256())
            )
            print("⚠️  Signature Verification: VALID (should be invalid)")
        except Exception:
            print("🛡️  Signature Verification: INVALID (tampering detected)")
        
        print("\n 💡 Digital Signature Properties:")
        print("   ✓ Authenticity: Proves message origin")
        print("   ✓ Integrity: Detects tampering")
        print("   ✓ Non-repudiation: Cannot deny signing")
        print("   ✓ Blockchain Application: Transaction authorization")
    
    def demonstrate_encryption_concept(self) -> None:
        """Explain encryption/decryption concepts"""
        print("\n 🔐 ENCRYPTION/DECRYPTION CONCEPT")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ASYMMETRIC ENCRYPTION FLOW                              │
├─────────────────────────────────────────────────────────────┤
│  1. Sender obtains recipient's PUBLIC KEY                 │
│  2. Sender encrypts message with recipient's PUBLIC KEY    │
│  3. Encrypted message (ciphertext) sent                   │
│  4. Recipient decrypts with PRIVATE KEY                   │
│  5. Only recipient can read the message                   │
│                                                           │
│  USAGE IN BLOCKCHAIN:                                    │
│   • Secure communication channels                         │
│   • Wallet encryption                                     │
│   • Transaction signing (signatures)                      │
│   • Identity verification                                 │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_blockchain_applications(self) -> None:
        """Explain cryptography applications in blockchain"""
        print("\n ⛓️  BLOCKCHAIN CRYPTOGRAPHIC APPLICATIONS")
        print("-" * 40)
        
        applications = {
            "Wallet Address Generation": {
                "process": "Private Key → Public Key → Hash → Address",
                "purpose": "Creating unique wallet identifiers",
                "standard": "Bitcoin/Ethereum addressing"
            },
            "Transaction Authorization": {
                "process": "Transaction Data → Sign with Private Key",
                "purpose": "Proving ownership and authorizing transfers",
                "standard": "ECDSA signatures"
            },
            "Identity Verification": {
                "process": "Challenge → Sign → Verify with Public Key",
                "purpose": "Proving identity without sharing private key",
                "standard": "Challenge-response authentication"
            },
            "Secure Communication": {
                "process": "Encrypt with Public Key → Decrypt with Private Key",
                "purpose": "Private messaging between blockchain participants",
                "standard": "Elliptic curve encryption"
            }
        }
        
        print("\n 📊 Cryptography in Blockchain:")
        for app_name, details in applications.items():
            print(f"\n  {app_name}:")
            print(f"    Process: {details['process']}")
            print(f"    Purpose: {details['purpose']}")
            print(f"    Standard: {details['standard']}")
    
    def compare_curves(self) -> None:
        """Compare different elliptic curves"""
        print("\n 📊 ELLIPTIC CURVE COMPARISON")
        print("-" * 40)
        
        curves = {
            "SECP256K1": {
                "key_size": "256 bits",
                "security": "128 bits",
                "usage": "Bitcoin, Ethereum",
                "speed": "Fast"
            },
            "SECP256R1": {
                "key_size": "256 bits",
                "security": "128 bits",
                "usage": "NIST standard",
                "speed": "Fast"
            },
            "SECP384R1": {
                "key_size": "384 bits",
                "security": "192 bits",
                "usage": "Government/Enterprise",
                "speed": "Moderate"
            },
            "SECP521R1": {
                "key_size": "521 bits",
                "security": "256 bits",
                "usage": "High security",
                "speed": "Slower"
            }
        }
        
        print(f" {'Curve':>12} | {'Key Size':>12} | {'Security':>10} | {'Usage':>15} | {'Speed':>10}")
        print("-" * 65)
        
        for curve_name, details in curves.items():
            print(f" {curve_name:>12} | {details['key_size']:>12} | "
                  f"{details['security']:>10} | {details['usage']:>15} | {details['speed']:>10}")
        
        print("\n 💡 Recommendation:")
        print("   • SECP256K1: Default for blockchain applications")
        print("   • SECP256R1: When NIST compliance is required")
        print("   • Higher curves: When extra security is needed")

class CryptographicAnalytics:
    """Additional cryptographic analysis tools"""
    
    @staticmethod
    def analyze_key_strength() -> None:
        """Analyze cryptographic key strength"""
        print("\n 🛡️  KEY STRENGTH ANALYSIS")
        print("-" * 40)
        
        key_strengths = {
            "Key Type": ["ECC-256", "ECC-384", "ECC-521", "RSA-2048", "RSA-4096"],
            "Security Level": ["128-bit", "192-bit", "256-bit", "112-bit", "128-bit"],
            "Equivalent Symmetric": ["AES-128", "AES-192", "AES-256", "AES-112", "AES-128"],
            "Recommended": ["✅ Yes", "✅ Yes", "✅ Yes", "⚠️  Deprecated", "✅ Yes"]
        }
        
        print(f" {'Key Type':>12} | {'Security':>12} | {'Symmetric Equivalent':>20} | {'Recommended':>12}")
        print("-" * 60)
        
        for i in range(len(key_strengths["Key Type"])):
            key_type = key_strengths["Key Type"][i]
            security = key_strengths["Security Level"][i]
            symmetric = key_strengths["Equivalent Symmetric"][i]
            recommended = key_strengths["Recommended"][i]
            
            print(f" {key_type:>12} | {security:>12} | {symmetric:>20} | {recommended:>12}")

def demonstrate_crypto_engine():
    """Execute comprehensive cryptographic demonstration"""
    print("=" * 60)
    print(" ASYMMETRIC CRYPTOGRAPHIC ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = AsymmetricCryptographyEngine()
    
    # Generate keys
    key_pair = engine.generate_crypto_keys()
    
    # Run demonstrations
    engine.demonstrate_digital_signatures(key_pair)
    engine.demonstrate_encryption_concept()
    engine.explain_blockchain_applications()
    engine.compare_curves()
    
    # Additional analytics
    CryptographicAnalytics.analyze_key_strength()
    
    print("\n" + "=" * 60)
    print(" PUBLIC KEY CRYPTOGRAPHY SUMMARY:")
    print("   ✓ Two Keys: Private (secret) and Public (shared)")
    print("   ✓ Digital Signatures: Authentication and integrity")
    print("   ✓ Address Generation: From public key to wallet address")
    print("   ✓ Blockchain Foundation: Secure transactions and identity")
    print("   ✓ ECDSA: Standard signature algorithm")
    print("   ✓ SECP256K1: Bitcoin/Ethereum curve standard")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_crypto_engine()

3.6 Private Keys

What is a Private Key?

A private key is a randomly generated number that controls access to cryptocurrency and is used to sign transactions. It’s the most critical piece of information in blockchain security. The private key is the “secret” that proves ownership of funds and authorizes transactions.

Private Key Characteristics:

1. Randomness:

Private keys must be truly random to be secure. Any pattern or predictability makes them vulnerable to attack. The randomness must come from a cryptographically secure random number generator.

Why Randomness Matters: If private keys are predictable, an attacker could guess them and steal funds. The 256-bit key space (2^256 possible keys) is so large that brute force is impossible—but only if the keys are truly random.

2. Length:

Typically 256 bits (32 bytes). This provides 2^256 possible keys, making brute force attacks computationally impossible. To put this in perspective, 2^256 is more than the number of atoms in the observable universe.

3. Secrecy:

The private key must never be shared. Anyone with the private key has full control over the associated funds. The private key is the “password” to your cryptocurrency.

4. Single Point of Failure:

Losing a private key can permanently result in the loss of access to the associated funds, as blockchain systems generally have no central “forgot password” or key-recovery mechanism. If you lose your private key, your funds are gone forever.

Private Key Formats:

FormatDescriptionExampleUse Case
Hex64 hex characters0x1e99423a4ed27608…Machine-readable
WIFWallet Import Format5HueCGU8rMjxEXxi…Easy to copy
Mnemonic12-24 words“abandon ability able…”Human-friendly backup

Private Key Security:

Best PracticeWhy
Store OfflinePrevents online hacking
Use Hardware WalletPrivate key never leaves device
Multiple BackupsProtects against loss
Never ShareAnyone with key controls funds
Secure LocationPhysical and digital security

Code Example – Private Keys:

"""
CRYPTOGRAPHIC KEY MANAGEMENT FRAMEWORK
======================================
Complete private key generation, formatting, and security demonstration
"""

import secrets
import hashlib
import base58
import random
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass

@dataclass
class PrivateKeyData:
    """Represents a private key in various formats"""
    hex_key: str
    wif_key: str
    mnemonic_phrase: str
    entropy_bits: int
    checksum: str

@dataclass
class KeySecurityAdvice:
    """Security recommendations for private keys"""
    category: str
    recommendation: str
    risk_level: str
    implementation: str

class PrivateKeyManagementEngine:
    """Comprehensive private key demonstration and management suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" PRIVATE KEY MANAGEMENT ENGINE")
        print("=" * 60)
    
    def generate_secure_private_key(self) -> PrivateKeyData:
        """Generate cryptographically secure private key"""
        print("\n 🔑 GENERATING PRIVATE KEY")
        print("-" * 40)
        
        # Generate 256-bit secure random key
        key_bytes = secrets.token_bytes(32)
        hex_key = key_bytes.hex()
        
        print(f"Raw Private Key (Hex):")
        print(f"  {hex_key[:32]}")
        print(f"  {hex_key[32:]}")
        print(f"  Length: {len(hex_key)} hex characters")
        print(f"  Entropy: {len(hex_key) * 4} bits")
        
        # Show statistics
        print(f"\n 📊 Key Statistics:")
        print(f"  • Total Possible Keys: 2^256")
        print(f"  • Key Space: 115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640,564,039,457,584,007,913,129,639,936")
        print(f"  • Security Level: 128-bit collision resistance")
        print(f"  • Generated Using: System random (cryptographically secure)")
        
        # Convert to formats
        wif_key = self._convert_to_wif(hex_key)
        mnemonic = self._generate_mnemonic_phrase()
        
        print(f"\n 📋 Private Key Formats:")
        print(f"  • Hex Format:     {hex_key[:16]}...")
        print(f"  • WIF Format:     {wif_key}")
        print(f"  • Mnemonic Phrase: {mnemonic[:30]}...")
        
        return PrivateKeyData(
            hex_key=hex_key,
            wif_key=wif_key,
            mnemonic_phrase=mnemonic,
            entropy_bits=256,
            checksum=hashlib.sha256(key_bytes).hexdigest()[:8]
        )
    
    def _convert_to_wif(self, hex_key: str) -> str:
        """Convert hex private key to Wallet Import Format"""
        # Add mainnet version byte (0x80)
        versioned = b'\x80' + bytes.fromhex(hex_key)
        
        # Add compression flag
        versioned += b'\x01'
        
        # Calculate double SHA-256 checksum
        checksum = hashlib.sha256(hashlib.sha256(versioned).digest()).digest()[:4]
        
        # Base58 encode
        return base58.b58encode(versioned + checksum).decode()
    
    def _generate_mnemonic_phrase(self, word_count: int = 12) -> str:
        """Generate BIP-39 style mnemonic phrase"""
        # Extended word list (BIP-39 English)
        word_list = [
            "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", "alcohol", "alert", "alien",
            "all", "alley", "allow", "almost", "alone", "alpha", "already"
        ]
        
        selected_words = random.sample(word_list, word_count)
        return " ".join(selected_words)
    
    def demonstrate_security_implications(self) -> None:
        """Explain security implications of private key management"""
        print("\n 🛡️  PRIVATE KEY SECURITY IMPLICATIONS")
        print("-" * 40)
        
        security_advice = [
            KeySecurityAdvice(
                category="Storage",
                recommendation="Store offline in hardware wallets",
                risk_level="Critical",
                implementation="Ledger, Trezor, or cold storage"
            ),
            KeySecurityAdvice(
                category="Backup",
                recommendation="Multiple redundant backups",
                risk_level="High",
                implementation="3-2-1 backup strategy"
            ),
            KeySecurityAdvice(
                category="Sharing",
                recommendation="Never share with anyone",
                risk_level="Critical",
                implementation="Keep private key strictly confidential"
            ),
            KeySecurityAdvice(
                category="Generation",
                recommendation="Use cryptographically secure RNG",
                risk_level="High",
                implementation="Hardware generation or secure environment"
            ),
            KeySecurityAdvice(
                category="Recovery",
                recommendation="Test recovery procedure",
                risk_level="Medium",
                implementation="Regular recovery drills"
            ),
            KeySecurityAdvice(
                category="Exposure",
                recommendation="Avoid digital copies",
                risk_level="Critical",
                implementation="Paper or steel backups only"
            )
        ]
        
        print(" 📊 Security Advisory Matrix:")
        print(f" {'Category':>15} | {'Recommendation':>25} | {'Risk':>12} | {'Implementation':>20}")
        print("-" * 80)
        
        for advice in security_advice:
            print(f" {advice.category:>15} | {advice.recommendation:>25} | "
                  f"{advice.risk_level:>12} | {advice.implementation:>20}")
    
    def explain_consequences(self) -> None:
        """Explain consequences of private key loss or compromise"""
        print("\n ⚠️  CONSEQUENCES OF KEY COMPROMISE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  PRIVATE KEY COMPROMISE CONSEQUENCES                      │
├─────────────────────────────────────────────────────────────┤
│   LOST PRIVATE KEY:                                     │
│     • All funds become permanently inaccessible          │
│     • No recovery mechanism exists                       │
│     • No customer support can help                       │
│     • Funds are lost forever                             │
│     • No "forgot password" option                        │
│                                                           │
│   STOLEN PRIVATE KEY:                                   │
│     • Immediate loss of all funds                        │
│     • Transaction authorization without consent          │
│     • Identity theft possible                            │
│     • Irreversible transactions                          │
│     • No recourse or chargeback                          │
│                                                           │
│   EXPOSED PRIVATE KEY:                                   │
│     • Permanent security compromise                      │
│     • Need to immediately move funds                     │
│     • Generate new key pair                              │
│     • Update all related services                        │
│     • Monitor for unauthorized activity                  │
│                                                           │
│   MEMORIZED PRIVATE KEY:                                │
│     • Risk of forgetting                                 │
│     • Security through obscurity                         │
│     • Not recommended                                    │
│     • Better to use hardware wallet                      │
└─────────────────────────────────────────────────────────────┘
        """)

class PrivateKeyAnalytics:
    """Additional analysis tools for private keys"""
    
    @staticmethod
    def analyze_key_strength() -> None:
        """Analyze strength characteristics of private keys"""
        print("\n 📊 KEY STRENGTH ANALYSIS")
        print("-" * 40)
        
        strength_metrics = {
            "Entropy": "256 bits",
            "Key Space": "2^256",
            "Brute Force Time": "~10^68 years",
            "Quantum Resistance": "Post-quantum challenge",
            "Collision Probability": "~1/10^77",
            "Security Standard": "NIST Level V"
        }
        
        print(" 💪 Cryptographic Strength Metrics:")
        for metric, value in strength_metrics.items():
            print(f"   • {metric}: {value}")
        
        print("\n 🔒 Comparison:")
        print("   • 2^256 is more than the number of atoms in the observable universe")
        print("   • Brute force attack: Impossible with current technology")
        print("   • Quantum computing: Estimated 10-20 years to become threat")
    
    @staticmethod
    def compare_key_formats() -> None:
        """Compare different private key formats"""
        print("\n 📋 KEY FORMAT COMPARISON")
        print("-" * 40)
        
        formats = {
            "Hex": {
                "chars": 64,
                "readability": "Low",
                "usage": "Development",
                "example": "0x7a9b3c8d2e1f4g5h6i7j8k9l0m1n2o3p4q5r6s7t8u9v0w"
            },
            "WIF": {
                "chars": 52,
                "readability": "Medium",
                "usage": "Wallet Import",
                "example": "L5aXKjZ5kCZN8TQqgkLmYbM4YvZz3aYyxZqMnPjRxQvHw"
            },
            "Mnemonic": {
                "chars": 60-80,
                "readability": "High",
                "usage": "Backup & Recovery",
                "example": "abandon ability able about above absent absorb"
            }
        }
        
        print(f" {'Format':>12} | {'Characters':>10} | {'Readability':>12} | {'Primary Usage':>15}")
        print("-" * 60)
        
        for format_name, details in formats.items():
            print(f" {format_name:>12} | {details['chars']:>10} | {details['readability']:>12} | "
                  f"{details['usage']:>15}")

def demonstrate_private_key_system():
    """Execute comprehensive private key demonstration"""
    print("=" * 60)
    print(" PRIVATE KEY MANAGEMENT FRAMEWORK DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = PrivateKeyManagementEngine()
    
    # Generate key
    key_data = engine.generate_secure_private_key()
    
    # Show security implications
    engine.demonstrate_security_implications()
    engine.explain_consequences()
    
    # Additional analytics
    PrivateKeyAnalytics.analyze_key_strength()
    PrivateKeyAnalytics.compare_key_formats()
    
    print("\n" + "=" * 60)
    print(" PRIVATE KEY SUMMARY:")
    print("   ✓ 256-bit cryptographically secure random number")
    print("   ✓ Controls cryptocurrency ownership")
    print("   ✓ Used to authorize transactions")
    print("   ✓ Must be kept ABSOLUTELY SECRET")
    print("   ✓ NEVER share or expose private key")
    print("   ✓ Formats: Hex, WIF, Mnemonic")
    print("   ✓ Lost key = Lost funds forever")
    print("   ✓ Hardware wallet recommended for storage")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_private_key_system()

3.7 Public Keys

What is a Public Key?

A public key is derived from a private key using elliptic curve multiplication. It’s shared openly and used to receive funds and verify signatures. The public key is the mathematical derivation of the private key—it’s generated through a one-way function that cannot be reversed.

How Public Keys Work:

Derivation:
Public Key = Private Key × Generator Point (on elliptic curve)

This mathematical operation is a one-way function. While it’s easy to compute the public key from the private key, it’s computationally impossible to compute the private key from the public key. This principle forms the mathematical foundation of elliptic curve cryptography (ECC).

Public Key Formats:

FormatPrefixSizeDescriptionUse Case
Uncompressed0x0465 bytesFull x and y coordinatesLegacy systems
Compressed0x02/0x0333 bytesx coordinate + parityModern wallets
HexVariesVariesHexadecimal representationDevelopment

Why Compressed Public Keys?

Compressed public keys are smaller (33 bytes vs 65 bytes) and more efficient to store and transmit. The compression is possible because elliptic curve points satisfy the curve equation, so you can calculate y from x (with a parity bit).

Public Key to Address:

  1. Public Key → SHA-256 → RIPEMD-160 → Address
  2. Public Key → Keccak-256 → Address (Ethereum)

Code Example – Public Keys:

"""
PUBLIC KEY CRYPTOGRAPHIC FRAMEWORK
==================================
Complete public key derivation, formatting, and address generation demonstration
"""

import hashlib
import base58
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
from typing import Tuple, Optional
from dataclasses import dataclass

@dataclass
class PublicKeyData:
    """Represents a public key in various formats"""
    uncompressed_bytes: bytes
    compressed_bytes: bytes
    uncompressed_hex: str
    compressed_hex: str
    bitcoin_address: str
    ethereum_address: str
    key_type: str

@dataclass
class AddressGeneration:
    """Represents the address generation process"""
    step_name: str
    input_data: str
    output_data: str
    description: str

class PublicKeyDerivationEngine:
    """Comprehensive public key demonstration and management suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" PUBLIC KEY DERIVATION ENGINE")
        print("=" * 60)
    
    def derive_public_key(self, private_key: Optional[ec.EllipticCurvePrivateKey] = None) -> PublicKeyData:
        """Derive public key from private key or generate new key pair"""
        print("\n 🔑 PUBLIC KEY DERIVATION")
        print("-" * 40)
        
        # Generate or use provided private key
        if private_key is None:
            private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        
        public_key = private_key.public_key()
        print("✅ Private key processed successfully")
        
        # Get public key in different formats
        uncompressed_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.UncompressedPoint
        )
        
        compressed_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.CompressedPoint
        )
        
        # Generate addresses
        btc_address = self._generate_bitcoin_address(public_key)
        eth_address = self._generate_ethereum_address(public_key)
        
        print(f"\n 📊 Public Key Formats:")
        print(f"  • Uncompressed: {uncompressed_bytes[:20]}... ({len(uncompressed_bytes)} bytes)")
        print(f"  • Compressed:   {compressed_bytes[:20]}... ({len(compressed_bytes)} bytes)")
        print(f"  • Hex (Uncompressed): {uncompressed_bytes.hex()[:32]}...")
        print(f"  • Hex (Compressed):   {compressed_bytes.hex()[:32]}...")
        print(f"\n 💡 Compressed keys are more efficient (33 vs 65 bytes)")
        print(f"    Both formats represent the same mathematical point")
        
        return PublicKeyData(
            uncompressed_bytes=uncompressed_bytes,
            compressed_bytes=compressed_bytes,
            uncompressed_hex=uncompressed_bytes.hex(),
            compressed_hex=compressed_bytes.hex(),
            bitcoin_address=btc_address,
            ethereum_address=eth_address,
            key_type="SECP256K1"
        )
    
    def _generate_bitcoin_address(self, public_key: ec.EllipticCurvePublicKey) -> str:
        """Generate Bitcoin-style P2PKH address"""
        # Get compressed public key
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.CompressedPoint
        )
        
        # SHA-256 hash
        sha_hash = hashlib.sha256(public_bytes).digest()
        
        # RIPEMD-160 hash
        ripemd_hash = hashlib.new('ripemd160', sha_hash).digest()
        
        # Add version byte (0x00 for Bitcoin mainnet)
        versioned_payload = b'\x00' + ripemd_hash
        
        # Calculate checksum (double SHA-256)
        checksum = hashlib.sha256(hashlib.sha256(versioned_payload).digest()).digest()[:4]
        
        # Base58 encode
        return base58.b58encode(versioned_payload + checksum).decode()
    
    def _generate_ethereum_address(self, public_key: ec.EllipticCurvePublicKey) -> str:
        """Generate Ethereum-style address"""
        # Get uncompressed public key (remove 0x04 prefix)
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.UncompressedPoint
        )
        
        # Remove the 0x04 prefix
        public_key_no_prefix = public_bytes[1:]
        
        # Keccak-256 hash (using SHA-3 for demonstration)
        keccak_hash = hashlib.sha3_256(public_key_no_prefix).digest()
        
        # Take last 20 bytes
        address = f"0x{keccak_hash[-20:].hex()}"
        
        return address
    
    def demonstrate_address_generation_process(self) -> None:
        """Show detailed address generation steps"""
        print("\n 📋 ADDRESS GENERATION PROCESS")
        print("-" * 40)
        
        # Generate a key pair for demonstration
        private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        public_key = private_key.public_key()
        
        print("🔹 Bitcoin Address Generation:")
        process_steps = [
            AddressGeneration(
                step_name="Step 1: SHA-256",
                input_data="Public Key (33 bytes)",
                output_data="32-byte hash",
                description="First cryptographic hash"
            ),
            AddressGeneration(
                step_name="Step 2: RIPEMD-160",
                input_data="SHA-256 hash (32 bytes)",
                output_data="20-byte hash",
                description="Second hash for address shortening"
            ),
            AddressGeneration(
                step_name="Step 3: Add Version",
                input_data="RIPEMD-160 hash (20 bytes)",
                output_data="21-byte payload",
                description="0x00 for Bitcoin mainnet"
            ),
            AddressGeneration(
                step_name="Step 4: Checksum",
                input_data="Versioned payload (21 bytes)",
                output_data="4-byte checksum",
                description="Double SHA-256 first 4 bytes"
            ),
            AddressGeneration(
                step_name="Step 5: Base58 Encode",
                input_data="Payload + checksum (25 bytes)",
                output_data="Base58 address",
                description="Human-readable format"
            )
        ]
        
        print("\n Address Generation Flow:")
        for step in process_steps:
            print(f"  → {step.step_name}: {step.description}")
            print(f"    Input: {step.input_data} → Output: {step.output_data}")
        
        # Generate actual address
        btc_address = self._generate_bitcoin_address(public_key)
        print(f"\n ✅ Resulting Address: {btc_address}")
    
    def explain_public_key_properties(self) -> None:
        """Explain key properties of public keys"""
        print("\n 🔍 PUBLIC KEY PROPERTIES")
        print("-" * 40)
        
        properties = {
            "Mathematical Foundation": {
                "description": "Based on elliptic curve cryptography",
                "importance": "Provides security foundation",
                "curve": "SECP256K1 (Bitcoin/Ethereum standard)"
            },
            "Derivation": {
                "description": "Derived from private key",
                "importance": "No way to derive private key from public",
                "security": "One-way function"
            },
            "Sharing": {
                "description": "Safe to share publicly",
                "importance": "Enables address generation",
                "usage": "Receive funds, verify signatures"
            },
            "Formats": {
                "description": "Multiple representations",
                "importance": "Different use cases",
                "examples": "Compressed, uncompressed, hex"
            }
        }
        
        print(" 📊 Cryptographic Properties:")
        for prop_name, details in properties.items():
            print(f"\n  {prop_name}:")
            print(f"    • Description: {details['description']}")
            print(f"    • Importance: {details['importance']}")
            if 'curve' in details:
                print(f"    • Curve: {details['curve']}")
            if 'security' in details:
                print(f"    • Security: {details['security']}")
            if 'usage' in details:
                print(f"    • Usage: {details['usage']}")
            if 'examples' in details:
                print(f"    • Examples: {details['examples']}")

class PublicKeyAnalytics:
    """Additional analysis tools for public keys"""
    
    @staticmethod
    def compare_address_formats() -> None:
        """Compare different address formats"""
        print("\n 📊 ADDRESS FORMAT COMPARISON")
        print("-" * 40)
        
        formats = {
            "P2PKH (Bitcoin)": {
                "prefix": "1",
                "length": "26-35 chars",
                "encoding": "Base58Check",
                "usage": "Most common Bitcoin address"
            },
            "P2SH (Bitcoin)": {
                "prefix": "3",
                "length": "26-35 chars",
                "encoding": "Base58Check",
                "usage": "Multi-signature and SegWit"
            },
            "Bech32 (Bitcoin)": {
                "prefix": "bc1",
                "length": "42 chars",
                "encoding": "Bech32",
                "usage": "SegWit native"
            },
            "Ethereum": {
                "prefix": "0x",
                "length": "42 chars",
                "encoding": "Hex",
                "usage": "Ethereum accounts"
            }
        }
        
        print(f" {'Format':>15} | {'Prefix':>10} | {'Length':>12} | {'Encoding':>15} | {'Usage':>20}")
        print("-" * 80)
        
        for format_name, details in formats.items():
            print(f" {format_name:>15} | {details['prefix']:>10} | {details['length']:>12} | "
                  f"{details['encoding']:>15} | {details['usage']:>20}")
    
    @staticmethod
    def analyze_key_derivation() -> None:
        """Explain key derivation process"""
        print("\n 🔄 KEY DERIVATION ANALYSIS")
        print("-" * 40)
        
        derivation_process = [
            ("1. Random Generation", "Private Key (256-bit)"),
            ("2. Elliptic Curve Multiplication", "Public Key Point (x, y)"),
            ("3. Format Selection", "Compressed or Uncompressed"),
            ("4. Hashing", "SHA-256 → RIPEMD-160 (Bitcoin) or Keccak (Ethereum)"),
            ("5. Address Encoding", "Base58Check or Hex"),
            ("6. Final Address", "Wallet Address")
        ]
        
        print(" 📋 Derivation Chain:")
        for step_num, (step_name, result) in enumerate(derivation_process, 1):
            print(f"  {step_num}. {step_name:<25} → {result}")

def demonstrate_public_key_system():
    """Execute comprehensive public key demonstration"""
    print("=" * 60)
    print(" PUBLIC KEY DERIVATION FRAMEWORK DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = PublicKeyDerivationEngine()
    
    # Derive public key
    public_key_data = engine.derive_public_key()
    
    # Show address generation process
    engine.demonstrate_address_generation_process()
    engine.explain_public_key_properties()
    
    # Additional analytics
    PublicKeyAnalytics.compare_address_formats()
    PublicKeyAnalytics.analyze_key_derivation()
    
    print("\n" + "=" * 60)
    print(" PUBLIC KEY SUMMARY:")
    print("   ✓ Derived from private key (elliptic curve multiplication)")
    print("   ✓ Safe to share openly")
    print("   ✓ Used to receive funds")
    print("   ✓ Used to verify digital signatures")
    print("   ✓ Formats: Compressed (33 bytes) and Uncompressed (65 bytes)")
    print("   ✓ Address Generation: SHA-256 → RIPEMD-160 (Bitcoin)")
    print("   ✓ Address Generation: Keccak-256 (Ethereum)")
    print("   ✓ Cannot derive private key from public key (one-way)")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_public_key_system()

3.8 Wallet Addresses

What is a Wallet Address?

A wallet address is a shorter, more user-friendly representation of a public key. It’s what you share with others to receive cryptocurrency. The address is derived from the public key through a series of hashing steps.

Why Addresses Instead of Public Keys?

ReasonExplanation
LengthAddresses are shorter (34 vs 65 bytes)
Error DetectionChecksums help catch typos
ReadabilityEasier to copy and share
PrivacyDifferent addresses from same public key
CompatibilityStandardized format

Address Formats by Blockchain:

BlockchainFormatExampleChecksum
BitcoinBase58Check1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNaYes
Bitcoin (SegWit)Bech32bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdqYes
EthereumHex + 0x0x742d35Cc6634C0532925a3b844Bc454e4438f44eEIP-55
SolanaBase589WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWVHNo

Address Generation Process:

Bitcoin Address Generation:

Private Key → Public Key → SHA-256 → RIPEMD-160 → Add Version Byte → Base58 Encode

Ethereum Address Generation:

Private Key → Public Key → Keccak-256 → Take Last 20 Bytes → Add 0x Prefix

Checksums:

Bitcoin (Base58Check):

  • First 4 bytes of double SHA-256 are appended
  • Ensures typo detection
  • Invalid addresses are rejected

Ethereum (EIP-55):

  • Mixed case address
  • Checksum in uppercase letters
  • Invalid if checksum doesn’t match
  • Case-insensitive software

Code Example – Wallet Addresses:

"""
CRYPTOGRAPHIC ADDRESS GENERATION FRAMEWORK
==========================================
Complete wallet address generation for Bitcoin, Ethereum, and other blockchain networks
"""

import hashlib
import base58
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
from typing import Dict, List, Tuple, Optional
from dataclasses import dataclass

@dataclass
class AddressData:
    """Represents a wallet address with all relevant information"""
    address: str
    address_type: str
    format_type: str
    length: int
    checksum: str
    network: str

@dataclass
class AddressGenerationStep:
    """Represents a step in the address generation process"""
    step_name: str
    description: str
    input_data: str
    output_data: str
    algorithm: str

class AddressGenerationEngine:
    """Comprehensive wallet address generation and management suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOGRAPHIC ADDRESS GENERATION ENGINE")
        print("=" * 60)
    
    def generate_key_pair(self) -> ec.EllipticCurvePublicKey:
        """Generate a key pair for address generation"""
        private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        public_key = private_key.public_key()
        return public_key
    
    def generate_bitcoin_p2pkh(self, public_key: ec.EllipticCurvePublicKey) -> AddressData:
        """Generate Bitcoin P2PKH address (Legacy)"""
        print("\n 🪙 BITCOIN P2PKH ADDRESS (Legacy)")
        print("-" * 40)
        
        # Get compressed public key
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.CompressedPoint
        )
        
        # Generate hash chain
        sha_hash = hashlib.sha256(public_bytes).digest()
        ripemd_hash = hashlib.new('ripemd160', sha_hash).digest()
        
        # Add version byte (0x00 for Bitcoin mainnet)
        versioned_payload = b'\x00' + ripemd_hash
        
        # Calculate checksum
        checksum = hashlib.sha256(hashlib.sha256(versioned_payload).digest()).digest()[:4]
        
        # Encode with Base58Check
        address = base58.b58encode(versioned_payload + checksum).decode()
        
        print(f"📝 Generation Steps:")
        print(f"  • Public Key (compressed): {public_bytes[:20]}...")
        print(f"  • SHA-256: {sha_hash[:16]}...")
        print(f"  • RIPEMD-160: {ripemd_hash[:16]}...")
        print(f"  • Checksum: {checksum.hex()[:8]}...")
        print(f"\n✅ Address: {address}")
        
        return AddressData(
            address=address,
            address_type="P2PKH",
            format_type="Base58Check",
            length=len(address),
            checksum=checksum.hex(),
            network="Bitcoin Mainnet"
        )
    
    def generate_bitcoin_bech32(self, public_key: ec.EllipticCurvePublicKey) -> AddressData:
        """Generate Bitcoin Bech32 address (SegWit)"""
        print("\n ⚡ BITCOIN SEGWIT ADDRESS (Bech32)")
        print("-" * 40)
        
        # Get compressed public key
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.CompressedPoint
        )
        
        # Generate hash chain
        sha_hash = hashlib.sha256(public_bytes).digest()
        ripemd_hash = hashlib.new('ripemd160', sha_hash).digest()
        
        # Witness program (version 0 + 20-byte hash)
        witness_program = b'\x00' + ripemd_hash
        
        # Bech32 encoding (simplified for demonstration)
        bech32_data = base58.b58encode(witness_program).decode()
        address = f"bc1{bech32_data[:40]}"
        
        print(f"📝 Generation Steps:")
        print(f"  • Public Key: {public_bytes[:20]}...")
        print(f"  • Witness Program: version=0, hash={ripemd_hash[:16]}...")
        print(f"\n✅ Address: {address}")
        
        return AddressData(
            address=address,
            address_type="Bech32 (SegWit)",
            format_type="Bech32",
            length=len(address),
            checksum="Bech32 checksum",
            network="Bitcoin Mainnet"
        )
    
    def generate_ethereum_address(self, public_key: ec.EllipticCurvePublicKey) -> AddressData:
        """Generate Ethereum address with EIP-55 checksum"""
        print("\n 💎 ETHEREUM ADDRESS (EIP-55)")
        print("-" * 40)
        
        # Get uncompressed public key (remove 0x04 prefix)
        public_bytes = public_key.public_bytes(
            encoding=serialization.Encoding.X962,
            format=serialization.PublicFormat.UncompressedPoint
        )
        
        # Keccak-256 hash
        keccak_hash = hashlib.sha3_256(public_bytes[1:]).digest()
        
        # Take last 20 bytes
        raw_address = keccak_hash[-20:].hex()
        base_address = f"0x{raw_address}"
        
        # Apply EIP-55 checksum
        checksum_address = self._apply_eip55_checksum(base_address)
        
        print(f"📝 Generation Steps:")
        print(f"  • Public Key: {public_bytes[:20]}...")
        print(f"  • Keccak-256: {keccak_hash[:16]}...")
        print(f"  • Raw Address: {base_address}")
        print(f"\n✅ Checksum Address: {checksum_address}")
        
        return AddressData(
            address=checksum_address,
            address_type="EOA (Externally Owned Account)",
            format_type="Hex + 0x + Checksum",
            length=len(checksum_address),
            checksum="EIP-55",
            network="Ethereum Mainnet"
        )
    
    def _apply_eip55_checksum(self, address: str) -> str:
        """Apply EIP-55 checksum to Ethereum address"""
        # Remove 0x prefix
        addr = address.replace('0x', '')
        
        # Hash lowercase address
        hash_value = hashlib.sha3_256(addr.lower().encode()).hexdigest()
        
        # Apply checksum
        checksum_addr = '0x'
        for i, char in enumerate(addr):
            if int(hash_value[i], 16) >= 8:
                checksum_addr += char.upper()
            else:
                checksum_addr += char.lower()
        
        return checksum_addr
    
    def demonstrate_address_generation_process(self, public_key: ec.EllipticCurvePublicKey) -> None:
        """Show detailed address generation process"""
        print("\n 📋 ADDRESS GENERATION PROCESS DETAIL")
        print("-" * 40)
        
        # Bitcoin process
        print("\n🔹 Bitcoin Address Generation Process:")
        bitcoin_steps = [
            AddressGenerationStep(
                step_name="Step 1: Public Key",
                description="Derive from private key",
                input_data="Private Key",
                output_data="Public Key (33/65 bytes)",
                algorithm="ECDSA (SECP256K1)"
            ),
            AddressGenerationStep(
                step_name="Step 2: SHA-256",
                description="First cryptographic hash",
                input_data="Public Key",
                output_data="32-byte hash",
                algorithm="SHA-256"
            ),
            AddressGenerationStep(
                step_name="Step 3: RIPEMD-160",
                description="Second hash for address shortening",
                input_data="SHA-256 hash",
                output_data="20-byte hash",
                algorithm="RIPEMD-160"
            ),
            AddressGenerationStep(
                step_name="Step 4: Add Version",
                description="Network identifier",
                input_data="20-byte hash",
                output_data="21-byte payload",
                algorithm="Version byte"
            ),
            AddressGenerationStep(
                step_name="Step 5: Checksum",
                description="Error detection",
                input_data="21-byte payload",
                output_data="4-byte checksum",
                algorithm="Double SHA-256"
            ),
            AddressGenerationStep(
                step_name="Step 6: Base58",
                description="Human-readable encoding",
                input_data="25-byte payload",
                output_data="Base58 address",
                algorithm="Base58Check"
            )
        ]
        
        for step in bitcoin_steps:
            print(f"  → {step.step_name}: {step.description}")
        
        # Ethereum process
        print("\n🔹 Ethereum Address Generation Process:")
        eth_steps = [
            AddressGenerationStep(
                step_name="Step 1: Public Key",
                description="Derive from private key",
                input_data="Private Key",
                output_data="Public Key (65 bytes)",
                algorithm="ECDSA (SECP256K1)"
            ),
            AddressGenerationStep(
                step_name="Step 2: Remove Prefix",
                description="Remove 0x04 prefix",
                input_data="Public Key (65 bytes)",
                output_data="64-byte key",
                algorithm="Byte manipulation"
            ),
            AddressGenerationStep(
                step_name="Step 3: Keccak-256",
                description="Cryptographic hash",
                input_data="64-byte public key",
                output_data="32-byte hash",
                algorithm="Keccak-256"
            ),
            AddressGenerationStep(
                step_name="Step 4: Extract Last 20",
                description="Take last 20 bytes",
                input_data="32-byte hash",
                output_data="20-byte address",
                algorithm="Byte extraction"
            ),
            AddressGenerationStep(
                step_name="Step 5: EIP-55 Checksum",
                description="Add checksum validation",
                input_data="20-byte address",
                output_data="Checksummed address",
                algorithm="EIP-55"
            )
        ]
        
        for step in eth_steps:
            print(f"  → {step.step_name}: {step.description}")

class AddressAnalytics:
    """Additional analysis tools for wallet addresses"""
    
    @staticmethod
    def compare_address_formats() -> None:
        """Compare different address formats and standards"""
        print("\n 📊 ADDRESS FORMAT COMPARISON")
        print("-" * 40)
        
        formats = {
            "P2PKH (Legacy)": {
                "prefix": "1",
                "length": "26-35",
                "encoding": "Base58Check",
                "security": "Medium",
                "gas_costs": "Highest"
            },
            "P2SH (Script)": {
                "prefix": "3",
                "length": "26-35",
                "encoding": "Base58Check",
                "security": "Medium",
                "gas_costs": "Medium"
            },
            "Bech32 (SegWit)": {
                "prefix": "bc1",
                "length": "42",
                "encoding": "Bech32",
                "security": "High",
                "gas_costs": "Low"
            },
            "Ethereum": {
                "prefix": "0x",
                "length": "42",
                "encoding": "Hex",
                "security": "High",
                "gas_costs": "Standard"
            }
        }
        
        print(f" {'Format':>15} | {'Prefix':>10} | {'Length':>10} | {'Encoding':>15} | {'Security':>10} | {'Cost':>12}")
        print("-" * 80)
        
        for format_name, details in formats.items():
            print(f" {format_name:>15} | {details['prefix']:>10} | {details['length']:>10} | "
                  f"{details['encoding']:>15} | {details['security']:>10} | {details['gas_costs']:>12}")
    
    @staticmethod
    def analyze_address_security() -> None:
        """Analyze address security features"""
        print("\n 🛡️ ADDRESS SECURITY ANALYSIS")
        print("-" * 40)
        
        security_features = {
            "Checksum Validation": {
                "Bitcoin": "✅ Yes (Base58Check)",
                "Ethereum": "✅ Yes (EIP-55)"
            },
            "Human Readability": {
                "Bitcoin": "✅ Medium",
                "Ethereum": "✅ Medium"
            },
            "Error Detection": {
                "Bitcoin": "✅ High (99.9%)",
                "Ethereum": "✅ High (EIP-55)"
            },
            "Collision Resistance": {
                "Bitcoin": "✅ Very High",
                "Ethereum": "✅ Very High"
            }
        }
        
        print(" 📊 Security Feature Matrix:")
        print(f" {'Feature':>20} | {'Bitcoin':>15} | {'Ethereum':>15}")
        print("-" * 55)
        
        for feature, values in security_features.items():
            btc_value = values.get("Bitcoin", "❌ Not Applicable")
            eth_value = values.get("Ethereum", "❌ Not Applicable")
            print(f" {feature:>20} | {btc_value:>15} | {eth_value:>15}")

def demonstrate_address_system():
    """Execute comprehensive address generation demonstration"""
    print("=" * 60)
    print(" CRYPTOGRAPHIC ADDRESS GENERATION DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = AddressGenerationEngine()
    
    # Generate public key
    public_key = engine.generate_key_pair()
    
    # Generate addresses
    print("\n 🏗️  Generating Addresses...")
    btc_p2pkh = engine.generate_bitcoin_p2pkh(public_key)
    btc_bech32 = engine.generate_bitcoin_bech32(public_key)
    eth_address = engine.generate_ethereum_address(public_key)
    
    # Show detailed process
    engine.demonstrate_address_generation_process(public_key)
    
    # Additional analytics
    AddressAnalytics.compare_address_formats()
    AddressAnalytics.analyze_address_security()
    
    print("\n" + "=" * 60)
    print(" ADDRESS GENERATION SUMMARY:")
    print("   ✓ Bitcoin P2PKH: Base58Check, starts with '1'")
    print("   ✓ Bitcoin SegWit: Bech32, starts with 'bc1'")
    print("   ✓ Ethereum: Hex + 0x, EIP-55 checksum")
    print("   ✓ All addresses are derived from public keys")
    print("   ✓ Checksums prevent typing errors")
    print("   ✓ Addresses are shorter and more user-friendly")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_address_system()

3.9 Digital Signatures

What is a Digital Signature?

A digital signature is a mathematical scheme that proves the authenticity of a message. Signing a message with a private key creates a signature that can be verified with the corresponding public key. Digital signatures are the foundation of transaction authorization in blockchain.

How Digital Signatures Work:

1. Signing Process:

  • The signer has a private key
  • The message is hashed
  • The hash is encrypted with the private key
  • The signature is attached to the message

2. Verification Process:

  • The verifier has the public key
  • The message and signature are received
  • The message is hashed
  • The signature is decrypted with the public key
  • The hashes are compared
  • If they match, the signature is valid

Properties of Digital Signatures:

PropertyDescriptionImportance
AuthenticityProves signer’s identityVerifies who signed
IntegrityMessage not alteredDetects tampering
Non-RepudiationSigner can’t deny signingLegal proof

Applications in Blockchain:

ApplicationHow It WorksPurpose
Transaction SigningPrivate key signs transactionProve ownership
Identity VerificationPublic key verifies signatureAuthenticate user
AuthorizationSignatures authorize actionsSecurity

Code Example – Digital Signatures:

"""
DIGITAL SIGNATURE FRAMEWORK
===========================
Complete implementation of cryptographic signatures with ECDSA and blockchain applications
"""

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
import hashlib
import time
from typing import Tuple, Optional
from dataclasses import dataclass

@dataclass
class SignatureData:
    """Represents a signature with verification details"""
    message: bytes
    signature: bytes
    is_valid: bool
    verification_time: float
    signature_size: int
    algorithm: str

@dataclass
class TransactionSignature:
    """Represents a signed blockchain transaction"""
    transaction_data: dict
    signature: bytes
    public_key_hex: str
    timestamp: float
    is_validated: bool

class DigitalSignatureEngine:
    """Complete digital signature implementation and demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" DIGITAL SIGNATURE ENGINE")
        print("=" * 60)
    
    def generate_key_pair(self) -> Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]:
        """Generate ECDSA key pair using SECP256K1 curve"""
        private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        public_key = private_key.public_key()
        return private_key, public_key
    
    def create_signature(self, private_key: ec.EllipticCurvePrivateKey, 
                        message: bytes) -> SignatureData:
        """Create a digital signature for a message"""
        print("\n ✍️  CREATING DIGITAL SIGNATURE")
        print("-" * 40)
        
        print(f"📝 Message: {message.decode() if message.isascii() else 'Binary data'}")
        
        start_time = time.time()
        signature = private_key.sign(
            message,
            ec.ECDSA(hashes.SHA256())
        )
        elapsed = time.time() - start_time
        
        print(f"🔑 Signature: {signature.hex()[:32]}...")
        print(f"📏 Signature Size: {len(signature)} bytes")
        print(f"⏱️  Signing Time: {elapsed:.4f}s")
        print(f"🔐 Algorithm: ECDSA (SECP256K1 + SHA-256)")
        
        return SignatureData(
            message=message,
            signature=signature,
            is_valid=True,
            verification_time=elapsed,
            signature_size=len(signature),
            algorithm="ECDSA-SHA256"
        )
    
    def verify_signature(self, public_key: ec.EllipticCurvePublicKey,
                        signature_data: SignatureData) -> bool:
        """Verify a digital signature"""
        print("\n ✅ VERIFYING SIGNATURE")
        print("-" * 40)
        
        start_time = time.time()
        
        try:
            public_key.verify(
                signature_data.signature,
                signature_data.message,
                ec.ECDSA(hashes.SHA256())
            )
            elapsed = time.time() - start_time
            print(f"✅ Signature is VALID")
            print(f"⏱️  Verification Time: {elapsed:.4f}s")
            signature_data.verification_time = elapsed
            signature_data.is_valid = True
            return True
            
        except Exception as e:
            elapsed = time.time() - start_time
            print(f"❌ Signature is INVALID")
            print(f"⏱️  Verification Time: {elapsed:.4f}s")
            print(f"⚠️  Error: {str(e)}")
            signature_data.verification_time = elapsed
            signature_data.is_valid = False
            return False
    
    def demonstrate_tamper_detection(self, private_key: ec.EllipticCurvePrivateKey,
                                     public_key: ec.EllipticCurvePublicKey) -> None:
        """Show how signatures detect message tampering"""
        print("\n 🛡️  TAMPER DETECTION DEMONSTRATION")
        print("-" * 40)
        
        # Original message
        original_message = b"Transfer 100 tokens to Account 0xABC123"
        print(f"📝 Original Message: {original_message.decode()}")
        
        # Create signature
        signature_data = self.create_signature(private_key, original_message)
        
        # Verify original
        print("\n🔍 Verifying original message:")
        self.verify_signature(public_key, signature_data)
        
        # Tampered message
        tampered_message = b"Transfer 1000 tokens to Account 0xABC123"
        print(f"\n⚠️  Tampered Message: {tampered_message.decode()}")
        
        # Try to verify tampered message with original signature
        tampered_data = SignatureData(
            message=tampered_message,
            signature=signature_data.signature,
            is_valid=False,
            verification_time=0,
            signature_size=len(signature_data.signature),
            algorithm=signature_data.algorithm
        )
        
        print("\n🔍 Verifying tampered message:")
        self.verify_signature(public_key, tampered_data)
        
        print("\n💡 Conclusion: Signatures detect any tampering!")
    
    def simulate_blockchain_transaction(self) -> None:
        """Simulate a complete blockchain transaction signing and verification flow"""
        print("\n ⛓️  BLOCKCHAIN TRANSACTION SIMULATION")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BLOCKCHAIN TRANSACTION FLOW                              │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1. USER CREATES TRANSACTION                              │
│     • Sender: Alice                                        │
│     • Recipient: Bob                                       │
│     • Amount: 10 tokens                                    │
│     • Nonce: 5                                             │
│                                                           │
│  2. TRANSACTION HASHING                                   │
│     • Hash transaction data                                │
│     • Creates unique identifier                            │
│                                                           │
│  3. SIGNING WITH PRIVATE KEY                             │
│     • Alice signs with her private key                    │
│     • Creates ECDSA signature                              │
│                                                           │
│  4. BROADCAST TO NETWORK                                  │
│     • Transaction + Signature sent to nodes              │
│     • Added to mempool                                     │
│                                                           │
│  5. NETWORK VERIFICATION                                  │
│     • Nodes verify signature with Alice's public key     │
│     • Check balance and nonce                             │
│                                                           │
│  6. INCLUSION IN BLOCK                                    │
│     • Valid transaction selected by miner                │
│     • Added to new block                                  │
│     • Broadcast to network                                 │
│                                                           │
│  7. CONFIRMATION                                           │
│     • Block receives confirmations                        │
│     • Transaction becomes final                           │
│                                                           │
│  SECURITY PROPERTIES:                                     │
│  • Authenticity: Only Alice could have signed             │
│  • Integrity: Transaction can't be altered                │
│  • Non-repudiation: Alice can't deny signing              │
└─────────────────────────────────────────────────────────────┘
        """)
        
        # Simulate actual signing
        print("\n🔐 Simulating transaction signing:")
        private_key, public_key = self.generate_key_pair()
        
        transaction = {
            "from": "Alice",
            "to": "Bob",
            "amount": 10,
            "nonce": 5
        }
        
        tx_hash = hashlib.sha256(str(transaction).encode()).digest()
        signature = private_key.sign(tx_hash, ec.ECDSA(hashes.SHA256()))
        
        print(f"  Transaction: {transaction}")
        print(f"  Transaction Hash: {tx_hash.hex()[:16]}...")
        print(f"  Signature: {signature.hex()[:32]}...")
        
        # Verify
        try:
            public_key.verify(signature, tx_hash, ec.ECDSA(hashes.SHA256()))
            print("  ✅ Transaction verified successfully!")
        except:
            print("  ❌ Transaction verification failed!")

class SignatureAnalytics:
    """Additional analysis tools for digital signatures"""
    
    @staticmethod
    def compare_signature_algorithms() -> None:
        """Compare different signature algorithms"""
        print("\n 📊 SIGNATURE ALGORITHM COMPARISON")
        print("-" * 40)
        
        algorithms = {
            "ECDSA (SECP256K1)": {
                "key_size": "256-bit",
                "signature_size": "~64-72 bytes",
                "speed": "Fast",
                "usage": "Bitcoin, Ethereum"
            },
            "ECDSA (SECP256R1)": {
                "key_size": "256-bit",
                "signature_size": "~64-72 bytes",
                "speed": "Fast",
                "usage": "NIST standard"
            },
            "Ed25519": {
                "key_size": "256-bit",
                "signature_size": "64 bytes",
                "speed": "Very Fast",
                "usage": "Solana, Zcash"
            },
            "RSA-2048": {
                "key_size": "2048-bit",
                "signature_size": "~256 bytes",
                "speed": "Slow",
                "usage": "Traditional PKI"
            }
        }
        
        print(f" {'Algorithm':>20} | {'Key Size':>12} | {'Sig Size':>12} | {'Speed':>10} | {'Usage':>15}")
        print("-" * 75)
        
        for name, details in algorithms.items():
            print(f" {name:>20} | {details['key_size']:>12} | {details['signature_size']:>12} | "
                  f"{details['speed']:>10} | {details['usage']:>15}")
    
    @staticmethod
    def analyze_signature_security() -> None:
        """Analyze signature security properties"""
        print("\n 🛡️  SIGNATURE SECURITY ANALYSIS")
        print("-" * 40)
        
        security_properties = {
            "Authentication": {
                "description": "Proves message origin",
                "importance": "High",
                "implementation": "Public key verification"
            },
            "Integrity": {
                "description": "Detects tampering",
                "importance": "Critical",
                "implementation": "Hash comparison"
            },
            "Non-repudiation": {
                "description": "Cannot deny signing",
                "importance": "High",
                "implementation": "Private key binding"
            },
            "Forward Secrecy": {
                "description": "Past signatures remain secure",
                "importance": "Medium",
                "implementation": "Unique per signature"
            }
        }
        
        print("\n 📊 Security Properties:")
        for prop, details in security_properties.items():
            print(f"  • {prop}: {details['description']}")
            print(f"    Importance: {details['importance']}")
            print(f"    Implementation: {details['implementation']}")

def demonstrate_signature_engine():
    """Execute comprehensive digital signature demonstration"""
    print("=" * 60)
    print(" DIGITAL SIGNATURE ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = DigitalSignatureEngine()
    
    # Generate key pair
    private_key, public_key = engine.generate_key_pair()
    print("\n🔑 Key pair generated successfully")
    
    # Create and verify signature
    test_message = b"Secure Transfer: 50 tokens to Wallet 0xXYZ789"
    signature_data = engine.create_signature(private_key, test_message)
    engine.verify_signature(public_key, signature_data)
    
    # Demonstrate tamper detection
    engine.demonstrate_tamper_detection(private_key, public_key)
    
    # Simulate blockchain transaction
    engine.simulate_blockchain_transaction()
    
    # Additional analytics
    SignatureAnalytics.compare_signature_algorithms()
    SignatureAnalytics.analyze_signature_security()
    
    print("\n" + "=" * 60)
    print(" DIGITAL SIGNATURE SUMMARY:")
    print("   ✓ Authentication: Proves message origin")
    print("   ✓ Integrity: Detects tampering")
    print("   ✓ Non-repudiation: Cannot deny signing")
    print("   ✓ ECDSA: Standard for Bitcoin and Ethereum")
    print("   ✓ SECP256K1: Curve used in blockchain")
    print("   ✓ Hash then sign: SHA-256 + ECDSA")
    print("   ✓ Foundation of blockchain security")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_signature_engine()

3.10 ECDSA

What is ECDSA?

ECDSA (Elliptic Curve Digital Signature Algorithm) is a digital signature algorithm based on elliptic curve cryptography. It’s used by Bitcoin, Ethereum (pre-merge), and many other blockchains. ECDSA is the standard for signing transactions in most cryptocurrencies.

How ECDSA Works:

Key Generation:

  • Random private key (256-bit) is generated
  • Public key is derived using elliptic curve multiplication

Signing:

  1. A random number (k) is generated
  2. The message is hashed
  3. The signature is computed using the private key and k

Verification:

  1. The signature is verified using the public key
  2. The hash of the message is used
  3. The signature is validated without needing the private key

ECDSA Parameters:

ParameterDescriptionValue (Bitcoin)
CurveElliptic curvesecp256k1
Key SizePrivate key size256 bits
Security LevelCollision resistance128 bits
Signature Sizer + s64 bytes

Code Example – ECDSA:

"""
ELLIPTIC CURVE DIGITAL SIGNATURE ALGORITHM FRAMEWORK
=====================================================
Complete ECDSA implementation with secp256k1 curve and blockchain applications
"""

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend
import hashlib
import time
from typing import Tuple, Optional
from dataclasses import dataclass

@dataclass
class ECDSAKeyPair:
    """Represents an ECDSA key pair with secp256k1 curve"""
    private_key: ec.EllipticCurvePrivateKey
    public_key: ec.EllipticCurvePublicKey
    private_key_hex: str
    public_key_x: int
    public_key_y: int
    curve_name: str

@dataclass
class ECDSASignature:
    """Represents an ECDSA signature with verification details"""
    signature: bytes
    message_hash: bytes
    is_valid: bool
    signing_time: float
    verification_time: float
    signature_size: int

class ECDSAEngine:
    """Complete ECDSA implementation and demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ECDSA - ELLIPTIC CURVE DIGITAL SIGNATURE ENGINE")
        print("=" * 60)
    
    def generate_ecdsa_keypair(self) -> ECDSAKeyPair:
        """Generate ECDSA key pair using secp256k1 curve"""
        print("\n 🔑 GENERATING ECDSA KEY PAIR")
        print("-" * 40)
        
        private_key = ec.generate_private_key(ec.SECP256K1(), default_backend())
        public_key = private_key.public_key()
        
        private_numbers = private_key.private_numbers()
        public_numbers = public_key.public_numbers()
        
        print(f"📊 Key Generation Details:")
        print(f"  • Curve: SECP256K1")
        print(f"  • Private Key: {private_numbers.private_value:x}")
        print(f"  • Public Key X: {public_numbers.x:x}")
        print(f"  • Public Key Y: {public_numbers.y:x}")
        print(f"  • Key Size: 256 bits")
        print(f"  • Security Level: 128 bits")
        
        return ECDSAKeyPair(
            private_key=private_key,
            public_key=public_key,
            private_key_hex=hex(private_numbers.private_value),
            public_key_x=public_numbers.x,
            public_key_y=public_numbers.y,
            curve_name="secp256k1"
        )
    
    def sign_transaction(self, private_key: ec.EllipticCurvePrivateKey,
                        transaction_data: bytes) -> ECDSASignature:
        """Sign a transaction using ECDSA"""
        print("\n ✍️  ECDSA SIGNING PROCESS")
        print("-" * 40)
        
        print(f"📝 Transaction Data: {transaction_data.decode() if transaction_data.isascii() else 'Binary'}")
        
        # Hash the transaction
        tx_hash = hashlib.sha256(transaction_data).digest()
        print(f"🔐 Transaction Hash: {tx_hash.hex()[:32]}...")
        
        # Sign the hash
        start_time = time.time()
        signature = private_key.sign(
            tx_hash,
            ec.ECDSA(hashes.SHA256())
        )
        signing_time = time.time() - start_time
        
        print(f"✍️  Signature: {signature.hex()[:32]}...")
        print(f"📏 Signature Size: {len(signature)} bytes")
        print(f"⏱️  Signing Time: {signing_time:.4f}s")
        
        return ECDSASignature(
            signature=signature,
            message_hash=tx_hash,
            is_valid=True,
            signing_time=signing_time,
            verification_time=0,
            signature_size=len(signature)
        )
    
    def verify_transaction(self, public_key: ec.EllipticCurvePublicKey,
                          signature_data: ECDSASignature,
                          transaction_data: bytes) -> bool:
        """Verify an ECDSA signature"""
        print("\n ✅ ECDSA VERIFICATION PROCESS")
        print("-" * 40)
        
        # Hash the transaction
        tx_hash = hashlib.sha256(transaction_data).digest()
        print(f"🔐 Transaction Hash: {tx_hash.hex()[:32]}...")
        print(f"📝 Hash Matches: {tx_hash == signature_data.message_hash}")
        
        # Verify signature
        start_time = time.time()
        try:
            public_key.verify(
                signature_data.signature,
                tx_hash,
                ec.ECDSA(hashes.SHA256())
            )
            verification_time = time.time() - start_time
            signature_data.verification_time = verification_time
            signature_data.is_valid = True
            
            print(f"✅ Signature is VALID")
            print(f"⏱️  Verification Time: {verification_time:.4f}s")
            return True
            
        except Exception as e:
            verification_time = time.time() - start_time
            signature_data.verification_time = verification_time
            signature_data.is_valid = False
            
            print(f"❌ Signature is INVALID")
            print(f"⏱️  Verification Time: {verification_time:.4f}s")
            print(f"⚠️  Error: {str(e)}")
            return False
    
    def demonstrate_curve_properties(self) -> None:
        """Explain secp256k1 curve properties"""
        print("\n 📊 SECP256K1 CURVE PROPERTIES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SECP256K1 CURVE SPECIFICATIONS                           │
├─────────────────────────────────────────────────────────────┤
│  Curve Equation: y² = x³ + 7 (mod p)                     │
│                                                           │
│  Prime Field (p):                                        │
│    2²⁵⁶ - 2³² - 2⁹ - 2⁸ - 2⁷ - 2⁶ - 2⁴ - 1            │
│                                                           │
│  Order (n):                                              │
│    0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25│
│     E8CD0364141                                          │
│                                                           │
│  Base Point (G):                                         │
│    x = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D9│
│        59F2815B16F81798                                  │
│    y = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A6855419│
│        9C47D08FFB10D4B8                                  │
│                                                           │
│  Key Size: 256 bits                                      │
│  Security: 128-bit collision resistance                   │
│  Status: Industry standard for blockchain                 │
│                                                           │
│  Bitcoin's Choice:                                       │
│    • Used for all Bitcoin addresses and transactions     │
│    • Provides cryptographic security                     │
│    • Efficient and fast                                   │
└─────────────────────────────────────────────────────────────┘
        """)

class ECDSAAnalytics:
    """Additional analysis tools for ECDSA"""
    
    @staticmethod
    def compare_signature_algorithms() -> None:
        """Compare ECDSA with other signature algorithms"""
        print("\n 📊 SIGNATURE ALGORITHM COMPARISON")
        print("-" * 40)
        
        algorithms = {
            "ECDSA (secp256k1)": {
                "key_size": "256 bits",
                "sig_size": "~64-72 bytes",
                "speed": "Fast",
                "security": "128 bits",
                "usage": "Bitcoin, Ethereum"
            },
            "Ed25519": {
                "key_size": "256 bits",
                "sig_size": "64 bytes",
                "speed": "Very Fast",
                "security": "128 bits",
                "usage": "Solana, Zcash"
            },
            "RSA-2048": {
                "key_size": "2048 bits",
                "sig_size": "~256 bytes",
                "speed": "Slow",
                "security": "112 bits",
                "usage": "Traditional PKI"
            }
        }
        
        print(f" {'Algorithm':>20} | {'Key Size':>12} | {'Sig Size':>12} | {'Speed':>10} | {'Security':>10} | {'Usage':>15}")
        print("-" * 85)
        
        for name, details in algorithms.items():
            print(f" {name:>20} | {details['key_size']:>12} | {details['sig_size']:>12} | "
                  f"{details['speed']:>10} | {details['security']:>10} | {details['usage']:>15}")
    
    @staticmethod
    def analyze_ecdsa_security() -> None:
        """Analyze ECDSA security considerations"""
        print("\n 🛡️  ECDSA SECURITY ANALYSIS")
        print("-" * 40)
        
        security_aspects = {
            "Key Strength": {
                "description": "256-bit private keys",
                "risk": "Brute force: ~2^128 operations",
                "mitigation": "Use secure RNG"
            },
            "Nonce Reuse": {
                "description": "Reusing random k value",
                "risk": "Exposes private key",
                "mitigation": "Deterministic ECDSA (RFC 6979)"
            },
            "Side-Channel Attacks": {
                "description": "Timing/power analysis",
                "risk": "Can leak key information",
                "mitigation": "Constant-time algorithms"
            },
            "Quantum Computing": {
                "description": "Shor's algorithm threat",
                "risk": "Potential future vulnerability",
                "mitigation": "Post-quantum cryptography"
            }
        }
        
        print("\n 📊 Security Assessment:")
        for aspect, details in security_aspects.items():
            print(f"\n  {aspect}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_ecdsa_engine():
    """Execute comprehensive ECDSA demonstration"""
    print("=" * 60)
    print(" ECDSA ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = ECDSAEngine()
    
    # Generate key pair
    key_pair = engine.generate_ecdsa_keypair()
    
    # Demonstrate curve properties
    engine.demonstrate_curve_properties()
    
    # Create and verify signature
    transaction = b"Send 10 BTC from Address A to Address B"
    signature = engine.sign_transaction(key_pair.private_key, transaction)
    engine.verify_transaction(key_pair.public_key, signature, transaction)
    
    # Demonstrate tamper detection
    print("\n 🔍 TAMPER DETECTION DEMONSTRATION")
    print("-" * 40)
    tampered_transaction = b"Send 1000 BTC from Address A to Address B"
    print(f"📝 Tampered Transaction: {tampered_transaction.decode()}")
    engine.verify_transaction(key_pair.public_key, signature, tampered_transaction)
    
    # Additional analytics
    ECDSAAnalytics.compare_signature_algorithms()
    ECDSAAnalytics.analyze_ecdsa_security()
    
    print("\n" + "=" * 60)
    print(" ECDSA SUMMARY:")
    print("   ✓ Curve: SECP256K1 (Bitcoin/Ethereum standard)")
    print("   ✓ Key Size: 256 bits")
    print("   ✓ Security: 128-bit collision resistance")
    print("   ✓ Algorithm: ECDSA with SHA-256")
    print("   ✓ Application: Digital signatures for blockchain")
    print("   ✓ Properties: Fast, efficient, secure")
    print("   ✓ Nonce Reuse: Critical vulnerability to avoid")
    print("   ✓ Used in: Bitcoin, Ethereum, and many blockchains")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_ecdsa_engine()

3.11 EdDSA

What is EdDSA?

EdDSA (Edwards-curve Digital Signature Algorithm) is a modern digital signature algorithm that offers significant improvements over ECDSA. It’s used by newer blockchains like Solana and Cardano.

EdDSA Features:

FeatureDescriptionAdvantage
Curveed25519High performance
Security128-bitVery secure
SpeedVery FastFaster than ECDSA
DeterministicYesNo randomness needed
Batch VerificationYesMultiple signatures at once

EdDSA vs ECDSA:

FeatureECDSAEdDSA
Curvesecp256k1ed25519
Sign SpeedReference20% Faster
Verify SpeedReference20% Faster
DeterministicNoYes
Batch VerifyNoYes
Security128-bit128-bit
Key Size256-bit256-bit
Used InBitcoin, ETHSolana, Cardano

Code Example – EdDSA:

"""
EDWARDS-CURVE DIGITAL SIGNATURE ALGORITHM FRAMEWORK
===================================================
Complete EdDSA implementation with ed25519 curve and blockchain applications
"""

import hashlib
import time
from typing import Tuple, Optional
from dataclasses import dataclass

@dataclass
class EdDSAKeyPair:
    """Represents an EdDSA key pair with ed25519 curve"""
    private_key: bytes
    public_key: bytes
    private_key_hex: str
    public_key_hex: str
    curve_name: str

@dataclass
class EdDSASignature:
    """Represents an EdDSA signature with verification details"""
    signature: bytes
    message: bytes
    is_valid: bool
    signing_time: float
    verification_time: float
    signature_size: int

class EdDSAEngine:
    """Complete EdDSA demonstration suite with ed25519 curve"""
    
    def __init__(self):
        print("=" * 60)
        print(" EdDSA - EDWARDS-CURVE DIGITAL SIGNATURE ENGINE")
        print("=" * 60)
    
    def generate_eddsa_keypair(self) -> EdDSAKeyPair:
        """Generate EdDSA key pair using ed25519 curve"""
        print("\n 🔑 GENERATING EdDSA KEY PAIR")
        print("-" * 40)
        
        # Simulate ed25519 key generation
        private_key = hashlib.sha256(b"ed25519_seed_12345").digest()
        public_key = hashlib.sha256(private_key + b"public").digest()
        
        print(f"📊 Key Generation Details:")
        print(f"  • Curve: ed25519")
        print(f"  • Private Key: {private_key.hex()[:32]}...")
        print(f"  • Public Key: {public_key.hex()[:32]}...")
        print(f"  • Key Size: 256 bits")
        print(f"  • Security Level: 128 bits")
        
        return EdDSAKeyPair(
            private_key=private_key,
            public_key=public_key,
            private_key_hex=private_key.hex(),
            public_key_hex=public_key.hex(),
            curve_name="ed25519"
        )
    
    def create_signature(self, private_key: bytes, message: bytes) -> EdDSASignature:
        """Create an EdDSA signature"""
        print("\n ✍️  EdDSA SIGNING PROCESS")
        print("-" * 40)
        
        print(f"📝 Message: {message.decode() if message.isascii() else 'Binary data'}")
        
        # Simulate ed25519 signing
        start_time = time.time()
        
        # Hash message with private key
        combined = private_key + message
        signature = hashlib.sha512(combined).digest()[:64]
        
        signing_time = time.time() - start_time
        
        print(f"✍️  Signature: {signature.hex()[:32]}...")
        print(f"📏 Signature Size: {len(signature)} bytes")
        print(f"⏱️  Signing Time: {signing_time:.4f}s")
        print(f"🔐 Algorithm: Ed25519")
        print(f"✅ Deterministic: Yes (no randomness needed)")
        
        return EdDSASignature(
            signature=signature,
            message=message,
            is_valid=True,
            signing_time=signing_time,
            verification_time=0,
            signature_size=len(signature)
        )
    
    def verify_signature(self, public_key: bytes, 
                        signature_data: EdDSASignature,
                        message: bytes) -> bool:
        """Verify an EdDSA signature"""
        print("\n ✅ EdDSA VERIFICATION PROCESS")
        print("-" * 40)
        
        print(f"📝 Message: {message.decode() if message.isascii() else 'Binary data'}")
        
        start_time = time.time()
        
        # Simulate ed25519 verification
        expected = hashlib.sha512(public_key + message).digest()[:64]
        is_valid = signature_data.signature == expected
        
        verification_time = time.time() - start_time
        signature_data.verification_time = verification_time
        signature_data.is_valid = is_valid
        
        if is_valid:
            print(f"✅ Signature is VALID")
        else:
            print(f"❌ Signature is INVALID")
        
        print(f"⏱️  Verification Time: {verification_time:.4f}s")
        return is_valid
    
    def demonstrate_eddsa_properties(self) -> None:
        """Explain EdDSA properties and advantages"""
        print("\n 📊 EdDSA PROPERTIES AND ADVANTAGES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  EdDSA (Edwards-curve Digital Signature Algorithm)        │
├─────────────────────────────────────────────────────────────┤
│  CURVE: ed25519                                          │
│  • -x² + y² = 1 - (121665/121666)x²y²                    │
│  • 256-bit security                                      │
│  • 128-bit collision resistance                          │
│                                                           │
│  KEY FEATURES:                                          │
│  ✓ Deterministic: No randomness needed                    │
│  ✓ Fast: 20% faster than ECDSA                           │
│  ✓ Batch Verification: Verify multiple signatures at once│
│  ✓ Side-Channel Resistant: Constant-time operations       │
│  ✓ Modern Design: Based on current best practices        │
│                                                           │
│  COMPARED TO ECDSA:                                      │
│  • Faster signing and verification                        │
│  • Safer (deterministic nonce generation)                │
│  • Better for high-volume systems                         │
│  • Supports batch verification                            │
└─────────────────────────────────────────────────────────────┘
        """)

class EdDSAAnalytics:
    """Additional analysis tools for EdDSA"""
    
    @staticmethod
    def compare_with_ecdsa() -> None:
        """Compare EdDSA with ECDSA"""
        print("\n 📊 EdDSA VS ECDSA COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Feature": ["Curve", "Sign Speed", "Verify Speed", "Deterministic", "Batch Verify", "Side-Channel Resistant"],
            "ECDSA": ["secp256k1", "Reference", "Reference", "❌ No", "❌ No", "⚠️  Partial"],
            "EdDSA": ["ed25519", "20% Faster", "20% Faster", "✅ Yes", "✅ Yes", "✅ Yes"]
        }
        
        print(f"\n {'Feature':>25} | {'ECDSA (secp256k1)':>20} | {'EdDSA (ed25519)':>20}")
        print("-" * 70)
        
        for i in range(len(comparison["Feature"])):
            feature = comparison["Feature"][i]
            ecdsa_val = comparison["ECDSA"][i]
            eddsa_val = comparison["EdDSA"][i]
            print(f" {feature:>25} | {ecdsa_val:>20} | {eddsa_val:>20}")
    
    @staticmethod
    def analyze_blockchain_usage() -> None:
        """Analyze blockchain usage of EdDSA"""
        print("\n 📊 BLOCKCHAIN EdDSA USAGE")
        print("-" * 40)
        
        usage = {
            "Solana": {
                "purpose": "Transaction signing",
                "advantage": "High throughput, fast verification",
                "adoption": "Primary signature algorithm"
            },
            "Cardano": {
                "purpose": "Address generation and signing",
                "advantage": "Security and efficiency",
                "adoption": "Native signature scheme"
            },
            "Zcash": {
                "purpose": "Sapling protocol",
                "advantage": "Privacy and performance",
                "adoption": "Part of shielded transactions"
            },
            "Stellar": {
                "purpose": "Transaction authentication",
                "advantage": "Fast and secure",
                "adoption": "Default signature scheme"
            }
        }
        
        print("\n 📈 EdDSA Adoption in Blockchains:")
        for blockchain, details in usage.items():
            print(f"\n  {blockchain}:")
            print(f"    Purpose: {details['purpose']}")
            print(f"    Advantage: {details['advantage']}")
            print(f"    Adoption: {details['adoption']}")

def demonstrate_eddsa_engine():
    """Execute comprehensive EdDSA demonstration"""
    print("=" * 60)
    print(" EdDSA ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = EdDSAEngine()
    
    # Generate key pair
    key_pair = engine.generate_eddsa_keypair()
    
    # Demonstrate EdDSA properties
    engine.demonstrate_eddsa_properties()
    
    # Create and verify signature
    message = b"Solana Transaction: Transfer 50 SOL to Address 0xXYZ"
    signature = engine.create_signature(key_pair.private_key, message)
    engine.verify_signature(key_pair.public_key, signature, message)
    
    # Demonstrate tamper detection
    print("\n 🔍 TAMPER DETECTION DEMONSTRATION")
    print("-" * 40)
    tampered_message = b"Solana Transaction: Transfer 5000 SOL to Address 0xXYZ"
    print(f"📝 Tampered Message: {tampered_message.decode()}")
    engine.verify_signature(key_pair.public_key, signature, tampered_message)
    
    # Additional analytics
    EdDSAAnalytics.compare_with_ecdsa()
    EdDSAAnalytics.analyze_blockchain_usage()
    
    print("\n" + "=" * 60)
    print(" EdDSA SUMMARY:")
    print("   ✓ Curve: ed25519 (modern, efficient)")
    print("   ✓ Deterministic: No randomness needed")
    print("   ✓ Speed: 20% faster than ECDSA")
    print("   ✓ Security: 128-bit collision resistance")
    print("   ✓ Batch Verification: Supports multiple signatures")
    print("   ✓ Side-Channel Resistant: Constant-time operations")
    print("   ✓ Used In: Solana, Cardano, Zcash, Stellar")
    print("   ✓ Advantages: Faster, safer, more efficient")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_eddsa_engine()

3.12 Elliptic Curve Cryptography (ECC)

What is Elliptic Curve Cryptography?

Elliptic Curve Cryptography (ECC) is a public-key cryptography system based on the algebraic structure of elliptic curves over finite fields. It’s the mathematical foundation of all blockchain cryptography.

Why ECC?

ECC provides the same security as traditional RSA but with much smaller keys. A 256-bit ECC key provides security comparable to a 3072-bit RSA key, making ECC more efficient while requiring significantly smaller keys.

Elliptic Curve Mathematics:

The Curve Equation:

y² = x³ + ax + b

Bitcoin’s secp256k1 Curve:

y² = x³ + 7 (mod p)

where p = 2²⁵⁶ – 2³² – 2⁹ – 2⁸ – 2⁷ – 2⁶ – 2⁴ – 1

Key Operations:

  1. Point Addition: Adding two points on the curve
  2. Point Doubling: Adding a point to itself
  3. Scalar Multiplication: Multiplying a point by a scalar
  4. Discrete Logarithm Problem: Finding the scalar from point multiplication (hard)

Code Example – ECC:

"""
ELLIPTIC CURVE CRYPTOGRAPHY FRAMEWORK
=====================================
Complete ECC implementation with secp256k1 curve and blockchain applications
"""

import random
import hashlib
import time
from typing import Tuple, Optional, List
from dataclasses import dataclass

@dataclass
class ECCPoint:
    """Represents a point on an elliptic curve"""
    x: int
    y: int
    
    def __str__(self) -> str:
        return f"({self.x:x}, {self.y:x})"

@dataclass
class ECCKeyPair:
    """Represents an ECC key pair"""
    private_key: int
    public_key: ECCPoint
    curve_name: str
    key_size: int

@dataclass
class ECCSignature:
    """Represents an ECC signature"""
    r: int
    s: int
    message_hash: int
    is_valid: bool
    signing_time: float
    verification_time: float

class Secp256k1Curve:
    """SECP256K1 elliptic curve implementation (Bitcoin/Ethereum standard)"""
    
    def __init__(self):
        # Curve parameters
        self.a = 0
        self.b = 7
        self.p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
        self.n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
        
        # Generator point (G)
        self.G = ECCPoint(
            x=0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
            y=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
        )
        
        print("=" * 60)
        print(" ELLIPTIC CURVE CRYPTOGRAPHY (ECC) ENGINE")
        print("=" * 60)
        print("\n📊 SECP256K1 Curve Parameters:")
        print(f"  • Curve: y² = x³ + 7 (mod p)")
        print(f"  • Prime (p): {hex(self.p)[:20]}...")
        print(f"  • Order (n): {hex(self.n)[:20]}...")
        print(f"  • Generator: x={self.G.x:x}, y={self.G.y:x}")
        print(f"  • Key Size: 256 bits")
        print(f"  • Security Level: 128 bits")
        print(f"  • Status: Bitcoin/Ethereum standard")
    
    def point_add(self, P: Optional[ECCPoint], Q: Optional[ECCPoint]) -> Optional[ECCPoint]:
        """Add two points on the elliptic curve"""
        if P is None:
            return Q
        if Q is None:
            return P
        
        x1, y1 = P.x, P.y
        x2, y2 = Q.x, Q.y
        
        # Point at infinity check
        if x1 == x2 and y1 != y2:
            return None
        
        # Calculate slope (m)
        if x1 == x2 and y1 == y2:
            # Point doubling
            m = (3 * x1 * x1 + self.a) * pow(2 * y1, -1, self.p) % self.p
        else:
            # Point addition
            m = (y2 - y1) * pow(x2 - x1, -1, self.p) % self.p
        
        # Calculate new point
        x3 = (m * m - x1 - x2) % self.p
        y3 = (m * (x1 - x3) - y1) % self.p
        
        return ECCPoint(x3, y3)
    
    def scalar_multiply(self, k: int, P: ECCPoint) -> Optional[ECCPoint]:
        """Multiply a point by a scalar using double-and-add"""
        result = None
        current = P
        
        while k > 0:
            if k & 1:
                result = self.point_add(result, current)
            current = self.point_add(current, current)
            k >>= 1
        
        return result
    
    def generate_key_pair(self) -> ECCKeyPair:
        """Generate a random ECC key pair"""
        private_key = random.randint(1, self.n - 1)
        public_key = self.scalar_multiply(private_key, self.G)
        
        return ECCKeyPair(
            private_key=private_key,
            public_key=public_key,
            curve_name="secp256k1",
            key_size=256
        )

class ECCEngine:
    """Complete ECC demonstration and application suite"""
    
    def __init__(self):
        self.curve = Secp256k1Curve()
    
    def demonstrate_ecdsa_signing(self) -> None:
        """Demonstrate ECDSA signing and verification"""
        print("\n ✍️  ECDSA SIGNING AND VERIFICATION")
        print("-" * 40)
        
        # Generate key pair
        key_pair = self.curve.generate_key_pair()
        print(f"🔑 Private Key: {key_pair.private_key:x}")
        print(f"📌 Public Key: ({key_pair.public_key.x:x}, {key_pair.public_key.y:x})")
        
        # Message to sign
        message = b"Transfer 50 tokens to Account 0xABC123"
        message_hash = int(hashlib.sha256(message).hexdigest(), 16) % self.curve.n
        
        print(f"\n📝 Message: {message.decode()}")
        print(f"🔐 Message Hash: {message_hash:x}")
        
        # Sign the message
        start_time = time.time()
        
        # Generate random nonce (k)
        k = random.randint(1, self.curve.n - 1)
        r_point = self.curve.scalar_multiply(k, self.curve.G)
        r = r_point.x % self.curve.n
        
        # Calculate s = k⁻¹ * (hash + private_key * r) mod n
        k_inv = pow(k, -1, self.curve.n)
        s = (k_inv * (message_hash + key_pair.private_key * r)) % self.curve.n
        
        signing_time = time.time() - start_time
        
        print(f"\n✍️  Signature:")
        print(f"  • r = {r:x}")
        print(f"  • s = {s:x}")
        print(f"  • Size: ~64 bytes")
        print(f"  • Signing Time: {signing_time:.4f}s")
        
        # Verify the signature
        start_time = time.time()
        
        # Calculate w = s⁻¹ mod n
        w = pow(s, -1, self.curve.n)
        u1 = (message_hash * w) % self.curve.n
        u2 = (r * w) % self.curve.n
        
        # Calculate v = u1*G + u2*PublicKey
        v_point = self.curve.point_add(
            self.curve.scalar_multiply(u1, self.curve.G),
            self.curve.scalar_multiply(u2, key_pair.public_key)
        )
        
        verification_time = time.time() - start_time
        
        if v_point and v_point.x % self.curve.n == r:
            print(f"\n✅ Signature is VALID")
            print(f"⏱️  Verification Time: {verification_time:.4f}s")
        else:
            print(f"\n❌ Signature is INVALID")
    
    def demonstrate_tamper_detection(self) -> None:
        """Show how ECC detects tampering"""
        print("\n 🛡️  TAMPER DETECTION WITH ECC")
        print("-" * 40)
        
        # Generate key pair
        key_pair = self.curve.generate_key_pair()
        
        # Original message
        original_message = b"Transfer 100 tokens to Address 0xXYZ"
        print(f"📝 Original: {original_message.decode()}")
        
        # Sign original
        hash_orig = int(hashlib.sha256(original_message).hexdigest(), 16) % self.curve.n
        k = random.randint(1, self.curve.n - 1)
        r_point = self.curve.scalar_multiply(k, self.curve.G)
        r = r_point.x % self.curve.n
        k_inv = pow(k, -1, self.curve.n)
        s = (k_inv * (hash_orig + key_pair.private_key * r)) % self.curve.n
        
        # Verify original
        w = pow(s, -1, self.curve.n)
        u1 = (hash_orig * w) % self.curve.n
        u2 = (r * w) % self.curve.n
        v_point = self.curve.point_add(
            self.curve.scalar_multiply(u1, self.curve.G),
            self.curve.scalar_multiply(u2, key_pair.public_key)
        )
        
        if v_point and v_point.x % self.curve.n == r:
            print(f"✅ Original signature is VALID")
        else:
            print(f"❌ Original signature is INVALID")
        
        # Tampered message
        tampered_message = b"Transfer 10000 tokens to Address 0xXYZ"
        print(f"\n⚠️  Tampered: {tampered_message.decode()}")
        
        # Try to verify tampered message with original signature
        hash_tampered = int(hashlib.sha256(tampered_message).hexdigest(), 16) % self.curve.n
        u1 = (hash_tampered * w) % self.curve.n
        u2 = (r * w) % self.curve.n
        v_point = self.curve.point_add(
            self.curve.scalar_multiply(u1, self.curve.G),
            self.curve.scalar_multiply(u2, key_pair.public_key)
        )
        
        if v_point and v_point.x % self.curve.n == r:
            print(f"❌ Tampered signature is VALID (should be invalid)")
        else:
            print(f"✅ Tampered signature is INVALID (tampering detected)")
    
    def demonstrate_curve_properties(self) -> None:
        """Explain ECC mathematical properties"""
        print("\n 📊 ECC MATHEMATICAL PROPERTIES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ECC MATHEMATICAL FOUNDATIONS                             │
├─────────────────────────────────────────────────────────────┤
│  GROUP OPERATIONS:                                      │
│    1. Point Addition: P + Q = R                          │
│       • Compute slope m = (y2-y1)/(x2-x1) mod p          │
│       • R = (m² - x1 - x2, m(x1 - x3) - y1)              │
│                                                           │
│    2. Point Doubling: P + P = 2P = R                    │
│       • Compute slope m = (3x² + a)/(2y) mod p           │
│       • R = (m² - 2x, m(x - x3) - y)                     │
│                                                           │
│    3. Scalar Multiplication: kP                          │
│       • Repeated addition of point to itself              │
│       • Double-and-add algorithm                          │
│       • O(log k) operations                               │
│                                                           │
│  DISCRETE LOGARITHM PROBLEM:                            │
│     Given: P and Q = kP                                  │
│     Find: k                                              │
│     This is computationally infeasible                    │
│     Provides ECC security                                 │
│                                                           │
│  SECURITY GUARANTEES:                                   │
│    • 256-bit keys provide 128-bit security              │
│    • No known sub-exponential attacks                    │
│    • Used by Bitcoin since 2009                         │
│    • Industry standard for blockchain                   │
└─────────────────────────────────────────────────────────────┘
        """)

class ECCAnalytics:
    """Additional analysis tools for ECC"""
    
    @staticmethod
    def compare_curves() -> None:
        """Compare different elliptic curves"""
        print("\n 📊 ELLIPTIC CURVE COMPARISON")
        print("-" * 40)
        
        curves = {
            "SECP256K1": {
                "key_size": "256 bits",
                "security": "128 bits",
                "speed": "Fast",
                "usage": "Bitcoin, Ethereum",
                "equation": "y² = x³ + 7"
            },
            "ED25519": {
                "key_size": "256 bits",
                "security": "128 bits",
                "speed": "Very Fast",
                "usage": "Solana, Cardano",
                "equation": "-x² + y² = 1 - (121665/121666)x²y²"
            },
            "P-256": {
                "key_size": "256 bits",
                "security": "128 bits",
                "speed": "Fast",
                "usage": "NIST standard",
                "equation": "y² = x³ - 3x + 41058363725152142129326129780047268409114441015993725554835256314039467401291"
            }
        }
        
        print(f" {'Curve':>12} | {'Key Size':>12} | {'Security':>10} | {'Speed':>10} | {'Usage':>15} | {'Equation':>20}")
        print("-" * 90)
        
        for name, details in curves.items():
            print(f" {name:>12} | {details['key_size']:>12} | {details['security']:>10} | "
                  f"{details['speed']:>10} | {details['usage']:>15} | {details['equation'][:20]}")
    
    @staticmethod
    def analyze_security_levels() -> None:
        """Analyze ECC security levels"""
        print("\n 🛡️  ECC SECURITY LEVEL ANALYSIS")
        print("-" * 40)
        
        security_levels = {
            "Key Size": ["160 bits", "192 bits", "224 bits", "256 bits", "384 bits", "512 bits"],
            "Security": ["80 bits", "96 bits", "112 bits", "128 bits", "192 bits", "256 bits"],
            "RSA Equivalent": ["1024 bits", "2048 bits", "3072 bits", "3072 bits", "7680 bits", "15360 bits"],
            "Status": ["❌ Deprecated", "⚠️  Weak", "✅ Secure", "✅ Strong", "✅ Very Strong", "✅ Extremely Strong"]
        }
        
        print("\n 📊 Security Level Matrix:")
        print(f" {'Key Size':>12} | {'Security':>12} | {'RSA Equivalent':>20} | {'Status':>20}")
        print("-" * 70)
        
        for i in range(len(security_levels["Key Size"])):
            key_size = security_levels["Key Size"][i]
            security = security_levels["Security"][i]
            rsa_eq = security_levels["RSA Equivalent"][i]
            status = security_levels["Status"][i]
            
            print(f" {key_size:>12} | {security:>12} | {rsa_eq:>20} | {status:>20}")

def demonstrate_ecc_engine():
    """Execute comprehensive ECC demonstration"""
    print("=" * 60)
    print(" ELLIPTIC CURVE CRYPTOGRAPHY ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = ECCEngine()
    
    # Demonstrate ECDSA signing
    engine.demonstrate_ecdsa_signing()
    
    # Demonstrate tamper detection
    engine.demonstrate_tamper_detection()
    
    # Demonstrate curve properties
    engine.demonstrate_curve_properties()
    
    # Additional analytics
    ECCAnalytics.compare_curves()
    ECCAnalytics.analyze_security_levels()
    
    print("\n" + "=" * 60)
    print(" ECC SUMMARY:")
    print("   ✓ Curve: SECP256K1 (Bitcoin/Ethereum standard)")
    print("   ✓ Key Size: 256 bits")
    print("   ✓ Security: 128-bit collision resistance")
    print("   ✓ Operations: Point addition, doubling, scalar multiplication")
    print("   ✓ Algorithms: ECDSA for signatures")
    print("   ✓ Advantages: Smaller keys, faster operations")
    print("   ✓ Foundation: Discrete logarithm problem")
    print("   ✓ Application: Blockchain cryptography foundation")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_ecc_engine()

3.13 Merkle Trees

What is a Merkle Tree?

A Merkle tree is a data structure where each leaf node is a hash of data, and each non-leaf node is a hash of its children. This allows efficient verification of data integrity—you can prove a specific piece of data is in the tree without downloading the entire tree.

Why Merkle Trees Matter:

Efficient Verification:
You can verify a transaction is in a block with just the transaction hash and a small Merkle proof (log2(N) hashes). This is the foundation of light clients.

Efficient Storage:
Light clients only need to store block headers, not the entire block. They can verify transactions without downloading everything.

Integrity:
The Merkle root represents all data in the tree. Any change to a single leaf node propagates through the tree, resulting in a different Merkle root.

How Merkle Trees Work:

                      Merkle Root
                         |
              ┌──────────┴──────────┐
              │                     │
           Hash12                  Hash34
          /      \                /      \
      Hash1      Hash2        Hash3      Hash4
        |          |            |          |
       Tx1        Tx2          Tx3        Tx4

Merkle Proof:

To prove Tx1 is in the tree:

  1. Provide Hash2, Hash34
  2. Hash(Hash1 + Hash2) = Hash12
  3. Hash(Hash12 + Hash34) = Merkle Root
  4. Compare to known root

Code Example – Merkle Trees:

"""
MERKLE TREE DATA STRUCTURE FRAMEWORK
====================================
Complete Merkle tree implementation with proof generation and verification
"""

import hashlib
import math
from typing import List, Tuple, Optional
from dataclasses import dataclass

@dataclass
class MerkleProof:
    """Represents a Merkle proof for a leaf"""
    leaf_hash: bytes
    sibling_hashes: List[Tuple[bytes, bool]]  # (hash, is_left)
    root_hash: bytes
    leaf_index: int
    is_valid: bool

@dataclass
class MerkleNode:
    """Represents a node in the Merkle tree"""
    hash_value: bytes
    left_child: Optional['MerkleNode'] = None
    right_child: Optional['MerkleNode'] = None
    is_leaf: bool = False

class MerkleTreeEngine:
    """Complete Merkle tree implementation with blockchain applications"""
    
    def __init__(self, data_items: List[str]):
        self.data_items = data_items
        self.leaf_hashes = [hashlib.sha256(item.encode()).hexdigest().encode() for item in data_items]
        self.tree_structure = self._construct_tree(self.leaf_hashes)
        self.root_hash = self.tree_structure[-1][0] if self.tree_structure else None
        
        print("=" * 60)
        print(" MERKLE TREE DATA STRUCTURE ENGINE")
        print("=" * 60)
        print(f"\n📊 Tree Statistics:")
        print(f"  • Data Items: {len(data_items)}")
        print(f"  • Tree Levels: {len(self.tree_structure)}")
        print(f"  • Root Hash: {self.root_hash.hex()[:16]}..." if self.root_hash else "  • Root Hash: None")
    
    def _construct_tree(self, leaf_nodes: List[bytes]) -> List[List[bytes]]:
        """Build the Merkle tree from leaf nodes"""
        if not leaf_nodes:
            return []
        
        tree_levels = [leaf_nodes]
        
        while len(tree_levels[-1]) > 1:
            current_level = tree_levels[-1]
            next_level = []
            
            for i in range(0, len(current_level), 2):
                if i + 1 < len(current_level):
                    combined = hashlib.sha256(current_level[i] + current_level[i + 1]).digest()
                else:
                    combined = current_level[i]  # Propagate odd node
                next_level.append(combined)
            
            tree_levels.append(next_level)
        
        return tree_levels
    
    def retrieve_root(self) -> Optional[bytes]:
        """Get the Merkle root hash"""
        return self.root_hash
    
    def generate_proof(self, leaf_index: int) -> Optional[MerkleProof]:
        """Generate a Merkle proof for a leaf at the given index"""
        if leaf_index >= len(self.leaf_hashes):
            print(f"❌ Invalid leaf index: {leaf_index}")
            return None
        
        proof_path = []
        current_index = leaf_index
        
        for level in self.tree_structure[:-1]:
            level_length = len(level)
            
            # Determine if node is left or right
            is_left = current_index % 2 == 0
            
            if current_index + 1 < level_length:
                sibling = level[current_index + 1]
            else:
                sibling = level[current_index - 1]
            
            proof_path.append((sibling, is_left))
            current_index = current_index // 2
        
        return MerkleProof(
            leaf_hash=self.leaf_hashes[leaf_index],
            sibling_hashes=proof_path,
            root_hash=self.root_hash,
            leaf_index=leaf_index,
            is_valid=True
        )
    
    def verify_proof(self, proof: MerkleProof) -> bool:
        """Verify a Merkle proof"""
        current_hash = proof.leaf_hash
        
        for sibling_hash, is_left in proof.sibling_hashes:
            if is_left:
                current_hash = hashlib.sha256(current_hash + sibling_hash).digest()
            else:
                current_hash = hashlib.sha256(sibling_hash + current_hash).digest()
        
        is_valid = current_hash == proof.root_hash
        proof.is_valid = is_valid
        return is_valid
    
    def render_tree(self) -> None:
        """Display the Merkle tree structure"""
        print("\n 🌳 MERKLE TREE STRUCTURE")
        print("-" * 40)
        
        for level_index, level in enumerate(self.tree_structure):
            level_name = "🔴 Root" if level_index == len(self.tree_structure) - 1 else f"📊 Level {level_index}"
            print(f"\n{level_name} ({len(level)} nodes):")
            
            for i, node_hash in enumerate(level):
                if level_index == len(self.tree_structure) - 1 and i == 0:
                    print(f"  ★ {node_hash.hex()[:20]}...")
                else:
                    print(f"  ├─ {node_hash.hex()[:20]}...")
    
    def demonstrate_merkle_verification(self) -> None:
        """Show Merkle proof verification process"""
        print("\n 🔍 MERKLE PROOF VERIFICATION")
        print("-" * 40)
        
        # Choose a random leaf
        index = 1 if len(self.data_items) > 1 else 0
        print(f"📝 Transaction: {self.data_items[index]}")
        
        # Generate proof
        proof = self.generate_proof(index)
        if not proof:
            return
        
        print(f"\n🔑 Proof Generation:")
        print(f"  • Leaf Hash: {proof.leaf_hash.hex()[:16]}...")
        print(f"  • Sibling Hashes: {len(proof.sibling_hashes)}")
        for i, (sibling_hash, is_left) in enumerate(proof.sibling_hashes):
            position = "left" if is_left else "right"
            print(f"    • Sibling {i+1}: {sibling_hash.hex()[:16]}... ({position})")
        
        # Verify proof
        is_valid = self.verify_proof(proof)
        print(f"\n✅ Proof Valid: {is_valid}")
        
        # Demonstrate tamper detection
        print("\n 🛡️  TAMPER DETECTION DEMONSTRATION")
        print("-" * 40)
        
        tampered_data = self.data_items[index] + " (tampered)"
        tampered_leaf = hashlib.sha256(tampered_data.encode()).digest()
        
        tampered_proof = MerkleProof(
            leaf_hash=tampered_leaf,
            sibling_hashes=proof.sibling_hashes,
            root_hash=proof.root_hash,
            leaf_index=proof.leaf_index,
            is_valid=False
        )
        
        is_tampered_valid = self.verify_proof(tampered_proof)
        print(f"📝 Original: {self.data_items[index]}")
        print(f"⚠️  Tampered: {tampered_data}")
        print(f"❌ Proof Valid with Tampered Data: {is_tampered_valid}")
        print("   ✓ Tampering detected successfully!")

class MerkleAnalytics:
    """Additional analysis tools for Merkle trees"""
    
    @staticmethod
    def analyze_efficiency() -> None:
        """Analyze Merkle tree efficiency"""
        print("\n 📊 MERKLE TREE EFFICIENCY ANALYSIS")
        print("-" * 40)
        
        data_sizes = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
        
        print("\n📈 Tree Height vs Data Size:")
        print(f" {'Data Items':>12} | {'Tree Height':>12} | {'Proof Size (hashes)':>20} | {'Hash Operations':>15}")
        print("-" * 65)
        
        for size in data_sizes:
            height = math.ceil(math.log2(size)) + 1 if size > 1 else 1
            proof_size = height - 1
            hash_ops = 2 * size - 1
            
            print(f" {size:>12} | {height:>12} | {proof_size:>20} | {hash_ops:>15}")
    
    @staticmethod
    def analyze_security_properties() -> None:
        """Analyze Merkle tree security properties"""
        print("\n 🛡️  MERKLE TREE SECURITY PROPERTIES")
        print("-" * 40)
        
        properties = {
            "Collision Resistance": {
                "description": "Hard to find two different trees with same root",
                "security": "High (128-bit)",
                "application": "Data integrity"
            },
            "Pre-image Resistance": {
                "description": "Hard to find original data from root hash",
                "security": "High (128-bit)",
                "application": "Data privacy"
            },
            "Efficient Verification": {
                "description": "Verify data with O(log n) hashes",
                "security": "High",
                "application": "Light clients"
            },
            "Tamper Detection": {
                "description": "Any change detectable at root",
                "security": "Guaranteed",
                "application": "Blockchain validation"
            }
        }
        
        print("\n 📋 Security Analysis:")
        for prop, details in properties.items():
            print(f"\n  {prop}:")
            print(f"    Description: {details['description']}")
            print(f"    Security: {details['security']}")
            print(f"    Application: {details['application']}")

def demonstrate_merkle_tree():
    """Execute comprehensive Merkle tree demonstration"""
    print("=" * 60)
    print(" MERKLE TREE ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Sample transactions
    transactions = [
        "Alice → Bob: Transfer 10 BTC",
        "Bob → Charlie: Transfer 5 BTC",
        "Charlie → Diana: Transfer 3 BTC",
        "Diana → Eve: Transfer 8 BTC",
        "Eve → Frank: Transfer 2 BTC",
        "Frank → Alice: Transfer 6 BTC"
    ]
    
    print("\n📝 Input Data (Transactions):")
    for i, tx in enumerate(transactions):
        print(f"  {i}: {tx}")
    
    # Initialize Merkle tree
    merkle_tree = MerkleTreeEngine(transactions)
    
    # Display tree structure
    merkle_tree.render_tree()
    
    # Demonstrate proof verification
    merkle_tree.demonstrate_merkle_verification()
    
    # Additional analytics
    MerkleAnalytics.analyze_efficiency()
    MerkleAnalytics.analyze_security_properties()
    
    print("\n" + "=" * 60)
    print(" MERKLE TREE SUMMARY:")
    print("   ✓ Data Structure: Binary tree of hashes")
    print("   ✓ Root Hash: Single hash representing all data")
    print("   ✓ Proof Size: O(log n) hashes")
    print("   ✓ Verification: Efficient and fast")
    print("   ✓ Tamper Detection: Any change detectable")
    print("   ✓ Application: Blockchain block headers")
    print("   ✓ Use: Light clients, SPV verification")
    print("   ✓ Security: Cryptographic hashing ensures integrity")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_merkle_tree()

3.14 Entropy

What is Entropy?

Entropy in cryptography refers to the randomness, unpredictability, or disorder of a system. High entropy means high randomness and unpredictability, which is essential for cryptographic security.

Why Entropy Matters:

Key Generation: Cryptographic keys must be generated from high-entropy sources. Low entropy = Predictable keys = Vulnerable to attack.

Security: The security of cryptographic systems depends on the quality of randomness. If randomness is predictable, the system can be broken.

Randomness Sources:

SourceQualityUse Case
Hardware RNGVery HighHigh security
Mouse MovementsMediumGeneral use
System TimeLowNot secure
User InputLowNot secure

Code Example – Entropy:

"""
CRYPTOGRAPHIC ENTROPY FRAMEWORK
===============================
Comprehensive entropy demonstration with security implications and best practices
"""

import secrets
import random
import time
import hashlib
import os
from typing import Tuple, Dict, List
from dataclasses import dataclass

@dataclass
class EntropySource:
    """Represents an entropy source with its characteristics"""
    name: str
    entropy_bits: int
    randomness_quality: str
    source_type: str
    example_output: str

@dataclass
class EntropyAnalysis:
    """Represents an analysis of entropy quality"""
    source_name: str
    sample_size: int
    estimated_entropy: float
    entropy_per_bit: float
    security_level: str
    recommendation: str

class EntropyEngine:
    """Complete entropy demonstration and analysis suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOGRAPHIC ENTROPY ENGINE")
        print("=" * 60)
    
    def explain_entropy_concept(self) -> None:
        """Explain the concept of entropy in cryptography"""
        print("\n 📊 WHAT IS ENTROPY?")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTOGRAPHIC ENTROPY                                    │
├─────────────────────────────────────────────────────────────┤
│  DEFINITION:                                             │
│    Entropy = Randomness = Unpredictability               │
│    Measured in bits of uncertainty                        │
│                                                           │
│  HIGH ENTROPY:                                           │
│    • Hard to predict                                      │
│    • Truly random                                         │
│    • Secure for cryptography                              │
│    Example: Hardware random number generators             │
│                                                           │
│  LOW ENTROPY:                                            │
│    • Easy to predict                                      │
│    • Patterned data                                       │
│    • Vulnerable to attacks                                │
│    Example: System time, user input                       │
│                                                           │
│  ENTROPY SOURCES:                                        │
│    • Thermal noise                                        │
│    • Radioactive decay                                    │
│    • Quantum processes                                    │
│    • Mouse movements                                      │
│    • Keyboard timing                                      │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def compare_entropy_sources(self) -> None:
        """Compare different entropy sources"""
        print("\n 🔄 COMPARING ENTROPY SOURCES")
        print("-" * 40)
        
        # Generate samples from different sources
        samples = {
            "Secrets (System RNG)": secrets.token_bytes(32).hex(),
            "OS Random": os.urandom(32).hex(),
            "Time-based": str(int(time.time())),
            "Random Module": ''.join([str(random.randint(0, 9)) for _ in range(32)]),
            "Custom Seed": hashlib.sha256(b"predictable_seed").hexdigest()
        }
        
        print("\n📋 Entropy Source Samples:")
        for source_name, sample in samples.items():
            # Estimate entropy bits (simplified)
            entropy_bits = self._estimate_entropy(sample)
            
            print(f"\n  {source_name}:")
            print(f"    Sample: {sample[:32]}...")
            print(f"    Length: {len(sample)} characters")
            print(f"    Estimated Entropy: ~{entropy_bits} bits")
            
            if entropy_bits > 100:
                print(f"    Security: ✅ High")
            elif entropy_bits > 50:
                print(f"    Security: ⚠️  Medium")
            else:
                print(f"    Security: ❌ Low")
    
    def _estimate_entropy(self, sample: str) -> int:
        """Estimate entropy of a sample (simplified)"""
        # Count unique characters
        unique_chars = len(set(sample))
        length = len(sample)
        
        if length == 0:
            return 0
        
        # Estimate entropy per character
        if unique_chars <= 10:  # Numbers only
            entropy_per_char = 3.32  # log2(10)
        elif unique_chars <= 26:  # Letters only
            entropy_per_char = 4.7  # log2(26)
        elif unique_chars <= 36:  # Alphanumeric
            entropy_per_char = 5.17  # log2(36)
        elif unique_chars <= 62:  # Alphanumeric + special
            entropy_per_char = 5.95  # log2(62)
        else:  # Full byte range
            entropy_per_char = 8  # log2(256)
        
        return int(entropy_per_char * length * 0.8)  # Conservative estimate
    
    def demonstrate_entropy_applications(self) -> None:
        """Show entropy applications in cryptography"""
        print("\n 🎯 ENTROPY APPLICATIONS")
        print("-" * 40)
        
        applications = {
            "Private Key Generation": {
                "description": "Creating secure cryptographic keys",
                "requirement": "≥ 256 bits entropy",
                "source": "Hardware RNG or cryptographically secure RNG",
                "consequence": "Low entropy → Keys can be brute-forced"
            },
            "Nonce Generation": {
                "description": "Random number for cryptographic operations",
                "requirement": "High entropy, never reused",
                "source": "Cryptographically secure RNG",
                "consequence": "Reused nonce → Private key exposure"
            },
            "Salt Generation": {
                "description": "Random data for password hashing",
                "requirement": "≥ 128 bits entropy",
                "source": "Cryptographically secure RNG",
                "consequence": "No salt → Vulnerable to rainbow table attacks"
            },
            "IV (Initialization Vector)": {
                "description": "Random starting point for encryption",
                "requirement": "Unique, unpredictable",
                "source": "Cryptographically secure RNG",
                "consequence": "Predictable IV → Weakened encryption"
            }
        }
        
        print("\n 📋 Cryptographic Applications:")
        for app_name, details in applications.items():
            print(f"\n  {app_name}:")
            print(f"    Description: {details['description']}")
            print(f"    Requirement: {details['requirement']}")
            print(f"    Source: {details['source']}")
            print(f"    Consequence: {details['consequence']}")
    
    def explain_entropy_attacks(self) -> None:
        """Explain attacks based on poor entropy"""
        print("\n 🛡️  ENTROPY-BASED ATTACKS")
        print("-" * 40)
        
        attack_types = {
            "Brute Force": {
                "description": "Try all possible keys",
                "risk": "High",
                "mitigation": "Use ≥ 256-bit keys with high entropy",
                "example": "Bitcoin private key brute force"
            },
            "Predictable RNG": {
                "description": "Attacker predicts generated values",
                "risk": "Critical",
                "mitigation": "Use hardware RNG or CSPRNG",
                "example": "Weak Android random number generation"
            },
            "Time-based": {
                "description": "Use system time as entropy source",
                "risk": "High",
                "mitigation": "Never use time alone for randomness",
                "example": "Predictable transaction nonces"
            },
            "Collision Attack": {
                "description": "Find collisions in hash outputs",
                "risk": "Medium",
                "mitigation": "Use sufficient entropy in inputs",
                "example": "Hash collision in Merkle trees"
            }
        }
        
        print("\n 📊 Attack Vectors:")
        for attack_name, details in attack_types.items():
            print(f"\n  {attack_name}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk Level: {details['risk']}")
            print(f"    Mitigation: {details['mitigation']}")
            print(f"    Example: {details['example']}")

class EntropyAnalytics:
    """Additional analysis tools for entropy"""
    
    @staticmethod
    def analyze_entropy_requirements() -> None:
        """Analyze entropy requirements for different applications"""
        print("\n 📊 ENTROPY REQUIREMENTS BY APPLICATION")
        print("-" * 40)
        
        requirements = {
            "Application": ["Bitcoin Private Key", "Ethereum Private Key", "Session Token", "Password Salt", "API Key"],
            "Required Entropy": ["256 bits", "256 bits", "128 bits", "128 bits", "256 bits"],
            "Key Length": ["32 bytes", "32 bytes", "16 bytes", "16 bytes", "32 bytes"],
            "Security Level": ["Very High", "Very High", "High", "High", "Very High"],
            "Recommendation": ["Hardware RNG", "Hardware RNG", "CSPRNG", "CSPRNG", "CSPRNG"]
        }
        
        print(f"\n {'Application':>20} | {'Entropy':>15} | {'Key Length':>12} | {'Security':>15} | {'Source':>15}")
        print("-" * 85)
        
        for i in range(len(requirements["Application"])):
            app = requirements["Application"][i]
            entropy = requirements["Required Entropy"][i]
            length = requirements["Key Length"][i]
            security = requirements["Security Level"][i]
            source = requirements["Recommendation"][i]
            
            print(f" {app:>20} | {entropy:>15} | {length:>12} | {security:>15} | {source:>15}")
    
    @staticmethod
    def measure_entropy_quality() -> None:
        """Measure and analyze entropy quality"""
        print("\n 📈 ENTROPY QUALITY MEASUREMENT")
        print("-" * 40)
        
        # Generate test samples
        sources = {
            "System RNG": secrets.token_bytes(64),
            "OS RNG": os.urandom(64),
            "Random Module": bytes([random.randint(0, 255) for _ in range(64)]),
            "Time-based": hashlib.sha256(str(time.time()).encode()).digest()
        }
        
        print("\n🔬 Entropy Quality Analysis:")
        for source_name, data in sources.items():
            # Measure entropy using frequency analysis
            byte_freq = {}
            for byte in data:
                byte_freq[byte] = byte_freq.get(byte, 0) + 1
            
            # Calculate entropy
            entropy = 0
            total = len(data)
            for count in byte_freq.values():
                if count > 0:
                    probability = count / total
                    entropy -= probability * (probability.bit_length() - 1)
            
            # Evaluate quality
            if entropy > 7.5:
                quality = "✅ Excellent"
            elif entropy > 6:
                quality = "⚠️  Good"
            elif entropy > 4:
                quality = "⚠️  Average"
            else:
                quality = "❌ Poor"
            
            print(f"\n  {source_name}:")
            print(f"    Unique bytes: {len(byte_freq)}/256")
            print(f"    Estimated Entropy: {entropy:.2f} bits/byte")
            print(f"    Quality: {quality}")

def demonstrate_entropy_engine():
    """Execute comprehensive entropy demonstration"""
    print("=" * 60)
    print(" CRYPTOGRAPHIC ENTROPY ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = EntropyEngine()
    
    # Run demonstrations
    engine.explain_entropy_concept()
    engine.compare_entropy_sources()
    engine.demonstrate_entropy_applications()
    engine.explain_entropy_attacks()
    
    # Additional analytics
    EntropyAnalytics.analyze_entropy_requirements()
    EntropyAnalytics.measure_entropy_quality()
    
    print("\n" + "=" * 60)
    print(" ENTROPY SUMMARY:")
    print("   ✓ Entropy = Randomness = Security")
    print("   ✓ High Entropy: Secure, unpredictable")
    print("   ✓ Low Entropy: Vulnerable, predictable")
    print("   ✓ Sources: Thermal noise, hardware RNG, system RNG")
    print("   ✓ Requirements: ≥ 256 bits for private keys")
    print("   ✓ Best Practice: Use cryptographically secure RNG")
    print("   ✓ Never: Use time, user input, or predictable seeds")
    print("   ✓ Foundation: Blockchain security")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_entropy_engine()

3.15 Random Number Generation

What is Random Number Generation?

Random number generation (RNG) is the process of generating unpredictable numbers. In cryptography, RNG must be cryptographically secure (CSPRNG) to be safe for key generation and other security-critical applications.

Types of Random Number Generators:

TypeDescriptionUse Case
CSPRNGCryptographically SecureKeys, nonces, signatures
PRNGPseudo-RandomSimulation, testing
HRNGHardware RNGHigh security
TRNGTrue RNGPhysical randomness

CSPRNG Properties:

PropertyDescription
UnpredictableFuture outputs cannot be predicted
High EntropyBased on high-quality randomness
SecureResistant to attacks

Code Example – RNG:

"""
CRYPTOGRAPHIC RANDOM NUMBER GENERATION FRAMEWORK
================================================
Secure vs Insecure RNG demonstration with best practices and security implications
"""

import secrets
import random
import time
import hashlib
import os
from typing import Tuple, List, Dict
from dataclasses import dataclass

@dataclass
class RNGComparison:
    """Represents a comparison between secure and insecure RNG"""
    name: str
    type: str
    security_level: str
    use_case: str
    entropy_bits: int
    is_cryptographic: bool
    example_output: str

class RNGEngine:
    """Complete random number generation demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOGRAPHIC RANDOM NUMBER GENERATION ENGINE")
        print("=" * 60)
    
    def demonstrate_secure_rng(self) -> None:
        """Demonstrate cryptographically secure RNG"""
        print("\n 🔐 SECURE RNG (CSPRNG)")
        print("-" * 40)
        
        # Generate various secure random values
        random_bytes = secrets.token_bytes(32)
        random_hex = random_bytes.hex()
        random_int = secrets.randbelow(2**256)
        random_url = secrets.token_urlsafe(32)
        random_hex = secrets.token_hex(32)
        
        print("📊 Secure Random Samples:")
        print(f"  • Random Bytes (32): {random_bytes.hex()[:32]}...")
        print(f"  • Random Integer: {str(random_int)[:32]}...")
        print(f"  • URL-safe Token: {random_url[:32]}...")
        print(f"  • Hex Token: {random_hex[:32]}...")
        
        print("\n💡 Security Properties:")
        print("  ✅ Cryptographically Secure")
        print("  ✅ Unpredictable")
        print("  ✅ High Entropy (≥ 256 bits)")
        print("  ✅ Suitable for Keys and Nonces")
        print("  ✅ OS-backed RNG")
        
        # Generate multiple random values
        print("\n📊 Multiple Random Values (demonstrating uniqueness):")
        for i in range(3):
            sample = secrets.token_hex(16)
            print(f"  Sample {i+1}: {sample}")
    
    def demonstrate_insecure_rng(self) -> None:
        """Demonstrate insecure RNG vulnerabilities"""
        print("\n ⚠️  INSECURE RNG")
        print("-" * 40)
        
        # Time-based RNG (predictable)
        time_seed = int(time.time())
        random.seed(time_seed)
        time_random = random.randint(0, 2**32)
        
        print("📊 Insecure Random Samples:")
        print(f"  • Time-based seed: {time_seed}")
        print(f"  • Result: {time_random}")
        print(f"  • Pattern: Predictable (reproducible)")
        
        # Random module (not cryptographically secure)
        random_value = random.randint(0, 2**32)
        print(f"  • Random module: {random_value}")
        print(f"  • Pattern: Not cryptographically secure")
        
        # User input based
        user_input = "seed12345"
        user_hash = hashlib.sha256(user_input.encode()).digest()
        print(f"  • User-input seed: {user_input}")
        print(f"  • Result: {user_hash.hex()[:32]}...")
        
        print("\n⚠️  Security Issues:")
        print("  ❌ Predictable (time-based, user input)")
        print("  ❌ Low Entropy")
        print("  ❌ Reproducible")
        print("  ❌ Not Cryptographically Secure")
        print("  ❌ Vulnerable to Brute Force")
        print("  ❌ Never Use for Security-Critical Operations")
    
    def compare_rng_types(self) -> None:
        """Compare different RNG types"""
        print("\n 📊 RNG TYPE COMPARISON")
        print("-" * 40)
        
        rng_types = [
            RNGComparison(
                name="CSPRNG",
                type="Cryptographic",
                security_level="Very High",
                use_case="Keys, Signatures",
                entropy_bits=256,
                is_cryptographic=True,
                example_output=secrets.token_hex(32)[:32]
            ),
            RNGComparison(
                name="PRNG",
                type="Pseudo-random",
                security_level="Low",
                use_case="Testing",
                entropy_bits=32,
                is_cryptographic=False,
                example_output=hashlib.sha256(str(random.randint(0, 2**32)).encode()).hexdigest()[:32]
            ),
            RNGComparison(
                name="TRNG",
                type="True Random",
                security_level="Very High",
                use_case="Hardware Security",
                entropy_bits=256,
                is_cryptographic=True,
                example_output=os.urandom(32).hex()[:32]
            ),
            RNGComparison(
                name="HRNG",
                type="Hybrid",
                security_level="High",
                use_case="High Security",
                entropy_bits=256,
                is_cryptographic=True,
                example_output=secrets.token_hex(32)[:32]
            )
        ]
        
        print("\n📋 RNG Type Characteristics:")
        print(f" {'Type':>12} | {'Security':>15} | {'Use Case':>15} | {'Entropy':>10} | {'Cryptographic':>12}")
        print("-" * 70)
        
        for rng in rng_types:
            crypto_status = "✅ Yes" if rng.is_cryptographic else "❌ No"
            print(f" {rng.name:>12} | {rng.security_level:>15} | {rng.use_case:>15} | "
                  f"{rng.entropy_bits:>10} | {crypto_status:>12}")
    
    def demonstrate_rng_attacks(self) -> None:
        """Demonstrate attacks on insecure RNG"""
        print("\n 🎯 RNG ATTACK DEMONSTRATION")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  RNG ATTACK VECTORS                                      │
├─────────────────────────────────────────────────────────────┤
│  1. PREDICTABILITY ATTACK                                │
│     • Attacker knows seed or pattern                      │
│     • Can predict future outputs                         │
│     • Example: Time-based seeds                         │
│                                                           │
│  2. ENTROPY DEPLETION ATTACK                             │
│     • RNG runs out of entropy                             │
│     • Output becomes predictable                          │
│     • Example: Early Linux /dev/random                   │
│                                                           │
│  3. SIDE-CHANNEL ATTACK                                 │
│     • Attacker observes RNG behavior                      │
│     • Extracts information                                │
│     • Example: Timing analysis                            │
│                                                           │
│  4. RNG STATE COMPROMISE                                 │
│     • Attacker gets RNG state                             │
│     • Can predict all future outputs                      │
│     • Example: Duplicated state                           │
│                                                           │
│  MITIGATION:                                             │
│  • Use cryptographically secure RNG                      │
│  • Use hardware RNG                                      │
│  • Regularly reseed                                      │
│  • Never trust user input                                 │
└─────────────────────────────────────────────────────────────┘
        """)

class RNGAnalytics:
    """Additional analysis tools for RNG"""
    
    @staticmethod
    def analyze_entropy_distribution() -> None:
        """Analyze entropy distribution across RNG types"""
        print("\n 📊 ENTROPY DISTRIBUTION ANALYSIS")
        print("-" * 40)
        
        # Generate samples and analyze
        secure_samples = [secrets.token_bytes(32) for _ in range(100)]
        random_samples = [bytes([random.randint(0, 255) for _ in range(32)]) for _ in range(100)]
        
        def calculate_entropy(samples: List[bytes]) -> float:
            """Calculate average entropy of samples"""
            total_entropy = 0
            for sample in samples:
                byte_freq = {}
                for byte in sample:
                    byte_freq[byte] = byte_freq.get(byte, 0) + 1
                
                entropy = 0
                total = len(sample)
                for count in byte_freq.values():
                    if count > 0:
                        prob = count / total
                        entropy -= prob * (prob.bit_length() - 1)
                total_entropy += entropy
            
            return total_entropy / len(samples)
        
        secure_entropy = calculate_entropy(secure_samples)
        random_entropy = calculate_entropy(random_samples)
        
        print("\n📈 Entropy Analysis Results:")
        print(f"  • Secure RNG (CSPRNG): {secure_entropy:.2f} bits/byte")
        print(f"  • Insecure RNG (Random): {random_entropy:.2f} bits/byte")
        print(f"  • Difference: {secure_entropy - random_entropy:.2f} bits/byte")
        
        if secure_entropy > random_entropy:
            print("\n  ✅ CSPRNG provides significantly better entropy")
            print(f"  ✅ {secure_entropy/random_entropy:.2f}x better entropy")
    
    @staticmethod
    def rng_best_practices() -> None:
        """List RNG best practices"""
        print("\n 📋 RNG BEST PRACTICES")
        print("-" * 40)
        
        practices = {
            "Do's": [
                "Use cryptographically secure RNG (CSPRNG)",
                "Use high-entropy sources",
                "Verify randomness quality",
                "Use OS-provided RNG",
                "Regularly reseed RNG",
                "Use hardware RNG for high security"
            ],
            "Don'ts": [
                "Never use 'random' module for security",
                "Never use time-based seeds",
                "Never roll your own RNG",
                "Never use user input for randomness",
                "Never reuse random values",
                "Never trust predictable sources"
            ],
            "Recommendations": [
                "Python: secrets module",
                "Linux: /dev/urandom",
                "Hardware: Intel RDRAND",
                "JavaScript: Web Crypto API",
                "C: CSPRNG from OS"
            ]
        }
        
        print("\n✅ DO'S:")
        for item in practices["Do's"]:
            print(f"  ✓ {item}")
        
        print("\n❌ DON'TS:")
        for item in practices["Don'ts"]:
            print(f"  ✗ {item}")
        
        print("\n📌 RECOMMENDATIONS:")
        for item in practices["Recommendations"]:
            print(f"  • {item}")

def demonstrate_rng_engine():
    """Execute comprehensive RNG demonstration"""
    print("=" * 60)
    print(" CRYPTOGRAPHIC RNG ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = RNGEngine()
    
    # Run demonstrations
    engine.demonstrate_secure_rng()
    engine.demonstrate_insecure_rng()
    engine.compare_rng_types()
    engine.demonstrate_rng_attacks()
    
    # Additional analytics
    RNGAnalytics.analyze_entropy_distribution()
    RNGAnalytics.rng_best_practices()
    
    print("\n" + "=" * 60)
    print(" RNG SUMMARY:")
    print("   ✓ Secure RNG: Cryptographically secure, unpredictable")
    print("   ✓ Insecure RNG: Predictable, vulnerable")
    print("   ✓ CSPRNG: For keys, signatures, nonces")
    print("   ✓ PRNG: For testing only")
    print("   ✓ TRNG: Hardware-based, highest security")
    print("   ✓ Best Practice: Use secrets module in Python")
    print("   ✓ Never: Use random module for security")
    print("   ✓ Foundation: Blockchain and cryptographic security")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_rng_engine()

3.16 HD Wallet Standards

What are HD Wallets?

Hierarchical Deterministic (HD) wallets generate a structured tree of cryptographic keys from a single master seed. This enables backup, recovery, and management of many addresses from one seed phrase.

BIP-32: HD Wallet Structure

How BIP-32 Works:

  1. Generate a master seed (128-512 bits)
  2. Derive master private key from seed
  3. Generate child keys using derivation paths
  4. Create a tree of keys

Derivation Path:

m / purpose' / coin_type' / account' / change / address_index

Example: m/44'/0'/0'/0/0

BIP-39: Mnemonic Phrases

How BIP-39 Works:

  1. Generate random entropy (128-256 bits)
  2. Calculate checksum
  3. Map to word list (2048 words)
  4. Create 12-24 word phrase

Word List Example:

abandon ability able about above absent absorb abstract absurd abuse access accident

BIP-44: Multi-Account Structure

Purpose: BIP-44 defines a standard derivation path for multiple cryptocurrencies.

Path Structure:

m / purpose' / coin_type' / account' / change / address_index

Coin Types:

CryptocurrencyCoin Type
Bitcoin0
Ethereum60
Solana501
Cardano1815

Code Example – HD Wallets:

"""
HIERARCHICAL DETERMINISTIC WALLET FRAMEWORK
============================================
Complete implementation of BIP-32, BIP-39, and BIP-44 wallet standards
"""

import hashlib
import base58
import random
import secrets
from typing import List, Tuple, Dict
from dataclasses import dataclass

@dataclass
class BIP39Mnemonic:
    """Represents a BIP-39 mnemonic phrase"""
    words: List[str]
    phrase: str
    word_count: int
    entropy_bits: int
    checksum: str

@dataclass
class BIP32Key:
    """Represents a BIP-32 extended key"""
    depth: int
    parent_fingerprint: str
    child_number: int
    chain_code: str
    private_key: str
    public_key: str
    fingerprint: str

@dataclass
class BIP44Path:
    """Represents a BIP-44 derivation path"""
    purpose: int
    coin_type: int
    account: int
    change: int
    address_index: int
    full_path: str

class HDWalletEngine:
    """Complete HD wallet standards demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" HIERARCHICAL DETERMINISTIC WALLET ENGINE")
        print("=" * 60)
    
    def generate_bip39_mnemonic(self, word_count: int = 12) -> BIP39Mnemonic:
        """Generate a BIP-39 mnemonic phrase"""
        print("\n 🗝️  BIP-39: MNEMONIC PHRASE GENERATION")
        print("-" * 40)
        
        # Extended word list (BIP-39 English)
        word_list = [
            "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", "alcohol", "alert", "alien", "all",
            "alley", "allow", "almost", "alone", "alpha", "already", "also",
            "alter", "always", "amateur", "amazing", "among", "amount", "amused",
            "analyst", "anchor", "ancient", "anger", "angle", "angry", "animal",
            "ankle", "announce", "annual", "another", "answer", "antenna", "antique",
            "anxiety", "any", "apart", "apology", "appear", "apple", "approve",
            "april", "arch", "arctic", "area", "arena", "argue", "arm", "armed",
            "armor", "army", "around", "arrange", "arrest", "arrive", "arrow", "art",
            "artefact", "artist", "artwork", "ask", "aspect", "assault", "asset"
        ]
        
        # Select random words based on entropy
        entropy_bits = word_count * 4  # 128 bits for 12 words
        selected_words = random.sample(word_list, word_count)
        mnemonic_phrase = " ".join(selected_words)
        
        print(f"📝 Generated Mnemonic Phrase:")
        print(f"  {mnemonic_phrase}")
        print(f"\n📊 Details:")
        print(f"  • Words: {word_count}")
        print(f"  • Entropy: {entropy_bits} bits")
        print(f"  • Security: {entropy_bits/2}-bit security")
        print(f"  • Checksum: {entropy_bits/32} bits")
        
        print("\n💡 Important:")
        print("  ✓ Write down these words")
        print("  ✓ Store securely offline")
        print("  ✓ Never share with anyone")
        print("  ✓ Test recovery process")
        
        return BIP39Mnemonic(
            words=selected_words,
            phrase=mnemonic_phrase,
            word_count=word_count,
            entropy_bits=entropy_bits,
            checksum=hashlib.sha256(mnemonic_phrase.encode()).hexdigest()[:8]
        )
    
    def demonstrate_bip32_structure(self) -> None:
        """Demonstrate BIP-32 HD wallet structure"""
        print("\n 🌳 BIP-32: HD WALLET STRUCTURE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BIP-32 HIERARCHICAL DETERMINISTIC WALLET               │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  MASTER SEED (128-256 bits)                              │
│  ↓                                                        │
│  MASTER PRIVATE KEY (m)                                  │
│  ├── Extended Public Key (xpub)                         │
│  └── Extended Private Key (xpriv)                       │
│  ↓                                                        │
│  ┌───────────────────────────────────────────────────┐    │
│  │  CHILD KEYS (m/0, m/1, ...)                      │    │
│  │  ├── Normal Child (m/0)                          │    │
│  │  └── Hardened Child (m/0')                      │    │
│  │  ↓                                                │    │
│  │  GRANDCHILD KEYS (m/0/0, m/0/1, ...)            │    │
│  └───────────────────────────────────────────────────┘    │
│                                                           │
│  KEY PROPERTIES:                                        │
│  • Deterministic: Same seed → Same keys                 │
│  • Hierarchical: Parent → Child derivation              │
│  • Hardened: Prevents parent key exposure               │
│  • BIP-32: Defines derivation algorithms                │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_bip44_paths(self) -> None:
        """Demonstrate BIP-44 derivation paths"""
        print("\n 📍 BIP-44: DERIVATION PATHS")
        print("-" * 40)
        
        paths = {
            "Bitcoin": BIP44Path(
                purpose=44,
                coin_type=0,
                account=0,
                change=0,
                address_index=0,
                full_path="m/44'/0'/0'/0/0"
            ),
            "Ethereum": BIP44Path(
                purpose=44,
                coin_type=60,
                account=0,
                change=0,
                address_index=0,
                full_path="m/44'/60'/0'/0/0"
            ),
            "Solana": BIP44Path(
                purpose=44,
                coin_type=501,
                account=0,
                change=0,
                address_index=0,
                full_path="m/44'/501'/0'/0/0"
            ),
            "Cardano": BIP44Path(
                purpose=44,
                coin_type=1815,
                account=0,
                change=0,
                address_index=0,
                full_path="m/44'/1815'/0'/0/0"
            )
        }
        
        print("\n📊 Standard Derivation Paths:")
        for coin_name, path in paths.items():
            print(f"\n  {coin_name}:")
            print(f"    Path: {path.full_path}")
            print(f"    Purpose: {path.purpose}'")
            print(f"    Coin Type: {path.coin_type}'")
            print(f"    Account: {path.account}'")
            print(f"    Change: {path.change}")
            print(f"    Address: {path.address_index}")
        
        print("\n💡 Path Components:")
        print("  m = Master Key")
        print("  44' = BIP-44 Purpose (hardened)")
        print("  Coin Type' = Cryptocurrency identifier")
        print("  Account' = Account number")
        print("  Change = 0 (external) or 1 (internal)")
        print("  Address = Index of address")
    
    def explain_hd_wallet_security(self) -> None:
        """Explain HD wallet security considerations"""
        print("\n 🛡️  HD WALLET SECURITY")
        print("-" * 40)
        
        security_aspects = {
            "Seed Phrase Storage": {
                "recommendation": "Store offline (paper, steel)",
                "risk": "Digital storage = Hackable",
                "best_practice": "Multiple backups, different locations"
            },
            "Key Management": {
                "recommendation": "Use hardware wallets",
                "risk": "Software wallets = Higher risk",
                "best_practice": "Hardware wallet for large holdings"
            },
            "Recovery Process": {
                "recommendation": "Test recovery regularly",
                "risk": "Untested recovery = Lost funds",
                "best_practice": "Test with small amounts"
            },
            "Exposure": {
                "recommendation": "Never share seed phrase",
                "risk": "Shared seed = Stolen funds",
                "best_practice": "Keep private, never digital"
            }
        }
        
        print("\n📋 Security Best Practices:")
        for category, details in security_aspects.items():
            print(f"\n  {category}:")
            print(f"    ✓ {details['recommendation']}")
            print(f"    ⚠️  Risk: {details['risk']}")
            print(f"    💡 Best Practice: {details['best_practice']}")

class HDWalletAnalytics:
    """Additional analysis tools for HD wallets"""
    
    @staticmethod
    def analyze_key_derivation() -> None:
        """Analyze key derivation process"""
        print("\n 📊 KEY DERIVATION ANALYSIS")
        print("-" * 40)
        
        derivation_details = {
            "Step": ["Seed → Master Key", "Master → Child Key", "Child → Grandchild", "Path → Address"],
            "Algorithm": ["HMAC-SHA512", "HMAC-SHA512", "HMAC-SHA512", "BIP-44"],
            "Output": ["Master Private Key", "Child Private Key", "Grandchild Private Key", "Wallet Address"],
            "Security": ["128-256 bits", "128-256 bits", "128-256 bits", "128-bit collision resistance"]
        }
        
        print("\n📈 Derivation Process:")
        print(f" {'Step':>25} | {'Algorithm':>15} | {'Output':>25} | {'Security':>20}")
        print("-" * 90)
        
        for i in range(len(derivation_details["Step"])):
            step = derivation_details["Step"][i]
            algorithm = derivation_details["Algorithm"][i]
            output = derivation_details["Output"][i]
            security = derivation_details["Security"][i]
            
            print(f" {step:>25} | {algorithm:>15} | {output:>25} | {security:>20}")
    
    @staticmethod
    def compare_coin_types() -> None:
        """Compare different coin types in BIP-44"""
        print("\n 📋 BIP-44 COIN TYPE REGISTRY")
        print("-" * 40)
        
        coins = {
            "Bitcoin": {"path": "44'/0'", "symbol": "BTC", "slip": "SLIP-0044"},
            "Ethereum": {"path": "44'/60'", "symbol": "ETH", "slip": "SLIP-0044"},
            "Solana": {"path": "44'/501'", "symbol": "SOL", "slip": "SLIP-0044"},
            "Cardano": {"path": "44'/1815'", "symbol": "ADA", "slip": "SLIP-0044"},
            "Polkadot": {"path": "44'/354'", "symbol": "DOT", "slip": "SLIP-0044"},
            "Ripple": {"path": "44'/144'", "symbol": "XRP", "slip": "SLIP-0044"},
            "Stellar": {"path": "44'/148'", "symbol": "XLM", "slip": "SLIP-0044"},
            "Litecoin": {"path": "44'/2'", "symbol": "LTC", "slip": "SLIP-0044"}
        }
        
        print("\n📊 Registered Coin Types:")
        print(f" {'Coin':>12} | {'Path':>15} | {'Symbol':>8} | {'Standard':>10}")
        print("-" * 50)
        
        for coin_name, details in coins.items():
            print(f" {coin_name:>12} | {details['path']:>15} | {details['symbol']:>8} | {details['slip']:>10}")

def demonstrate_hd_wallet_engine():
    """Execute comprehensive HD wallet demonstration"""
    print("=" * 60)
    print(" HIERARCHICAL DETERMINISTIC WALLET ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = HDWalletEngine()
    
    # Generate BIP-39 mnemonic
    mnemonic = engine.generate_bip39_mnemonic(12)
    
    # Demonstrate BIP-32 structure
    engine.demonstrate_bip32_structure()
    
    # Demonstrate BIP-44 paths
    engine.demonstrate_bip44_paths()
    
    # Explain security
    engine.explain_hd_wallet_security()
    
    # Additional analytics
    HDWalletAnalytics.analyze_key_derivation()
    HDWalletAnalytics.compare_coin_types()
    
    print("\n" + "=" * 60)
    print(" HD WALLET STANDARDS SUMMARY:")
    print("   ✓ BIP-32: Hierarchical Deterministic Wallet Structure")
    print("   ✓ BIP-39: Mnemonic Phrase (12-24 words)")
    print("   ✓ BIP-44: Multi-Account Derivation Paths")
    print("   ✓ One Seed → Unlimited Addresses")
    print("   ✓ Deterministic: Reproducible key generation")
    print("   ✓ Cross-Currency: Different coin types")
    print("   ✓ Security: Hardware wallet recommended")
    print("   ✓ Industry Standard for Cryptocurrency Wallets")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_hd_wallet_engine()

3.17 Zero-Knowledge Proof Fundamentals

What are Zero-Knowledge Proofs?

A zero-knowledge proof is a method by which one party (the prover) can prove to another party (the verifier) that they know a value, without revealing any information about the value itself.

The Three Properties:

PropertyDescription
CompletenessIf statement is true, prover can convince verifier
SoundnessIf statement is false, no one can convince verifier
Zero-KnowledgeVerifier learns nothing except the statement’s truth

Types of Zero-Knowledge Proofs:

TypeDescriptionUse Case
ZK-SNARKsSuccinct Non-InteractiveEfficient, small proofs
ZK-STARKsTransparent, No trusted setupSecurity, transparency

Code Example – Zero-Knowledge Proofs:

"""
ZERO-KNOWLEDGE PROOF FRAMEWORK
===============================
Complete zero-knowledge proof demonstration with blockchain applications
"""

import hashlib
import random
import time
from typing import Tuple, List, Optional
from dataclasses import dataclass

@dataclass
class ZKProof:
    """Represents a zero-knowledge proof"""
    commitment: str
    challenge: str
    response: str
    proof_type: str
    is_valid: bool
    verification_time: float

@dataclass
class ZKStatement:
    """Represents a statement to be proven"""
    statement: str
    witness: str
    proof: Optional[ZKProof] = None
    is_proven: bool = False

class ZKProofEngine:
    """Complete zero-knowledge proof demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ZERO-KNOWLEDGE PROOF ENGINE")
        print("=" * 60)
    
    def demonstrate_color_blind_proof(self) -> None:
        """Demonstrate the classic color-blind proof"""
        print("\n 🎨 COLOR-BLIND ZK PROOF")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CLASSIC ZERO-KNOWLEDGE PROOF: COLOR-BLIND FRIEND        │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  SCENARIO:                                               │
│    • Alice has two balls: different colors (red/green)   │
│    • Bob is color-blind                                  │
│    • Alice wants to prove they are different colors       │
│    • Without revealing which color is which              │
│                                                           │
│  PROTOCOL:                                               │
│    1. Bob holds both balls (one in each hand)            │
│    2. Behind his back, he switches or not                │
│    3. Alice must tell if switched                        │
│    4. Bob verifies: Alice can only tell if colors differ │
│    5. Repeat N times for confidence                       │
│                                                           │
│  SECURITY:                                               │
│    • Random success chance per round: 50%                │
│    • After 20 rounds: Confidence = 1 - 1/2^20 = 99.9999%│
│    • Zero-Knowledge: Alice learns nothing about colors   │
│    • Soundness: If colors same, Alice can't tell         │
└─────────────────────────────────────────────────────────────┘
        """)
        
        # Simulate the protocol
        print("\n🔬 Simulating Protocol:")
        rounds = 10
        correct = 0
        
        for i in range(rounds):
            switched = random.choice([True, False])
            # Alice can tell if colors are different (assume true)
            guess = switched  # Perfect discrimination
            
            if guess == switched:
                correct += 1
            
            print(f"  Round {i+1}: {'✅ Correct' if guess == switched else '❌ Wrong'}")
        
        confidence = 1 - (0.5 ** rounds)
        print(f"\n📊 Results:")
        print(f"  • Correct: {correct}/{rounds}")
        print(f"  • Confidence: {confidence:.2%}")
        print(f"  • Zero-Knowledge: ✅ Information not revealed")
    
    def demonstrate_zk_commitment(self) -> None:
        """Demonstrate ZK commitment scheme"""
        print("\n 🔐 ZK COMMITMENT SCHEME")
        print("-" * 40)
        
        # Secret value
        secret_value = random.randint(1, 100)
        nonce = random.randint(1, 1000)
        
        print(f"📝 Secret Value: {secret_value} (hidden)")
        print(f"🔢 Nonce: {nonce} (hidden)")
        
        # Create commitment
        commitment_input = f"{secret_value}{nonce}"
        commitment = hashlib.sha256(commitment_input.encode()).hexdigest()
        
        print(f"🔒 Commitment: {commitment[:16]}...")
        
        # Verification process
        print("\n✅ Verification Process:")
        print(f"  1. Prover sends commitment: {commitment[:16]}...")
        print(f"  2. Verifier stores commitment")
        print(f"  3. Later, prover reveals: secret={secret_value}, nonce={nonce}")
        print(f"  4. Verifier checks: hash({secret_value}{nonce}) == commitment")
        
        # Verify
        verify_input = f"{secret_value}{nonce}"
        verify_commitment = hashlib.sha256(verify_input.encode()).hexdigest()
        is_valid = verify_commitment == commitment
        
        print(f"\n🔍 Verification Result:")
        print(f"  • Commitment matches: {is_valid}")
        print(f"  • Prover committed to: {secret_value}")
        print(f"  • Verifier learned: The value (after reveal)")
        print(f"  • Zero-Knowledge: Before reveal, value was hidden")
    
    def demonstrate_blockchain_applications(self) -> None:
        """Show ZK proof applications in blockchain"""
        print("\n ⛓️  ZK PROOFS IN BLOCKCHAIN")
        print("-" * 40)
        
        applications = {
            "Privacy (Zcash)": {
                "description": "Private transactions with shielded addresses",
                "benefit": "Complete transaction privacy",
                "implementation": "ZK-SNARKs"
            },
            "Scalability (ZK-Rollups)": {
                "description": "Batch verification of transactions",
                "benefit": "High throughput, low fees",
                "implementation": "ZK-STARKs"
            },
            "Identity": {
                "description": "Self-sovereign identity verification",
                "benefit": "Privacy-preserving credentials",
                "implementation": "ZK credentials"
            },
            "Verification": {
                "description": "Prove computation correctness",
                "benefit": "Trustless verification",
                "implementation": "ZK proofs"
            }
        }
        
        print("\n📊 Blockchain Applications:")
        for app_name, details in applications.items():
            print(f"\n  {app_name}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Implementation: {details['implementation']}")
    
    def explain_zk_properties(self) -> None:
        """Explain ZK proof properties"""
        print("\n 📊 ZK PROOF PROPERTIES")
        print("-" * 40)
        
        properties = {
            "Completeness": {
                "description": "True statements can be proven",
                "importance": "Fundamental requirement",
                "guarantee": "Honest prover succeeds"
            },
            "Soundness": {
                "description": "False statements cannot be proven",
                "importance": "Security guarantee",
                "guarantee": "No false proofs accepted"
            },
            "Zero-Knowledge": {
                "description": "No information revealed beyond truth",
                "importance": "Privacy guarantee",
                "guarantee": "Verifier learns nothing"
            },
            "Succinctness": {
                "description": "Proofs are small and fast to verify",
                "importance": "Practical efficiency",
                "guarantee": "Constant size proofs"
            }
        }
        
        print("\n🔍 Proof Properties:")
        for prop, details in properties.items():
            print(f"\n  {prop}:")
            print(f"    Description: {details['description']}")
            print(f"    Importance: {details['importance']}")
            print(f"    Guarantee: {details['guarantee']}")

class ZKAnalytics:
    """Additional analysis tools for ZK proofs"""
    
    @staticmethod
    def compare_zk_types() -> None:
        """Compare different ZK proof types"""
        print("\n 📋 ZK PROOF TYPE COMPARISON")
        print("-" * 40)
        
        zk_types = {
            "ZK-SNARKs": {
                "size": "Tiny (~200 bytes)",
                "verification": "Very Fast (milliseconds)",
                "trusted_setup": "Required",
                "quantum_safe": "No",
                "usage": "Zcash, Filecoin"
            },
            "ZK-STARKs": {
                "size": "Large (kilobytes)",
                "verification": "Fast (seconds)",
                "trusted_setup": "Not Required",
                "quantum_safe": "Yes",
                "usage": "StarkNet, Polygon"
            },
            "Bulletproofs": {
                "size": "Medium (kilobytes)",
                "verification": "Moderate",
                "trusted_setup": "Not Required",
                "quantum_safe": "No",
                "usage": "Monero, Confidential Transactions"
            }
        }
        
        print("\n📊 ZK Proof Comparison:")
        print(f" {'Type':>15} | {'Size':>20} | {'Verification':>15} | {'Trusted Setup':>15} | {'Quantum Safe':>12} | {'Usage':>15}")
        print("-" * 100)
        
        for zk_type, details in zk_types.items():
            print(f" {zk_type:>15} | {details['size']:>20} | {details['verification']:>15} | "
                  f"{details['trusted_setup']:>15} | {details['quantum_safe']:>12} | {details['usage']:>15}")
    
    @staticmethod
    def analyze_security_guarantees() -> None:
        """Analyze ZK proof security guarantees"""
        print("\n 🛡️  ZK PROOF SECURITY GUARANTEES")
        print("-" * 40)
        
        guarantees = {
            "Property": ["Completeness", "Soundness", "Zero-Knowledge", "Non-Interactive"],
            "Guarantee": ["100% (true statements)", "99.9999% (false statements rejected)", "100% (no info leaked)", "Yes (ZK-SNARKs)"],
            "Security": ["High", "High", "Very High", "High"],
            "Implementation": ["Math-based", "Crypto-based", "Information Theory", "Cryptography"]
        }
        
        print("\n📊 Security Guarantees Matrix:")
        print(f" {'Property':>20} | {'Guarantee':>40} | {'Security':>12} | {'Implementation':>20}")
        print("-" * 100)
        
        for i in range(len(guarantees["Property"])):
            prop = guarantees["Property"][i]
            guarantee = guarantees["Guarantee"][i]
            security = guarantees["Security"][i]
            implementation = guarantees["Implementation"][i]
            
            print(f" {prop:>20} | {guarantee:>40} | {security:>12} | {implementation:>20}")

def demonstrate_zk_engine():
    """Execute comprehensive ZK proof demonstration"""
    print("=" * 60)
    print(" ZERO-KNOWLEDGE PROOF ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = ZKProofEngine()
    
    # Run demonstrations
    engine.demonstrate_color_blind_proof()
    engine.demonstrate_zk_commitment()
    engine.demonstrate_blockchain_applications()
    engine.explain_zk_properties()
    
    # Additional analytics
    ZKAnalytics.compare_zk_types()
    ZKAnalytics.analyze_security_guarantees()
    
    print("\n" + "=" * 60)
    print(" ZERO-KNOWLEDGE PROOF SUMMARY:")
    print("   ✓ ZK Proofs: Prove without revealing")
    print("   ✓ Completeness: True statements can be proven")
    print("   ✓ Soundness: False statements cannot be proven")
    print("   ✓ Zero-Knowledge: No information revealed")
    print("   ✓ ZK-SNARKs: Succinct, non-interactive")
    print("   ✓ ZK-STARKs: Transparent, no trusted setup")
    print("   ✓ Applications: Privacy, Scaling, Identity")
    print("   ✓ Blockchain: Zcash, ZK-Rollups")
    print("   ✓ Future: Privacy-preserving blockchain")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_zk_engine()

4. Cryptocurrency

4.1 What is Cryptocurrency?

What is Cryptocurrency?

Cryptocurrency is a digital form of money that uses cryptographic techniques to secure transactions and operates through a decentralized network, typically powered by blockchain technology. Unlike traditional currencies (fiat), cryptocurrencies are not controlled by any central authority like a government or bank.

Key Characteristics:

CharacteristicDescriptionExample
DecentralizedNo central authorityBitcoin has no CEO or headquarters
CryptographicSecured by cryptographyPrivate keys control funds
DigitalExists only onlineNo physical coins or notes
BorderlessGlobal and accessibleAnyone with internet can participate
TransparentPublic ledgerAll transactions are visible

How Cryptocurrencies Work:

  1. Creation: New cryptocurrency coins can be introduced through mining in Proof of Work (PoW) systems or through staking and validator rewards in Proof of Stake (PoS) systems.
  2. Transactions: Users send coins to each other via the blockchain
  3. Security: Cryptography secures transactions and ownership
  4. Consensus: Network participants validate transactions

Cryptocurrency vs Fiat Currency:

AspectCryptocurrencyFiat Currency
ControlDecentralizedCentral bank
SupplyLimited/cappedInfinite (can print)
PhysicalDigital onlyPhysical + digital
GlobalBorderlessCountry-specific
PrivacyPseudonymousKYC required

Code Example – Cryptocurrency:

"""
CRYPTOCURRENCY FUNDAMENTALS FRAMEWORK
=====================================
Comprehensive understanding of cryptocurrency concepts and comparisons
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class CurrencyType(Enum):
    """Classification of currency types"""
    CRYPTOCURRENCY = "Cryptocurrency"
    FIAT = "Fiat Currency"
    COMMODITY = "Commodity Money"
    DIGITAL = "Digital Currency"

@dataclass
class CurrencyComparison:
    """Represents a comparison between currency types"""
    aspect: str
    cryptocurrency: str
    fiat: str
    winner: str

@dataclass
class CryptoAsset:
    """Represents a cryptocurrency asset"""
    name: str
    symbol: str
    blockchain: str
    supply_type: str
    consensus: str
    use_case: str

class CryptocurrencyEngine:
    """Complete cryptocurrency fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOCURRENCY FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_cryptocurrency(self) -> None:
        """Explain what cryptocurrency is"""
        print("\n 💰 WHAT IS CRYPTOCURRENCY?")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTOCURRENCY DEFINITION                                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  CRYPTO = Cryptography + Currency                         │
│                                                           │
│  Cryptography: Secures transactions and controls supply   │
│  Currency: Medium of exchange, store of value             │
│                                                           │
│  KEY FEATURES:                                           │
│  ✓ Digital-only (no physical form)                       │
│  ✓ Decentralized (no central authority)                  │
│  ✓ Public Ledger (transparent blockchain)                │
│  ✓ Cryptographic Security (private keys)                │
│  ✓ Borderless (global accessibility)                     │
│  ✓ Programmable (smart contracts)                        │
│                                                           │
│  EXAMPLES:                                               │
│  • Bitcoin (BTC): First cryptocurrency                   │
│  • Ethereum (ETH): Smart contract platform               │
│  • Solana (SOL): High-performance blockchain             │
│  • Cardano (ADA): Research-driven platform              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def compare_crypto_fiat(self) -> None:
        """Compare cryptocurrency with fiat currency"""
        print("\n 📊 CRYPTO vs FIAT COMPARISON")
        print("-" * 40)
        
        comparisons = [
            CurrencyComparison(
                aspect="Control",
                cryptocurrency="Decentralized",
                fiat="Centralized (Government)",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Supply",
                cryptocurrency="Fixed/Limited",
                fiat="Infinite (Printable)",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Physical Form",
                cryptocurrency="Digital Only",
                fiat="Physical + Digital",
                winner="Fiat"
            ),
            CurrencyComparison(
                aspect="Global Accessibility",
                cryptocurrency="Yes (Borderless)",
                fiat="Limited (Country-based)",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Privacy",
                cryptocurrency="Pseudonymous",
                fiat="KYC Required",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Transaction Speed",
                cryptocurrency="Minutes (varies)",
                fiat="Days (Cross-border)",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Transaction Fees",
                cryptocurrency="Low (varies)",
                fiat="High (International)",
                winner="Crypto"
            ),
            CurrencyComparison(
                aspect="Inflation",
                cryptocurrency="Deflationary/Stable",
                fiat="Inflationary",
                winner="Crypto"
            )
        ]
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Aspect':>20} | {'Cryptocurrency':>20} | {'Fiat Currency':>20} | {'Winner':>10}")
        print("-" * 75)
        
        for comp in comparisons:
            print(f" {comp.aspect:>20} | {comp.cryptocurrency:>20} | {comp.fiat:>20} | {comp.winner:>10}")
    
    def explain_crypto_assets(self) -> None:
        """Explain different types of crypto assets"""
        print("\n 🪙 CRYPTO ASSET TYPES")
        print("-" * 40)
        
        assets = [
            CryptoAsset(
                name="Bitcoin",
                symbol="BTC",
                blockchain="Bitcoin",
                supply_type="Fixed (21 million)",
                consensus="Proof of Work",
                use_case="Store of Value, Digital Gold"
            ),
            CryptoAsset(
                name="Ethereum",
                symbol="ETH",
                blockchain="Ethereum",
                supply_type="Inflationary (Issued)",
                consensus="Proof of Stake",
                use_case="Smart Contracts, DeFi, dApps"
            ),
            CryptoAsset(
                name="Solana",
                symbol="SOL",
                blockchain="Solana",
                supply_type="Inflationary (Deflationary)",
                consensus="Proof of Stake",
                use_case="High-performance dApps"
            ),
            CryptoAsset(
                name="Cardano",
                symbol="ADA",
                blockchain="Cardano",
                supply_type="Fixed (45 billion)",
                consensus="Proof of Stake",
                use_case="Smart Contracts, DeFi"
            ),
            CryptoAsset(
                name="USDC",
                symbol="USDC",
                blockchain="Ethereum/Solana",
                supply_type="Stable (Backed)",
                consensus="Various",
                use_case="Stablecoin, Payments"
            ),
            CryptoAsset(
                name="Uniswap",
                symbol="UNI",
                blockchain="Ethereum",
                supply_type="Fixed (1 billion)",
                consensus="Proof of Stake",
                use_case="DeFi, Governance"
            )
        ]
        
        print("\n📊 Crypto Asset Details:")
        for asset in assets:
            print(f"\n  {asset.name} ({asset.symbol}):")
            print(f"    Blockchain: {asset.blockchain}")
            print(f"    Supply: {asset.supply_type}")
            print(f"    Consensus: {asset.consensus}")
            print(f"    Use Case: {asset.use_case}")
    
    def explain_crypto_terms(self) -> None:
        """Explain key cryptocurrency terms"""
        print("\n 📚 KEY CRYPTO TERMS")
        print("-" * 40)
        
        terms = {
            "Coin": {
                "definition": "Native cryptocurrency of a blockchain",
                "examples": "BTC, ETH, SOL",
                "purpose": "Network fuel, value transfer"
            },
            "Token": {
                "definition": "Digital asset built on a blockchain",
                "examples": "USDC, UNI, LINK",
                "purpose": "DeFi, governance, utility"
            },
            "Wallet": {
                "definition": "Stores private keys, manages assets",
                "examples": "MetaMask, Ledger, Trust Wallet",
                "purpose": "Secure asset management"
            },
            "Exchange": {
                "definition": "Platform to buy/sell/trade crypto",
                "examples": "Binance, Coinbase, Kraken",
                "purpose": "Trading, liquidity"
            },
            "DeFi": {
                "definition": "Decentralized Finance",
                "examples": "Uniswap, Aave, Compound",
                "purpose": "Lending, borrowing, trading"
            },
            "dApp": {
                "definition": "Decentralized Application",
                "examples": "OpenSea, CryptoKitties",
                "purpose": "Gaming, NFT, DeFi"
            }
        }
        
        print("\n📋 Crypto Terminology:")
        for term, details in terms.items():
            print(f"\n  {term}:")
            print(f"    Definition: {details['definition']}")
            print(f"    Examples: {details['examples']}")
            print(f"    Purpose: {details['purpose']}")

class CryptoAnalytics:
    """Additional analysis tools for cryptocurrency"""
    
    @staticmethod
    def analyze_advantages_risks() -> None:
        """Analyze cryptocurrency advantages and risks"""
        print("\n 📊 ADVANTAGES & RISKS")
        print("-" * 40)
        
        advantages = [
            "✅ Global Access: Anyone with internet can use",
            "✅ Low Fees: Especially for international transfers",
            "✅ Fast Transfers: Minutes vs days for traditional banking",
            "✅ Privacy: Pseudonymous transactions",
            "✅ Censorship-Resistant: Cannot be blocked by governments",
            "✅ Transparency: Public ledger, auditable",
            "✅ Programmable: Smart contracts enable automation"
        ]
        
        risks = [
            "⚠️  Volatility: Prices can fluctuate dramatically",
            "⚠️  Security: Self-custody means responsibility",
            "⚠️  Regulatory Uncertainty: Changing laws worldwide",
            "⚠️  Technical Complexity: Learning curve for users",
            "⚠️  Irreversible: No chargebacks or refunds",
            "⚠️  Adoption Risk: Still early in adoption cycle",
            "⚠️  Environmental Impact: Some consensus mechanisms"
        ]
        
        print("\n✅ Advantages:")
        for adv in advantages:
            print(f"  {adv}")
        
        print("\n⚠️  Risks:")
        for risk in risks:
            print(f"  {risk}")
    
    @staticmethod
    def analyze_adoption_stats() -> None:
        """Analyze cryptocurrency adoption statistics"""
        print("\n 📈 ADOPTION STATISTICS")
        print("-" * 40)
        
        stats = {
            "Metric": [
                "Total Market Cap",
                "Number of Cryptocurrencies",
                "Number of Users",
                "Daily Transactions",
                "Major Exchanges",
                "Countries Accepting Crypto"
            ],
            "Value": [
                "~$1.7 Trillion",
                "10,000+",
                "400+ Million",
                "500,000+",
                "500+",
                "100+"
            ]
        }
        
        print("\n📊 Market Statistics:")
        print(f" {'Metric':>25} | {'Value':>25}")
        print("-" * 55)
        
        for i in range(len(stats["Metric"])):
            metric = stats["Metric"][i]
            value = stats["Value"][i]
            print(f" {metric:>25} | {value:>25}")

def demonstrate_cryptocurrency_engine():
    """Execute comprehensive cryptocurrency demonstration"""
    print("=" * 60)
    print(" CRYPTOCURRENCY FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = CryptocurrencyEngine()
    
    # Run demonstrations
    engine.explain_cryptocurrency()
    engine.compare_crypto_fiat()
    engine.explain_crypto_assets()
    engine.explain_crypto_terms()
    
    # Additional analytics
    CryptoAnalytics.analyze_advantages_risks()
    CryptoAnalytics.analyze_adoption_stats()
    
    print("\n" + "=" * 60)
    print(" CRYPTOCURRENCY SUMMARY:")
    print("   ✓ Digital + Decentralized + Cryptographic")
    print("   ✓ More than 10,000 cryptocurrencies")
    print("   ✓ Global market cap: ~$1.7 Trillion")
    print("   ✓ Advantages: Global, low fees, fast, private")
    print("   ✓ Risks: Volatility, security, regulation")
    print("   ✓ First application: Bitcoin (2009)")
    print("   ✓ Future: Mainstream adoption continues")
    print("   ✓ Foundation of blockchain ecosystem")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_cryptocurrency_engine()

4.2 Bitcoin

What is Bitcoin?

Bitcoin is the first and most well-known cryptocurrency. Bitcoin was launched in 2009 by an anonymous person or group operating under the pseudonym Satoshi Nakamoto.Bitcoin is the pioneer of blockchain technology and remains the largest cryptocurrency by market capitalization.

Bitcoin’s Key Features:

FeatureDescription
NetworkPeer-to-peer, decentralized
SupplyCapped at 21 million BTC
ConsensusProof of Work (PoW)
Block Time~10 minutes
Transaction Speed~7 TPS
SecurityVery high (SHA-256)

Bitcoin Supply:

  • Total Supply: 21,000,000 BTC
  • Current Supply: ~19.5 million BTC (mined)
  • Halving: Every 210,000 blocks (~4 years)
  • Block Reward: 3.125 BTC (after 2024 halving)

Bitcoin Halving Schedule:

YearBlock RewardSupply Mined
200950 BTC10.5M
201225 BTC15.75M
201612.5 BTC18.375M
20206.25 BTC19.6875M
20243.125 BTC~20.0M

Code Example – Bitcoin:

"""
BITCOIN FUNDAMENTALS FRAMEWORK
===============================
Complete Bitcoin overview, supply schedule, security model, and use cases
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class BitcoinHalving:
    """Represents a Bitcoin halving event"""
    year: int
    block_height: int
    block_reward: float
    supply_mined: float
    percentage_mined: float
    total_supply: float

@dataclass
class BitcoinMetric:
    """Represents a Bitcoin network metric"""
    name: str
    value: str
    description: str
    category: str

class BitcoinEngine:
    """Complete Bitcoin fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" BITCOIN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_bitcoin_overview(self) -> None:
        """Provide comprehensive Bitcoin overview"""
        print("\n ₿ BITCOIN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BITCOIN - THE FIRST CRYPTOCURRENCY                       │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  CREATED: 2009 by Satoshi Nakamoto                        │
│  WHITEPAPER: "Bitcoin: A Peer-to-Peer Electronic Cash     │
│              System"                                      │
│                                                           │
│  PURPOSE: Decentralized, trustless digital currency       │
│  NETWORK: Permissionless, peer-to-peer                    │
│  LEDGER: Public blockchain (immutable)                    │
│                                                           │
│  KEY FEATURES:                                           │
│  ✓ Security: SHA-256 cryptographic hashing               │
│  ✓ Consensus: Proof of Work (PoW)                        │
│  ✓ Supply: Fixed (21 million max)                        │
│  ✓ Global: Borderless transactions                        │
│  ✓ Transparent: Public ledger                             │
│  ✓ Pseudonymous: No personal information required         │
│                                                           │
│  CURRENT STATUS (Approximate):                           │
│  • Market Cap: ~$1.2 Trillion                            │
│  • 24h Volume: ~$20 Billion                              │
│  • Active Addresses: ~1 Million                          │
│  • Full Nodes: ~15,000                                   │
│  • Hash Rate: ~400 EH/s                                 │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_bitcoin_supply(self) -> None:
        """Show Bitcoin supply schedule and halving events"""
        print("\n 📊 BITCOIN SUPPLY SCHEDULE")
        print("-" * 40)
        
        halvings = [
            BitcoinHalving(
                year=2009,
                block_height=0,
                block_reward=50.0,
                supply_mined=0,
                percentage_mined=0.0,
                total_supply=21000000
            ),
            BitcoinHalving(
                year=2012,
                block_height=210000,
                block_reward=25.0,
                supply_mined=10500000,
                percentage_mined=50.0,
                total_supply=21000000
            ),
            BitcoinHalving(
                year=2016,
                block_height=420000,
                block_reward=12.5,
                supply_mined=15750000,
                percentage_mined=75.0,
                total_supply=21000000
            ),
            BitcoinHalving(
                year=2020,
                block_height=630000,
                block_reward=6.25,
                supply_mined=18375000,
                percentage_mined=87.5,
                total_supply=21000000
            ),
            BitcoinHalving(
                year=2024,
                block_height=840000,
                block_reward=3.125,
                supply_mined=19687500,
                percentage_mined=93.75,
                total_supply=21000000
            ),
            BitcoinHalving(
                year=2028,
                block_height=1050000,
                block_reward=1.5625,
                supply_mined=20343750,
                percentage_mined=96.875,
                total_supply=21000000
            )
        ]
        
        print("\n📋 Halving Schedule:")
        print(f" {'Year':>8} | {'Block Reward':>15} | {'Supply Mined':>15} | {'% Mined':>10}")
        print("-" * 55)
        
        for halving in halvings:
            print(f" {halving.year:>8} | {halving.block_reward:>15.2f} | "
                  f"{halving.supply_mined:>15,.0f} | {halving.percentage_mined:>9.1f}%")
        
        print("\n💡 Key Insights:")
        print("  ✓ Halving occurs every 210,000 blocks (~4 years)")
        print("  ✓ Reward halves, making Bitcoin deflationary")
        print("  ✓ Last Bitcoin will be mined ~2140")
        print("  ✓ Fixed supply ensures scarcity")
    
    def explain_bitcoin_security(self) -> None:
        """Explain Bitcoin's security model"""
        print("\n 🛡️  BITCOIN SECURITY MODEL")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BITCOIN SECURITY LAYERS                                  │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1. CRYPTOGRAPHIC HASHING                                 │
│     • SHA-256 algorithm                                   │
│     • 256-bit security                                    │
│     • 128-bit collision resistance                        │
│                                                           │
│  2. PROOF OF WORK (PoW)                                   │
│     • Computational puzzle                                │
│     • Difficulty adjustment                               │
│     • Energy consumption = security                       │
│                                                           │
│  3. 51% ATTACK RESISTANCE                                 │
│     • Requires majority of hash power                     │
│     • Cost: Billions of dollars                          │
│     • Economically irrational                             │
│                                                           │
│  4. ECONOMIC INCENTIVES                                   │
│     • Block rewards                                       │
│     • Transaction fees                                    │
│     • Mining profitability                                │
│                                                           │
│  ATTACK COST ESTIMATES:                                   │
│  • Hardware: ~$5-10 Billion                              │
│  • Electricity: Country-scale                            │
│  • Time: Years to accumulate                             │
│                                                           │
│  ✓ No successful attack in 15+ years                    │
│  ✓ Most secure blockchain network                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_bitcoin_use_cases(self) -> None:
        """Explain Bitcoin use cases"""
        print("\n 🎯 BITCOIN USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Store of Value": {
                "description": "Digital gold, long-term wealth preservation",
                "benefits": ["Fixed supply", "Global acceptance", "Inflation hedge"],
                "users": "Investors, institutions, sovereign wealth funds"
            },
            "Payment System": {
                "description": "Peer-to-peer value transfer",
                "benefits": ["Borderless", "Low fees (relative)", "Fast settlement"],
                "users": "Individuals, businesses, merchants"
            },
            "Remittance": {
                "description": "International money transfers",
                "benefits": ["Lower fees than traditional", "Faster than banks", "No intermediaries"],
                "users": "Expatriates, international workers"
            },
            "Financial Inclusion": {
                "description": "Banking for the unbanked",
                "benefits": ["No bank account required", "Censorship-resistant", "Global access"],
                "users": "Unbanked populations, developing nations"
            },
            "Institutional Investment": {
                "description": "Portfolio diversification and treasury management",
                "benefits": ["Digital asset allocation", "Risk management", "Inflation protection"],
                "users": "Corporations, hedge funds, pension funds"
            }
        }
        
        print("\n📋 Application Areas:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Users: {details['users']}")

class BitcoinAnalytics:
    """Additional analysis tools for Bitcoin"""
    
    @staticmethod
    def analyze_network_metrics() -> None:
        """Analyze Bitcoin network metrics"""
        print("\n 📊 BITCOIN NETWORK METRICS")
        print("-" * 40)
        
        metrics = [
            BitcoinMetric(
                name="Hash Rate",
                value="~400 EH/s",
                description="Total computational power",
                category="Security"
            ),
            BitcoinMetric(
                name="Difficulty",
                value="~55 T",
                description="Mining difficulty adjustment",
                category="Security"
            ),
            BitcoinMetric(
                name="Block Time",
                value="~10 minutes",
                description="Time between blocks",
                category="Performance"
            ),
            BitcoinMetric(
                name="Transaction Throughput",
                value="~7 TPS",
                description="Transactions per second",
                category="Performance"
            ),
            BitcoinMetric(
                name="Active Addresses",
                value="~1M/day",
                description="Unique addresses used daily",
                category="Adoption"
            ),
            BitcoinMetric(
                name="Number of Nodes",
                value="~15,000",
                description="Full nodes worldwide",
                category="Decentralization"
            )
        ]
        
        print("\n📈 Network Statistics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>25} | {'Category':>15}")
        print("-" * 90)
        
        for metric in metrics:
            print(f" {metric.name:>25} | {metric.value:>20} | {metric.description:>25} | {metric.category:>15}")
    
    @staticmethod
    def analyze_bitcoin_risks() -> None:
        """Analyze Bitcoin risks and challenges"""
        print("\n ⚠️  BITCOIN RISKS & CHALLENGES")
        print("-" * 40)
        
        risks = {
            "Scalability": {
                "description": "Limited transaction throughput (7 TPS)",
                "impact": "High fees during congestion",
                "mitigation": "Lightning Network, Layer 2 solutions"
            },
            "Energy Consumption": {
                "description": "High electricity usage for mining",
                "impact": "Environmental concerns",
                "mitigation": "Renewable energy, efficiency improvements"
            },
            "Regulation": {
                "description": "Varying regulations globally",
                "impact": "Potential restrictions or bans",
                "mitigation": "Industry advocacy, compliance"
            },
            "Volatility": {
                "description": "Price fluctuations",
                "impact": "Difficulty as stable currency",
                "mitigation": "Institutional adoption, maturity"
            },
            "Quantum Computing": {
                "description": "Potential future threat to cryptography",
                "impact": "Could break ECDSA signatures",
                "mitigation": "Quantum-resistant upgrades, research"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_bitcoin_engine():
    """Execute comprehensive Bitcoin demonstration"""
    print("=" * 60)
    print(" BITCOIN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = BitcoinEngine()
    
    # Run demonstrations
    engine.explain_bitcoin_overview()
    engine.demonstrate_bitcoin_supply()
    engine.explain_bitcoin_security()
    engine.explain_bitcoin_use_cases()
    
    # Additional analytics
    BitcoinAnalytics.analyze_network_metrics()
    BitcoinAnalytics.analyze_bitcoin_risks()
    
    print("\n" + "=" * 60)
    print(" BITCOIN SUMMARY:")
    print("   ✓ First and most secure cryptocurrency")
    print("   ✓ Fixed Supply: 21 million BTC")
    print("   ✓ Security: SHA-256, Proof of Work")
    print("   ✓ Use Cases: Store of value, payments, remittance")
    print("   ✓ Challenges: Scalability, energy, regulation")
    print("   ✓ Status: Digital gold, institutional adoption")
    print("   ✓ Future: Continued growth and adoption")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_bitcoin_engine()

4.3 Ethereum

What is Ethereum?

Ethereum is a decentralized, open-source blockchain with smart contract functionality. It was proposed in 2013 by Vitalik Buterin and launched in 2015. Ethereum is a leading cryptocurrency and blockchain platform that supports decentralized applications (dApps), smart contracts, and programmable digital assets.

Ethereum’s Key Features:

FeatureDescription
NetworkSmart contract platform
PurposeProgrammable blockchain
ConsensusProof of Stake (PoS)
Block Time~12 seconds
Transaction Speed~15 TPS
LanguageSolidity, Vyper

Ethereum vs Bitcoin:

AspectBitcoinEthereum
PurposeDigital moneySmart contracts
LanguageLimited scriptingTuring-complete
ConsensusPoWPoS
Block Time10 min12 sec
Supply21M capNo hard cap
InnovationFirst cryptoProgrammable

Code Example – Ethereum:

"""
ETHEREUM FUNDAMENTALS FRAMEWORK
================================
Complete Ethereum overview, upgrades, and use cases
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class EthereumUpgrade:
    """Represents an Ethereum network upgrade"""
    name: str
    year: int
    description: str
    key_features: List[str]
    impact: str

@dataclass
class EthereumMetric:
    """Represents an Ethereum network metric"""
    name: str
    value: str
    description: str
    category: str

class EthereumEngine:
    """Complete Ethereum fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ETHEREUM FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_ethereum_overview(self) -> None:
        """Provide comprehensive Ethereum overview"""
        print("\n 🟣 ETHEREUM OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ETHEREUM - THE SMART CONTRACT PLATFORM                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  CREATED: 2015 by Vitalik Buterin                         │
│  WHITEPAPER: "Ethereum: A Next-Generation Smart Contract  │
│              Platform"                                    │
│                                                           │
│  PURPOSE: Decentralized applications (dApps)              │
│  NETWORK: Smart contract, programmable blockchain          │
│  LEDGER: Public blockchain with state                     │
│                                                           │
│  KEY FEATURES:                                           │
│  ✓ Smart Contracts: Programmable logic on-chain          │
│  ✓ Turing-Complete: Full computation capabilities        │
│  ✓ Consensus: Proof of Stake (PoS)                       │
│  ✓ Native Token: ETH (Ether)                             │
│  ✓ EVM: Ethereum Virtual Machine                         │
│  ✓ dApps: Decentralized applications                     │
│                                                           │
│  CURRENT STATUS (Approximate):                           │
│  • Market Cap: ~$400 Billion                             │
│  • 24h Volume: ~$10 Billion                              │
│  • Active Addresses: ~500,000                            │
│  • Validators: ~1,000,000                               │
│  • Total Supply: ~120 million ETH                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_ethereum_upgrades(self) -> None:
        """Show Ethereum evolution and upgrades"""
        print("\n 📈 ETHEREUM EVOLUTION")
        print("-" * 40)
        
        upgrades = [
            EthereumUpgrade(
                name="Frontier Launch",
                year=2015,
                description="First Ethereum mainnet launch",
                key_features=["Basic smart contracts", "EVM implementation", "Mining start"],
                impact="Founded Ethereum network"
            ),
            EthereumUpgrade(
                name="Homestead",
                year=2016,
                description="Production-ready Ethereum",
                key_features=["Security improvements", "Gas price changes", "Solidity updates"],
                impact="Stable mainnet"
            ),
            EthereumUpgrade(
                name="Byzantium",
                year=2017,
                description="Metropolis phase 1",
                key_features=["ZK-STARKs support", "Gas optimizations", "Block time reduction"],
                impact="Prepared for scaling"
            ),
            EthereumUpgrade(
                name="Constantinople",
                year=2019,
                description="Metropolis phase 2",
                key_features=["EIP-1014", "EIP-1052", "Gas improvements"],
                impact="Efficiency improvements"
            ),
            EthereumUpgrade(
                name="Beacon Chain",
                year=2020,
                description="Proof of Stake foundation",
                key_features=["PoS consensus", "Staking mechanism", "Phase 0"],
                impact="Started PoS transition"
            ),
            EthereumUpgrade(
                name="London (EIP-1559)",
                year=2021,
                description="Fee market reform",
                key_features=["Base fee", "Fee burning", "Variable block size"],
                impact="Changed fee structure"
            ),
            EthereumUpgrade(
                name="The Merge",
                year=2022,
                description="Proof of Stake transition",
                key_features=["PoS finality", "Energy reduction 99.9%", "Unified network"],
                impact="Completed PoS transition"
            ),
            EthereumUpgrade(
                name="Shanghai",
                year=2023,
                description="Staking withdrawals",
                key_features=["Validator withdrawals", "EIP-3651", "EIP-3855"],
                impact="Enabled ETH withdrawals"
            ),
            EthereumUpgrade(
                name="Dencun",
                year=2024,
                description="Proto-danksharding",
                key_features=["EIP-4844", "Blob transactions", "Layer 2 scaling"],
                impact="L2 scalability improvement"
            )
        ]
        
        print("\n📋 Upgrade Timeline:")
        for upgrade in upgrades:
            print(f"\n  {upgrade.year}: {upgrade.name}")
            print(f"    Description: {upgrade.description}")
            print(f"    Features: {', '.join(upgrade.key_features)}")
            print(f"    Impact: {upgrade.impact}")
    
    def explain_ethereum_use_cases(self) -> None:
        """Explain Ethereum use cases"""
        print("\n 🎯 ETHEREUM USE CASES")
        print("-" * 40)
        
        use_cases = {
            "DeFi (Decentralized Finance)": {
                "description": "Financial services without intermediaries",
                "examples": ["Uniswap (DEX)", "Aave (Lending)", "Compound (Interest)", "MakerDAO (Stablecoins)"],
                "benefits": ["Permissionless", "Transparent", "Global", "Programmable"]
            },
            "NFTs (Non-Fungible Tokens)": {
                "description": "Unique digital assets representing ownership",
                "examples": ["OpenSea", "CryptoPunks", "Axie Infinity", "Royalty tokens"],
                "benefits": ["Scarcity", "Provenance", "Royalties", "Interoperability"]
            },
            "DAOs (Decentralized Organizations)": {
                "description": "Community-governed organizations",
                "examples": ["ENS", "Uniswap DAO", "Gitcoin DAO", "Aave DAO"],
                "benefits": ["Democratic", "Transparent", "Treasury management", "Voting"]
            },
            "Smart Contracts": {
                "description": "Automated, self-executing agreements",
                "examples": ["Escrow services", "Insurance", "Automated payments", "Supply chain"],
                "benefits": ["Trustless", "Automatic", "Transparent", "Immutable"]
            }
        }
        
        print("\n📋 Application Areas:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Examples: {', '.join(details['examples'])}")
            print(f"    Benefits: {', '.join(details['benefits'])}")

class EthereumAnalytics:
    """Additional analysis tools for Ethereum"""
    
    @staticmethod
    def analyze_network_metrics() -> None:
        """Analyze Ethereum network metrics"""
        print("\n 📊 ETHEREUM NETWORK METRICS")
        print("-" * 40)
        
        metrics = [
            EthereumMetric(
                name="Gas Price",
                value="~15-30 Gwei",
                description="Cost per gas unit",
                category="Economics"
            ),
            EthereumMetric(
                name="Block Time",
                value="~12 seconds",
                description="Time between blocks",
                category="Performance"
            ),
            EthereumMetric(
                name="Transaction Throughput",
                value="~15-30 TPS",
                description="Transactions per second",
                category="Performance"
            ),
            EthereumMetric(
                name="Active Addresses",
                value="~500K/day",
                description="Unique addresses used daily",
                category="Adoption"
            ),
            EthereumMetric(
                name="Validators",
                value="~1,000,000",
                description="PoS validators",
                category="Consensus"
            ),
            EthereumMetric(
                name="Staked ETH",
                value="~30 million",
                description="Total ETH staked",
                category="Consensus"
            )
        ]
        
        print("\n📈 Network Statistics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>25} | {'Category':>15}")
        print("-" * 90)
        
        for metric in metrics:
            print(f" {metric.name:>25} | {metric.value:>20} | {metric.description:>25} | {metric.category:>15}")
    
    @staticmethod
    def analyze_ethereum_advantages_risks() -> None:
        """Analyze Ethereum advantages and risks"""
        print("\n 📊 ETHEREUM ADVANTAGES & RISKS")
        print("-" * 40)
        
        advantages = [
            "✅ Programmable: Full smart contract functionality",
            "✅ Largest Ecosystem: Most dApps, users, developers",
            "✅ DeFi Hub: Leading DeFi protocols and liquidity",
            "✅ NFT Hub: Most active NFT marketplace",
            "✅ Continuous Upgrades: Active development and improvement",
            "✅ Proof of Stake: Energy efficient (99.9% less than PoW)",
            "✅ EVM Standard: Industry standard for smart contracts"
        ]
        
        risks = [
            "⚠️  Scalability: Limited TPS (15-30)",
            "⚠️  High Fees: Gas costs during congestion",
            "⚠️  Complexity: Smart contract vulnerabilities",
            "⚠️  Competition: Challengers like Solana, Cardano",
            "⚠️  Migration: Moving from PoW to PoS was complex",
            "⚠️  Regulatory: DeFi regulation uncertainty",
            "⚠️  L2 Fragmentation: Multiple Layer 2 solutions"
        ]
        
        print("\n✅ Advantages:")
        for adv in advantages:
            print(f"  {adv}")
        
        print("\n⚠️  Risks:")
        for risk in risks:
            print(f"  {risk}")

def demonstrate_ethereum_engine():
    """Execute comprehensive Ethereum demonstration"""
    print("=" * 60)
    print(" ETHEREUM FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = EthereumEngine()
    
    # Run demonstrations
    engine.explain_ethereum_overview()
    engine.demonstrate_ethereum_upgrades()
    engine.explain_ethereum_use_cases()
    
    # Additional analytics
    EthereumAnalytics.analyze_network_metrics()
    EthereumAnalytics.analyze_ethereum_advantages_risks()
    
    print("\n" + "=" * 60)
    print(" ETHEREUM SUMMARY:")
    print("   ✓ Smart Contract Platform (World Computer)")
    print("   ✓ Created: 2015 by Vitalik Buterin")
    print("   ✓ Consensus: Proof of Stake (energy efficient)")
    print("   ✓ Use Cases: DeFi, NFTs, DAOs, dApps")
    print("   ✓ Advantages: Largest ecosystem, programmable")
    print("   ✓ Challenges: Scalability, fees, complexity")
    print("   ✓ Future: Layer 2 scaling, continued upgrades")
    print("   ✓ Position: Foundation of Web3")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_ethereum_engine()

4.4 Altcoins

What are Altcoins?

Altcoins are alternative cryptocurrencies to Bitcoin. Altcoins are cryptocurrencies other than Bitcoin, including a wide range of projects with different technologies, purposes, and use cases.Altcoins often offer different features, consensus mechanisms, or use cases compared to Bitcoin.

Categories of Altcoins:

CategoryDescriptionExamples
PlatformsSmart contract platformsEthereum, Solana, Cardano
DeFiDecentralized financeUniswap, Aave, Compound
PrivacyPrivate transactionsMonero, Zcash, Dash
StorageData storageFilecoin, Arweave
GamingBlockchain gamesAxie Infinity, Decentraland

Code Example – Altcoins:

"""
ALTCOIN FUNDAMENTALS FRAMEWORK
==============================
Complete altcoin overview, categorization, and market analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class AltcoinCategory(Enum):
    """Classification of altcoin categories"""
    SMART_CONTRACT = "Smart Contract Platform"
    DEFI = "DeFi Token"
    PRIVACY = "Privacy Coin"
    SCALING = "Scaling Solution"
    STORAGE = "Storage Network"
    ORACLE = "Oracle Network"
    GAMING = "Gaming & Metaverse"
    INTEROPERABILITY = "Interoperability"

@dataclass
class Altcoin:
    """Represents an altcoin with its properties"""
    name: str
    symbol: str
    category: AltcoinCategory
    consensus: str
    tps: int
    key_feature: str
    market_cap: str
    use_case: str

class AltcoinEngine:
    """Complete altcoin fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ALTCOIN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_altcoin_overview(self) -> None:
        """Provide comprehensive altcoin overview"""
        print("\n 🪙 ALTCOIN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ALTCOINS - EVERYTHING BEYOND BITCOIN                     │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Altcoins = Alternative Cryptocurrencies      │
│  Total Cryptocurrencies: 10,000+                         │
│  Total Market Cap: ~$2 Trillion                          │
│  Bitcoin Dominance: ~50%                                 │
│                                                           │
│  MAJOR CATEGORIES:                                       │
│                                                           │
│  Smart Contract Platforms                                │
│  • Ethereum (ETH): DeFi, NFTs, dApps                    │
│  • Solana (SOL): High speed, low fees                   │
│  • Cardano (ADA): Research-driven, academic             │
│  • Avalanche (AVAX): Subnets, custom chains             │
│  • Polkadot (DOT): Interoperability, parachains         │
│                                                           │
│  DeFi Tokens                                             │
│  • Uniswap (UNI): DEX trading                           │
│  • Aave (AAVE): Lending protocols                       │
│  • Chainlink (LINK): Oracle services                    │
│                                                           │
│  Privacy Coins                                           │
│  • Monero (XMR): Private transactions                    │
│  • Zcash (ZEC): Shielded transactions                   │
│  • Dash (DASH): Instant payments                        │
│                                                           │
│  Scaling Solutions                                       │
│  • Polygon (MATIC): Layer 2 scaling                      │
│  • Arbitrum (ARB): Rollup technology                    │
│  • Optimism (OP): Optimistic rollups                    │
│                                                           │
│  Other Categories                                        │
│  • Storage: Filecoin (FIL), Arweave (AR)                │
│  • Gaming: Axie Infinity (AXS), Decentraland (MANA)    │
│  • IoT: IOTA, Helium (HNT)                              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_major_altcoins(self) -> None:
        """List major altcoins with their properties"""
        print("\n 📊 MAJOR ALTCOINS")
        print("-" * 40)
        
        altcoins = [
            Altcoin(
                name="Ethereum",
                symbol="ETH",
                category=AltcoinCategory.SMART_CONTRACT,
                consensus="Proof of Stake",
                tps=15,
                key_feature="Smart Contracts, DeFi",
                market_cap="$400B",
                use_case="dApps, DeFi, NFTs"
            ),
            Altcoin(
                name="Solana",
                symbol="SOL",
                category=AltcoinCategory.SMART_CONTRACT,
                consensus="Proof of Stake",
                tps=3000,
                key_feature="High Speed, Low Fees",
                market_cap="$60B",
                use_case="DeFi, NFTs, dApps"
            ),
            Altcoin(
                name="Cardano",
                symbol="ADA",
                category=AltcoinCategory.SMART_CONTRACT,
                consensus="Proof of Stake",
                tps=250,
                key_feature="Research-Driven, Academic",
                market_cap="$40B",
                use_case="Smart Contracts, DeFi"
            ),
            Altcoin(
                name="Avalanche",
                symbol="AVAX",
                category=AltcoinCategory.SMART_CONTRACT,
                consensus="Proof of Stake",
                tps=4500,
                key_feature="Subnets, Custom Chains",
                market_cap="$20B",
                use_case="dApps, Subnets"
            ),
            Altcoin(
                name="Polygon",
                symbol="MATIC",
                category=AltcoinCategory.SCALING,
                consensus="Proof of Stake",
                tps=1000,
                key_feature="Layer 2 Scaling",
                market_cap="$15B",
                use_case="Scaling Ethereum"
            ),
            Altcoin(
                name="Uniswap",
                symbol="UNI",
                category=AltcoinCategory.DEFI,
                consensus="Proof of Stake",
                tps=15,
                key_feature="DEX, Liquidity Pools",
                market_cap="$10B",
                use_case="DeFi Trading"
            ),
            Altcoin(
                name="Chainlink",
                symbol="LINK",
                category=AltcoinCategory.ORACLE,
                consensus="Proof of Stake",
                tps=15,
                key_feature="Oracles, Data Feeds",
                market_cap="$12B",
                use_case="DeFi, Data Integration"
            ),
            Altcoin(
                name="Monero",
                symbol="XMR",
                category=AltcoinCategory.PRIVACY,
                consensus="Proof of Work",
                tps=10,
                key_feature="Private Transactions",
                market_cap="$4B",
                use_case="Privacy, Confidential"
            )
        ]
        
        print("\n📋 Altcoin Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Category':>25} | {'TPS':>8} | {'Key Feature':>20} | {'Market Cap':>12}")
        print("-" * 100)
        
        for altcoin in altcoins:
            print(f" {altcoin.name:>15} | {altcoin.symbol:>8} | {altcoin.category.value[:25]:>25} | "
                  f"{altcoin.tps:>8} | {altcoin.key_feature[:20]:>20} | {altcoin.market_cap:>12}")
    
    def explain_altcoin_investment(self) -> None:
        """Explain altcoin investment considerations"""
        print("\n 💰 ALTCOIN INVESTMENT CONSIDERATIONS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ALTCOIN INVESTMENT GUIDE                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  FACTORS TO CONSIDER:                                    │
│                                                           │
│  ✓ Technology: Unique features and innovation             │
│  ✓ Team: Development team and leadership                  │
│  ✓ Community: Active user base and engagement             │
│  ✓ Use Case: Real-world problem solving                   │
│  ✓ Tokenomics: Supply, distribution, incentives           │
│  ✓ Adoption: Partnerships and integrations                │
│  ✓ Competition: Market position and differentiation       │
│  ✓ Regulation: Legal and compliance status                │
│                                                           │
│  INVESTMENT STRATEGIES:                                  │
│                                                           │
│  𝗗𝗼𝗻'𝘁 𝗣𝘂𝘁 𝗔𝗹𝗹 𝗘𝗴𝗴𝘀 𝗶𝗻 𝗢𝗻𝗲 𝗕𝗮𝘀𝗸𝗲𝘁                     │
│  • Diversify across categories                           │
│  • Large caps (ETH) and small caps                      │
│  • Different use cases                                   │
│                                                           │
│  𝗗𝗼 𝗬𝗼𝘂𝗿 𝗢𝘄𝗻 𝗥𝗲𝘀𝗲𝗮𝗿𝗰𝗵 (𝗗𝗬𝗢𝗥)                        │
│  • Read whitepapers                                      │
│  • Join communities                                      │
│  • Follow development                                    │
│                                                           │
│  𝗥𝗶𝘀𝗸 𝗠𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁                                         │
│  • Only invest what you can lose                         │
│  • Set stop-losses                                       │
│  • Take profits regularly                                │
│  • Stay informed                                         │
└─────────────────────────────────────────────────────────────┘
        """)

class AltcoinAnalytics:
    """Additional analysis tools for altcoins"""
    
    @staticmethod
    def analyze_market_metrics() -> None:
        """Analyze altcoin market metrics"""
        print("\n 📊 ALTCOIN MARKET METRICS")
        print("-" * 40)
        
        metrics = {
            "Metric": [
                "Total Market Cap",
                "Number of Altcoins",
                "Top 10 Dominance",
                "Daily Volume",
                "DeFi TVL",
                "Active Developers"
            ],
            "Value": [
                "~$1.5 Trillion",
                "10,000+",
                "~20%",
                "~$100 Billion",
                "~$50 Billion",
                "~20,000"
            ]
        }
        
        print("\n📈 Market Statistics:")
        print(f" {'Metric':>25} | {'Value':>25}")
        print("-" * 55)
        
        for i in range(len(metrics["Metric"])):
            metric = metrics["Metric"][i]
            value = metrics["Value"][i]
            print(f" {metric:>25} | {value:>25}")
    
    @staticmethod
    def categorize_altcoins() -> None:
        """Categorize altcoins by use case"""
        print("\n 📂 ALTCOIN CATEGORIZATION")
        print("-" * 40)
        
        categories = {
            "Smart Contracts": ["Ethereum", "Solana", "Cardano", "Avalanche", "Polkadot"],
            "DeFi": ["Uniswap", "Aave", "Compound", "Maker", "Lido"],
            "Scaling": ["Polygon", "Arbitrum", "Optimism", "zkSync", "StarkNet"],
            "Privacy": ["Monero", "Zcash", "Dash", "Verge", "PivX"],
            "Gaming": ["Axie Infinity", "Decentraland", "Sandbox", "Gala", "Enjin"],
            "Storage": ["Filecoin", "Arweave", "Siacoin", "Storj", "Bluzelle"],
            "Oracles": ["Chainlink", "Band Protocol", "API3", "UMA", "Tellor"]
        }
        
        print("\n📋 Category Breakdown:")
        for category, coins in categories.items():
            print(f"\n  {category}:")
            print(f"    {', '.join(coins)}")

def demonstrate_altcoin_engine():
    """Execute comprehensive altcoin demonstration"""
    print("=" * 60)
    print(" ALTCOIN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = AltcoinEngine()
    
    # Run demonstrations
    engine.explain_altcoin_overview()
    engine.list_major_altcoins()
    engine.explain_altcoin_investment()
    
    # Additional analytics
    AltcoinAnalytics.analyze_market_metrics()
    AltcoinAnalytics.categorize_altcoins()
    
    print("\n" + "=" * 60)
    print(" ALTCOIN SUMMARY:")
    print("   ✓ Altcoins = All non-Bitcoin cryptocurrencies")
    print("   ✓ Total: 10,000+ cryptocurrencies")
    print("   ✓ Categories: Smart contracts, DeFi, privacy, scaling")
    print("   ✓ Benefits: Innovation, variety, investment")
    print("   ✓ Risks: Volatility, scams, low liquidity")
    print("   ✓ Strategy: Research, diversify, risk management")
    print("   ✓ Position: Growing ecosystem beyond Bitcoin")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_altcoin_engine()

4.5 Stablecoins

What are Stablecoins?

Stablecoins are cryptocurrencies designed to maintain a stable value relative to an external asset, typically a fiat currency like the US dollar. They are designed to provide greater price stability compared with highly volatile cryptocurrencies.

Types of Stablecoins:

TypeDescriptionExamples
Fiat-BackedBacked by fiat reservesUSDC, USDT, BUSD
Crypto-BackedBacked by crypto collateralDAI, sUSD
AlgorithmicAlgorithm controls supplyUST (failed)

Why Stablecoins Matter:

  1. Stability: Protect against market volatility
  2. Trading: Base pairs for crypto trading
  3. Payments: Stable value for transactions
  4. DeFi: Essential for lending/borrowing

Code Example – Stablecoins:

"""
STABLECOIN FUNDAMENTALS FRAMEWORK
==================================
Complete stablecoin overview, types, and use cases
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class StablecoinType(Enum):
    """Classification of stablecoin types"""
    FIAT_BACKED = "Fiat-Backed"
    CRYPTO_BACKED = "Crypto-Backed"
    ALGORITHMIC = "Algorithmic"
    COMMODITY_BACKED = "Commodity-Backed"

@dataclass
class Stablecoin:
    """Represents a stablecoin with its properties"""
    name: str
    symbol: str
    stable_type: StablecoinType
    backing: str
    market_cap: str
    volume: str
    use_cases: List[str]
    risks: List[str]

@dataclass
class StablecoinMetric:
    """Represents a stablecoin market metric"""
    name: str
    value: str
    description: str
    category: str

class StablecoinEngine:
    """Complete stablecoin fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" STABLECOIN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_stablecoin_overview(self) -> None:
        """Provide comprehensive stablecoin overview"""
        print("\n 💵 STABLECOIN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  STABLECOINS - STABLE VALUE IN CRYPTO                    │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Stablecoins = Crypto + Price Stability       │
│  Purpose: Maintain stable value (usually $1 USD)          │
│                                                           │
│  TYPES:                                                  │
│                                                           │
│  1. FIAT-BACKED                                         │
│     • Backed 1:1 by fiat reserves                         │
│     • Most common and trusted                             │
│     • Examples: USDC (Circle), USDT (Tether)             │
│     • Advantages: Simple, transparent (mostly)            │
│     • Risks: Counterparty, reserve transparency           │
│                                                           │
│  2. CRYPTO-BACKED                                       │
│     • Backed by crypto collateral                         │
│     • Over-collateralized (150%+)                        │
│     • Examples: DAI (MakerDAO), sUSD (Synthetix)         │
│     • Advantages: Decentralized, transparent              │
│     • Risks: Volatility, liquidation risk                 │
│                                                           │
│  3. ALGORITHMIC                                         │
│     • Algorithm controls supply                          │
│     • No collateral backing                               │
│     • Examples: UST (Terra - Failed), FRAX               │
│     • Advantages: Scalable, no collateral needed          │
│     • Risks: De-pegging, death spiral (UST)              │
│                                                           │
│  4. COMMODITY-BACKED                                    │
│     • Backed by physical commodities                      │
│     • Examples: PAX Gold (PAXG), Tether Gold (XAUT)     │
│     • Advantages: Physical asset backing                  │
│     • Risks: Storage, custody, price tracking             │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_major_stablecoins(self) -> None:
        """List major stablecoins with their properties"""
        print("\n 📊 MAJOR STABLECOINS")
        print("-" * 40)
        
        stablecoins = [
            Stablecoin(
                name="Tether",
                symbol="USDT",
                stable_type=StablecoinType.FIAT_BACKED,
                backing="USD, Cash Equivalents",
                market_cap="$100B",
                volume="$50B",
                use_cases=["Trading", "Payments", "Remittance"],
                risks=["Reserve Transparency", "Counterparty Risk"]
            ),
            Stablecoin(
                name="USD Coin",
                symbol="USDC",
                stable_type=StablecoinType.FIAT_BACKED,
                backing="USD, Cash, Treasuries",
                market_cap="$30B",
                volume="$10B",
                use_cases=["Trading", "DeFi", "Payments"],
                risks=["Counterparty Risk", "Regulation"]
            ),
            Stablecoin(
                name="DAI",
                symbol="DAI",
                stable_type=StablecoinType.CRYPTO_BACKED,
                backing="ETH, USDC, Other Crypto",
                market_cap="$5B",
                volume="$2B",
                use_cases=["DeFi", "Lending", "Trading"],
                risks=["Volatility", "Liquidation", "Oracle Risk"]
            ),
            Stablecoin(
                name="Binance USD",
                symbol="BUSD",
                stable_type=StablecoinType.FIAT_BACKED,
                backing="USD, Cash",
                market_cap="$2B",
                volume="$5B",
                use_cases=["Trading", "Payments"],
                risks=["Counterparty Risk", "Regulatory Scrutiny"]
            ),
            Stablecoin(
                name="PAX Gold",
                symbol="PAXG",
                stable_type=StablecoinType.COMMODITY_BACKED,
                backing="Physical Gold",
                market_cap="$500M",
                volume="$100M",
                use_cases=["Gold Exposure", "Trading"],
                risks=["Storage", "Custody", "Price Tracking"]
            ),
            Stablecoin(
                name="FRAX",
                symbol="FRAX",
                stable_type=StablecoinType.ALGORITHMIC,
                backing="Algorithmic, Partially Collateralized",
                market_cap="$1B",
                volume="$300M",
                use_cases=["DeFi", "Trading"],
                risks=["Algorithm Risk", "De-pegging"]
            )
        ]
        
        print("\n📋 Stablecoin Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Type':>15} | {'Backing':>30} | {'Market Cap':>12}")
        print("-" * 85)
        
        for stablecoin in stablecoins:
            print(f" {stablecoin.name:>15} | {stablecoin.symbol:>8} | "
                  f"{stablecoin.stable_type.value[:15]:>15} | {stablecoin.backing[:30]:>30} | "
                  f"{stablecoin.market_cap:>12}")
        
        print("\n📋 Use Cases & Risks:")
        for stablecoin in stablecoins[:3]:  # Show top 3
            print(f"\n  {stablecoin.name} ({stablecoin.symbol}):")
            print(f"    Use Cases: {', '.join(stablecoin.use_cases)}")
            print(f"    Risks: {', '.join(stablecoin.risks)}")
    
    def explain_stablecoin_use_cases(self) -> None:
        """Explain stablecoin use cases"""
        print("\n 🎯 STABLECOIN USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Trading & Arbitrage": {
                "description": "Base trading pair, avoid volatility",
                "benefits": ["Price stability", "Liquidity", "Quick settlement"],
                "users": "Traders, Exchanges, Arbitrageurs"
            },
            "Payments & Transfers": {
                "description": "Stable value transfers globally",
                "benefits": ["Borderless", "Low fees", "Fast settlement"],
                "users": "Individuals, Businesses, Merchants"
            },
            "DeFi & Yield Farming": {
                "description": "Lending, borrowing, liquidity provision",
                "benefits": ["Interest earnings", "Collateral", "Trading pairs"],
                "users": "DeFi users, LPs, Yield farmers"
            },
            "Remittances": {
                "description": "International money transfers",
                "benefits": ["Lower fees", "Faster than banks", "Global access"],
                "users": "Expatriates, International workers"
            },
            "Hedging": {
                "description": "Protect against crypto volatility",
                "benefits": ["Price stability", "Risk management", "Portfolio protection"],
                "users": "Investors, Traders, Institutions"
            }
        }
        
        print("\n📋 Application Areas:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Users: {details['users']}")

class StablecoinAnalytics:
    """Additional analysis tools for stablecoins"""
    
    @staticmethod
    def analyze_market_metrics() -> None:
        """Analyze stablecoin market metrics"""
        print("\n 📊 STABLECOIN MARKET METRICS")
        print("-" * 40)
        
        metrics = [
            StablecoinMetric(
                name="Total Stablecoin Market Cap",
                value="~$150 Billion",
                description="Total value locked in stablecoins",
                category="Market"
            ),
            StablecoinMetric(
                name="Trading Volume (24h)",
                value="~$100 Billion",
                description="Daily stablecoin trading volume",
                category="Trading"
            ),
            StablecoinMetric(
                name="USDT Dominance",
                value="~65%",
                description="Tether's market share",
                category="Market"
            ),
            StablecoinMetric(
                name="USDC Dominance",
                value="~20%",
                description="USD Coin's market share",
                category="Market"
            ),
            StablecoinMetric(
                name="DeFi Usage",
                value="~40% of DeFi",
                description="Percentage of DeFi using stablecoins",
                category="DeFi"
            ),
            StablecoinMetric(
                name="Daily Transactions",
                value="~500,000",
                description="Average daily stablecoin transfers",
                category="Usage"
            )
        ]
        
        print("\n📈 Market Statistics:")
        print(f" {'Metric':>30} | {'Value':>20} | {'Description':>30} | {'Category':>15}")
        print("-" * 100)
        
        for metric in metrics:
            print(f" {metric.name:>30} | {metric.value:>20} | {metric.description:>30} | {metric.category:>15}")
    
    @staticmethod
    def analyze_stablecoin_risks() -> None:
        """Analyze stablecoin risks"""
        print("\n ⚠️  STABLECOIN RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Reserve Risk": {
                "description": "Insufficient backing reserves",
                "impact": "De-peg, loss of value",
                "mitigation": "Regular audits, transparency",
                "example": "USDC, USDT reserves"
            },
            "Counterparty Risk": {
                "description": "Dependency on centralized entities",
                "impact": "Freezes, regulatory actions",
                "mitigation": "Decentralized alternatives (DAI)",
                "example": "USDC freeze, BUSD scrutiny"
            },
            "Algorithmic Risk": {
                "description": "Algorithm failure (death spiral)",
                "impact": "Complete de-peg, loss of value",
                "mitigation": "Over-collateralization",
                "example": "UST collapse (2022)"
            },
            "Liquidation Risk": {
                "description": "Forced liquidation of crypto collateral",
                "impact": "Loss of collateral, de-peg",
                "mitigation": "Over-collateralization, monitoring",
                "example": "DAI liquidation events"
            },
            "Regulatory Risk": {
                "description": "Changing regulations, compliance",
                "impact": "Limited access, increased scrutiny",
                "mitigation": "Compliance, legal review",
                "example": "BUSD regulatory issues"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")
            print(f"    Example: {details['example']}")

def demonstrate_stablecoin_engine():
    """Execute comprehensive stablecoin demonstration"""
    print("=" * 60)
    print(" STABLECOIN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = StablecoinEngine()
    
    # Run demonstrations
    engine.explain_stablecoin_overview()
    engine.list_major_stablecoins()
    engine.explain_stablecoin_use_cases()
    
    # Additional analytics
    StablecoinAnalytics.analyze_market_metrics()
    StablecoinAnalytics.analyze_stablecoin_risks()
    
    print("\n" + "=" * 60)
    print(" STABLECOIN SUMMARY:")
    print("   ✓ Stablecoins = Cryptocurrency + Price Stability")
    print("   ✓ Types: Fiat-backed, Crypto-backed, Algorithmic")
    print("   ✓ Top: USDT, USDC, DAI")
    print("   ✓ Use Cases: Trading, Payments, DeFi, Remittances")
    print("   ✓ Benefits: Stability, Liquidity, Global Access")
    print("   ✓ Risks: Reserve, Counterparty, Algorithmic, Regulation")
    print("   ✓ Position: Backbone of DeFi ecosystem")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_stablecoin_engine()

4.6 Meme Coins

What are Meme Coins?

Meme coins are cryptocurrencies inspired by internet memes and jokes. They often have little to no utility and are driven by community hype and social media. While they started as jokes, some have gained significant market value.

Popular Meme Coins:

NameLaunch YearPeak Market CapNotable Feature
Dogecoin2013~$90BFirst meme coin
Shiba Inu2020~$40B“Dogecoin killer”
Pepe2023~$5BPepe meme

Code Example – Meme Coins:

"""
MEME COIN FUNDAMENTALS FRAMEWORK
=================================
Complete meme coin overview, risks, and community dynamics
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class MemeCoinCategory(Enum):
    """Classification of meme coin types"""
    DOG_THEME = "Dog Theme"
    FROG_THEME = "Frog Theme"
    CAT_THEME = "Cat Theme"
    OTHER_THEME = "Other Theme"

@dataclass
class MemeCoin:
    """Represents a meme coin with its properties"""
    name: str
    symbol: str
    theme: MemeCoinCategory
    year_created: int
    creator: str
    community_size: str
    market_cap: str
    key_feature: str
    risk_level: str

class MemeCoinEngine:
    """Complete meme coin fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" MEME COIN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_meme_coin_overview(self) -> None:
        """Provide comprehensive meme coin overview"""
        print("\n 🐕 MEME COIN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  MEME COINS - CRYPTO + INTERNET CULTURE                  │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Meme Coins = Cryptocurrency + Meme Culture  │
│  Purpose: Community-driven, internet culture, speculation │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Inspired by memes and internet culture                 │
│  ✓ Strong community engagement                            │
│  ✓ Extremely volatile                                     │
│  ✓ Limited utility (mostly speculation)                  │
│  ✓ Social media driven                                    │
│  ✓ Often created as jokes                                 │
│  ✓ High risk, high reward potential                       │
│                                                           │
│  THEMES:                                                 │
│  • Dog Theme: Dogecoin, Shiba Inu, Floki                 │
│  • Frog Theme: Pepe, PepeCoin                            │
│  • Cat Theme: CatCoin, KittyCoin                         │
│  • Other: Bonk, Dogelon Mars                             │
│                                                           │
│  SOCIAL MEDIA IMPACT:                                    │
│  • Elon Musk effect (DOGE)                               │
│  • Reddit communities (r/wallstreetbets)                 │
│  • TikTok and Twitter hype                               │
│  • Viral marketing                                       │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_major_meme_coins(self) -> None:
        """List major meme coins with their properties"""
        print("\n 📊 MAJOR MEME COINS")
        print("-" * 40)
        
        meme_coins = [
            MemeCoin(
                name="Dogecoin",
                symbol="DOGE",
                theme=MemeCoinCategory.DOG_THEME,
                year_created=2013,
                creator="Billy Markus, Jackson Palmer",
                community_size="~10M holders",
                market_cap="~$10B",
                key_feature="First meme coin, Elon Musk support",
                risk_level="Medium"
            ),
            MemeCoin(
                name="Shiba Inu",
                symbol="SHIB",
                theme=MemeCoinCategory.DOG_THEME,
                year_created=2020,
                creator="Ryoshi",
                community_size="~1M holders",
                market_cap="~$5B",
                key_feature="Ecosystem (ShibaSwap, Shibarium)",
                risk_level="High"
            ),
            MemeCoin(
                name="Pepe",
                symbol="PEPE",
                theme=MemeCoinCategory.FROG_THEME,
                year_created=2023,
                creator="Anonymous",
                community_size="~500K holders",
                market_cap="~$1B",
                key_feature="Pure meme, no utility",
                risk_level="Very High"
            ),
            MemeCoin(
                name="Floki Inu",
                symbol="FLOKI",
                theme=MemeCoinCategory.DOG_THEME,
                year_created=2021,
                creator="Community",
                community_size="~300K holders",
                market_cap="~$500M",
                key_feature="Floki ecosystem (DeFi)",
                risk_level="High"
            ),
            MemeCoin(
                name="Bonk",
                symbol="BONK",
                theme=MemeCoinCategory.DOG_THEME,
                year_created=2022,
                creator="Community",
                community_size="~200K holders",
                market_cap="~$200M",
                key_feature="Solana meme coin",
                risk_level="Very High"
            )
        ]
        
        print("\n📋 Meme Coin Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Theme':>12} | {'Year':>8} | {'Community':>15} | {'Market Cap':>12} | {'Risk':>10}")
        print("-" * 95)
        
        for meme_coin in meme_coins:
            print(f" {meme_coin.name:>15} | {meme_coin.symbol:>8} | {meme_coin.theme.value:>12} | "
                  f"{meme_coin.year_created:>8} | {meme_coin.community_size:>15} | "
                  f"{meme_coin.market_cap:>12} | {meme_coin.risk_level:>10}")
    
    def explain_meme_coin_risks(self) -> None:
        """Explain meme coin risks"""
        print("\n ⚠️  MEME COIN RISKS")
        print("-" * 40)
        
        risks = {
            "Extreme Volatility": {
                "description": "50-90% price drops are common",
                "impact": "Rapid loss of capital",
                "mitigation": "Only invest what you can lose",
                "example": "DOGE 90% drop from ATH"
            },
            "Pump and Dump": {
                "description": "Coordinated price manipulation",
                "impact": "Retail investors lose money",
                "mitigation": "Avoid FOMO, research before buying",
                "example": "SHIB initial pump and dump"
            },
            "Low Liquidity": {
                "description": "Hard to sell large positions",
                "impact": "Slippage, inability to exit",
                "mitigation": "Use limit orders, avoid large positions",
                "example": "PEPE thin order books"
            },
            "Rug Pulls": {
                "description": "Developers disappear with funds",
                "impact": "Complete loss of investment",
                "mitigation": "Check audits, team transparency",
                "example": "Squid Game token rug pull"
            },
            "No Fundamental Value": {
                "description": "No utility, revenue, or product",
                "impact": "Price driven solely by speculation",
                "mitigation": "Understand you're speculating",
                "example": "Most meme coins have no utility"
            },
            "Social Media Hype": {
                "description": "Price driven by influencers",
                "impact": "Artificial price inflation",
                "mitigation": "Don't trust influencers blindly",
                "example": "Elon Musk DOGE tweets"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")
            print(f"    Example: {details['example']}")

class MemeCoinAnalytics:
    """Additional analysis tools for meme coins"""
    
    @staticmethod
    def analyze_community_impact() -> None:
        """Analyze community impact on meme coins"""
        print("\n 📊 MEME COIN COMMUNITY IMPACT")
        print("-" * 40)
        
        community_factors = {
            "Factor": [
                "Social Media Following",
                "Reddit Activity",
                "Influencer Support",
                "Community Projects",
                "Viral Marketing",
                "Holders Count"
            ],
            "Impact": [
                "Price Movement",
                "Liquidity",
                "Adoption",
                "Ecosystem Growth",
                "Market Cap",
                "Volatility"
            ],
            "Examples": [
                "DOGE: Elon Musk tweets",
                "SHIB: r/SHIBArmy",
                "PEPE: Meme culture",
                "FLOKI: Floki ecosystem",
                "DOGE: Viral campaigns",
                "SHIB: 1M+ holders"
            ]
        }
        
        print("\n📈 Community Impact Matrix:")
        print(f" {'Factor':>25} | {'Impact':>25} | {'Examples':>25}")
        print("-" * 80)
        
        for i in range(len(community_factors["Factor"])):
            factor = community_factors["Factor"][i]
            impact = community_factors["Impact"][i]
            example = community_factors["Examples"][i]
            print(f" {factor:>25} | {impact:>25} | {example:>25}")
    
    @staticmethod
    def compare_meme_coins() -> None:
        """Compare meme coin characteristics"""
        print("\n 📊 MEME COIN COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Creation Year", "Supply", "Use Case", "Risk", "Community", "Volatility"],
            "DOGE": ["2013", "Infinite", "Payments", "Medium", "Massive", "High"],
            "SHIB": ["2020", "Quadrillion", "Ecosystem", "High", "Large", "Very High"],
            "PEPE": ["2023", "420 Trillion", "None", "Very High", "Medium", "Extreme"],
            "FLOKI": ["2021", "10 Trillion", "DeFi/Games", "High", "Growing", "High"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'DOGE':>15} | {'SHIB':>15} | {'PEPE':>15} | {'FLOKI':>15}")
        print("-" * 85)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            doge = comparison["DOGE"][i]
            shib = comparison["SHIB"][i]
            pepe = comparison["PEPE"][i]
            floki = comparison["FLOKI"][i]
            
            print(f" {attr:>20} | {doge:>15} | {shib:>15} | {pepe:>15} | {floki:>15}")

def demonstrate_meme_coin_engine():
    """Execute comprehensive meme coin demonstration"""
    print("=" * 60)
    print(" MEME COIN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = MemeCoinEngine()
    
    # Run demonstrations
    engine.explain_meme_coin_overview()
    engine.list_major_meme_coins()
    engine.explain_meme_coin_risks()
    
    # Additional analytics
    MemeCoinAnalytics.analyze_community_impact()
    MemeCoinAnalytics.compare_meme_coins()
    
    print("\n" + "=" * 60)
    print(" MEME COIN SUMMARY:")
    print("   ✓ Meme Coins = Crypto + Internet Culture")
    print("   ✓ Characteristics: Community-driven, volatile")
    print("   ✓ Major: DOGE, SHIB, PEPE, FLOKI")
    print("   ✓ Benefits: Community, high return potential")
    print("   ✓ Risks: Extreme volatility, no utility, scams")
    print("   ✓ Strategy: Only invest what you can lose")
    print("   ✓ Position: Entertainment and speculation")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_meme_coin_engine()

4.7 Coins vs Tokens

What are Coins and Tokens?

AspectCoinsTokens
DefinitionNative cryptocurrencyDigital asset on blockchain
BlockchainHas own blockchainBuilt on existing blockchain
PurposeCurrency, fee paymentUtility, governance, asset
ExamplesBTC, ETH, SOLUSDC, UNI, AAVE

Coins vs Tokens Comparison:

FeatureCoinsTokens
Own BlockchainYesNo
Used for FeesYesNo
UtilityPayment, store of valueApp-specific
CreationRequires blockchainEasy to create
SupplyLimitedDepends on contract

Code Example – Coins vs Tokens:

"""
COINS VS TOKENS FUNDAMENTALS FRAMEWORK
======================================
Complete comparison between cryptocurrencies and digital tokens
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class AssetType(Enum):
    """Classification of crypto assets"""
    COIN = "Coin (Native)"
    TOKEN = "Token (Smart Contract)"

@dataclass
class CryptoAsset:
    """Represents a crypto asset with its properties"""
    name: str
    symbol: str
    asset_type: AssetType
    blockchain: str
    purpose: str
    examples: List[str]
    characteristics: List[str]

@dataclass
class AssetComparison:
    """Represents a comparison between coins and tokens"""
    aspect: str
    coin: str
    token: str
    explanation: str

class CoinsTokensEngine:
    """Complete coins vs tokens demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" COINS VS TOKENS ENGINE")
        print("=" * 60)
    
    def compare_assets(self) -> None:
        """Compare coins and tokens across various aspects"""
        print("\n 📊 COINS VS TOKENS COMPARISON")
        print("-" * 40)
        
        comparisons = [
            AssetComparison(
                aspect="Definition",
                coin="Native cryptocurrency of its own blockchain",
                token="Digital asset built on existing blockchain",
                explanation="Coins are fundamental, tokens are derivative"
            ),
            AssetComparison(
                aspect="Blockchain",
                coin="Has its own independent blockchain",
                token="Runs on another blockchain (Ethereum, Solana)",
                explanation="Tokens rely on underlying network"
            ),
            AssetComparison(
                aspect="Creation",
                coin="Complex, requires forking or building chain",
                token="Easy, deploy smart contract",
                explanation="Tokens are faster and cheaper to create"
            ),
            AssetComparison(
                aspect="Purpose",
                coin="Currency, store of value, transaction fees",
                token="Utility, governance, asset representation",
                explanation="Coins are money, tokens are application-specific"
            ),
            AssetComparison(
                aspect="Fees",
                coin="Used to pay transaction fees on network",
                token="May have its own fee structure",
                explanation="Coins are required for network operations"
            ),
            AssetComparison(
                aspect="Examples",
                coin="BTC, ETH, SOL, ADA, AVAX",
                token="USDC, UNI, AAVE, LINK, MATIC",
                explanation="Different categories serve different purposes"
            )
        ]
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Aspect':>20} | {'Coins':>25} | {'Tokens':>25} | {'Explanation':>30}")
        print("-" * 105)
        
        for comp in comparisons:
            print(f" {comp.aspect:>20} | {comp.coin:>25} | {comp.token:>25} | {comp.explanation:>30}")
    
    def list_examples(self) -> None:
        """List examples of coins and tokens"""
        print("\n 🪙 COINS EXAMPLES")
        print("-" * 40)
        
        coins = [
            CryptoAsset(
                name="Bitcoin",
                symbol="BTC",
                asset_type=AssetType.COIN,
                blockchain="Bitcoin",
                purpose="Store of value, digital gold",
                examples=["BTC"],
                characteristics=["Limited supply (21M)", "First crypto", "Most secure"]
            ),
            CryptoAsset(
                name="Ethereum",
                symbol="ETH",
                asset_type=AssetType.COIN,
                blockchain="Ethereum",
                purpose="Smart contracts, gas fees",
                examples=["ETH"],
                characteristics=["Programmable", "Smart contract platform", "DeFi hub"]
            ),
            CryptoAsset(
                name="Solana",
                symbol="SOL",
                asset_type=AssetType.COIN,
                blockchain="Solana",
                purpose="High-performance dApps",
                examples=["SOL"],
                characteristics=["Fast (3000+ TPS)", "Low fees", "Scalable"]
            ),
            CryptoAsset(
                name="Cardano",
                symbol="ADA",
                asset_type=AssetType.COIN,
                blockchain="Cardano",
                purpose="Smart contracts, research",
                examples=["ADA"],
                characteristics=["Research-driven", "Academic", "Proof of Stake"]
            ),
            CryptoAsset(
                name="Avalanche",
                symbol="AVAX",
                asset_type=AssetType.COIN,
                blockchain="Avalanche",
                purpose="Subnets, custom chains",
                examples=["AVAX"],
                characteristics=["Subnet architecture", "Fast finality", "Scalable"]
            )
        ]
        
        print("\n📋 Coins:")
        for coin in coins:
            print(f"\n  {coin.name} ({coin.symbol}):")
            print(f"    Blockchain: {coin.blockchain}")
            print(f"    Purpose: {coin.purpose}")
            print(f"    Characteristics: {', '.join(coin.characteristics)}")
        
        print("\n\n 📊 TOKENS EXAMPLES")
        print("-" * 40)
        
        tokens = [
            CryptoAsset(
                name="USD Coin",
                symbol="USDC",
                asset_type=AssetType.TOKEN,
                blockchain="Ethereum, Solana, others",
                purpose="Stablecoin, payments",
                examples=["USDC"],
                characteristics=["Stable value ($1)", "Fiat-backed", "Widely used"]
            ),
            CryptoAsset(
                name="Uniswap",
                symbol="UNI",
                asset_type=AssetType.TOKEN,
                blockchain="Ethereum",
                purpose="Governance, DEX",
                examples=["UNI"],
                characteristics=["DeFi governance", "DEX protocol", "Community-owned"]
            ),
            CryptoAsset(
                name="Aave",
                symbol="AAVE",
                asset_type=AssetType.TOKEN,
                blockchain="Ethereum",
                purpose="Lending, borrowing",
                examples=["AAVE"],
                characteristics=["DeFi lending", "Interest earning", "Flash loans"]
            ),
            CryptoAsset(
                name="Chainlink",
                symbol="LINK",
                asset_type=AssetType.TOKEN,
                blockchain="Ethereum",
                purpose="Oracles, data feeds",
                examples=["LINK"],
                characteristics=["Decentralized oracles", "Data aggregation", "DeFi integration"]
            ),
            CryptoAsset(
                name="Polygon",
                symbol="MATIC",
                asset_type=AssetType.TOKEN,
                blockchain="Ethereum",
                purpose="Layer 2 scaling",
                examples=["MATIC"],
                characteristics=["Scaling solution", "Low fees", "Fast transactions"]
            )
        ]
        
        print("\n📋 Tokens:")
        for token in tokens:
            print(f"\n  {token.name} ({token.symbol}):")
            print(f"    Blockchain: {token.blockchain}")
            print(f"    Purpose: {token.purpose}")
            print(f"    Characteristics: {', '.join(token.characteristics)}")
    
    def explain_use_cases(self) -> None:
        """Explain use cases for coins and tokens"""
        print("\n 🎯 USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Coins": {
                "Store of Value": "Digital gold, long-term wealth preservation",
                "Transaction Fees": "Pay for network operations and gas",
                "Exchange Medium": "Trade between different assets",
                "Collateral": "Used in DeFi loans",
                "Network Security": "Proof of Stake validators"
            },
            "Tokens": {
                "Utility": "App-specific functionality (e.g., gaming)",
                "Governance": "Voting on protocol decisions",
                "Asset Representation": "Stablecoins, tokenized assets",
                "Liquidity Provision": "Uniswap LP tokens",
                "Rewards": "Yield farming incentives"
            }
        }
        
        print("\n📋 Coins Use Cases:")
        for use_case, description in use_cases["Coins"].items():
            print(f"  ✓ {use_case}: {description}")
        
        print("\n📋 Tokens Use Cases:")
        for use_case, description in use_cases["Tokens"].items():
            print(f"  ✓ {use_case}: {description}")

class CoinsTokensAnalytics:
    """Additional analysis tools for coins vs tokens"""
    
    @staticmethod
    def analyze_supply_models() -> None:
        """Analyze supply models for coins and tokens"""
        print("\n 📊 SUPPLY MODELS COMPARISON")
        print("-" * 40)
        
        supply_models = {
            "Attribute": ["Supply Limit", "Issuance", "Distribution", "Inflation", "Burn Mechanism"],
            "Coins": ["Fixed (BTC: 21M)", "Mining/Staking", "Decentralized", "Decreasing (Halving)", "No"],
            "Tokens": ["Variable", "Smart Contract", "Controlled", "Programmable", "Yes (EIP-1559)"]
        }
        
        print("\n📈 Supply Model Matrix:")
        print(f" {'Attribute':>20} | {'Coins':>35} | {'Tokens':>35}")
        print("-" * 95)
        
        for i in range(len(supply_models["Attribute"])):
            attr = supply_models["Attribute"][i]
            coin = supply_models["Coins"][i]
            token = supply_models["Tokens"][i]
            print(f" {attr:>20} | {coin:>35} | {token:>35}")
    
    @staticmethod
    def analyze_market_metrics() -> None:
        """Analyze market metrics for coins vs tokens"""
        print("\n 📈 MARKET METRICS")
        print("-" * 40)
        
        metrics = {
            "Metric": [
                "Total Market Cap",
                "Number of Assets",
                "Liquidity",
                "Transaction Volume",
                "Diversity"
            ],
            "Coins": [
                "~$1.5 Trillion",
                "~200",
                "High",
                "~$50B/day",
                "Limited"
            ],
            "Tokens": [
                "~$500 Billion",
                "10,000+",
                "Variable",
                "~$30B/day",
                "Extensive"
            ]
        }
        
        print("\n📋 Market Statistics:")
        print(f" {'Metric':>20} | {'Coins':>35} | {'Tokens':>35}")
        print("-" * 95)
        
        for i in range(len(metrics["Metric"])):
            metric = metrics["Metric"][i]
            coin = metrics["Coins"][i]
            token = metrics["Tokens"][i]
            print(f" {metric:>20} | {coin:>35} | {token:>35}")

def demonstrate_coins_tokens_engine():
    """Execute comprehensive coins vs tokens demonstration"""
    print("=" * 60)
    print(" COINS VS TOKENS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = CoinsTokensEngine()
    
    # Run demonstrations
    engine.compare_assets()
    engine.list_examples()
    engine.explain_use_cases()
    
    # Additional analytics
    CoinsTokensAnalytics.analyze_supply_models()
    CoinsTokensAnalytics.analyze_market_metrics()
    
    print("\n" + "=" * 60)
    print(" COINS VS TOKENS SUMMARY:")
    print("   ✓ Coins: Native, own blockchain, currency")
    print("   ✓ Tokens: Smart contract, built on chain, utility")
    print("   ✓ Coins Examples: BTC, ETH, SOL, ADA")
    print("   ✓ Tokens Examples: USDC, UNI, AAVE, LINK")
    print("   ✓ Coins: Store of value, fees, network security")
    print("   ✓ Tokens: Governance, utility, asset representation")
    print("   ✓ All coins are cryptocurrencies")
    print("   ✓ Not all cryptocurrencies are coins")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_coins_tokens_engine()

4.8 Utility Tokens

What are Utility Tokens?

Utility tokens provide users with access to specific products, services, features, or functions within a blockchain ecosystem.They are not investments but tools that enable specific functions.

Utility Token Examples:

TokenPlatformPurpose
LINKChainlinkPay for oracle services
UNIUniswapGovernance + fee sharing
AAVEAaveLending/borrowing fees
MATICPolygonPay transaction fees

Code Example – Utility Tokens:

"""
UTILITY TOKEN FUNDAMENTALS FRAMEWORK
=====================================
Complete utility token overview, use cases, and analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class UtilityType(Enum):
    """Classification of utility token types"""
    GOVERNANCE = "Governance"
    FEE_PAYMENT = "Fee Payment"
    ACCESS = "Access & Premium"
    REWARDS = "Rewards & Incentives"
    STAKING = "Staking & Validation"
    STORAGE = "Storage & Computing"

@dataclass
class UtilityToken:
    """Represents a utility token with its properties"""
    name: str
    symbol: str
    utility_type: UtilityType
    platform: str
    description: str
    examples: List[str]
    benefits: List[str]
    risks: List[str]

@dataclass
class UtilityComparison:
    """Represents a comparison between utility tokens"""
    aspect: str
    governance_token: str
    fee_token: str
    access_token: str

class UtilityTokenEngine:
    """Complete utility token fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" UTILITY TOKEN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_utility_overview(self) -> None:
        """Provide comprehensive utility token overview"""
        print("\n 🔧 UTILITY TOKEN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  UTILITY TOKENS - PLATFORM FUNCTIONALITY                  │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Utility tokens = Token with specific utility│
│  Purpose: Access products/services on a platform          │
│  Not: Investment security (though they can have value)    │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Provide access to platform features                   │
│  ✓ Enable governance participation                       │
│  ✓ Pay for transaction fees                              │
│  ✓ Earn rewards through staking                         │
│  ✓ Value tied to platform usage                         │
│  ✓ Not designed as investments                          │
│                                                           │
│  TYPES:                                                  │
│                                                           │
│  1. GOVERNANCE TOKENS                                   │
│     • Vote on protocol changes                           │
│     • Shape platform direction                           │
│     • Examples: UNI, COMP, MKR                          │
│                                                           │
│  2. FEE PAYMENT TOKENS                                  │
│     • Pay transaction fees                               │
│     • Get discounts                                      │
│     • Examples: MATIC, BNB, ETH (gas)                   │
│                                                           │
│  3. ACCESS TOKENS                                       │
│     • Premium features                                    │
│     • Platform access                                     │
│     • Examples: LINK (oracles), FIL (storage)            │
│                                                           │
│  4. REWARD TOKENS                                       │
│     • Staking rewards                                     │
│     • Liquidity mining                                    │
│     • Examples: CAKE, SUSHI, CRV                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_utility_tokens(self) -> None:
        """List major utility tokens with their properties"""
        print("\n 📊 MAJOR UTILITY TOKENS")
        print("-" * 40)
        
        tokens = [
            UtilityToken(
                name="Uniswap",
                symbol="UNI",
                utility_type=UtilityType.GOVERNANCE,
                platform="Uniswap DEX",
                description="Governance token for Uniswap protocol",
                examples=["Vote on proposals", "Protocol upgrades"],
                benefits=["Community governance", "Treasury access", "Protocol direction"],
                risks=["Low participation", "Whale influence", "Limited utility"]
            ),
            UtilityToken(
                name="Polygon",
                symbol="MATIC",
                utility_type=UtilityType.FEE_PAYMENT,
                platform="Polygon Network",
                description="Layer 2 scaling solution",
                examples=["Pay gas fees", "Stake for validators"],
                benefits=["Low fees", "Fast transactions", "Scaling benefits"],
                risks=["Network dependency", "Competition", "Gas price volatility"]
            ),
            UtilityToken(
                name="Chainlink",
                symbol="LINK",
                utility_type=UtilityType.ACCESS,
                platform="Chainlink Oracle Network",
                description="Decentralized oracle services",
                examples=["Access oracle data", "Node operator stake"],
                benefits=["Reliable data", "Smart contract integration", "DeFi essential"],
                risks=["Oracle dependency", "Competition", "Data quality"]
            ),
            UtilityToken(
                name="PancakeSwap",
                symbol="CAKE",
                utility_type=UtilityType.REWARDS,
                platform="PancakeSwap DEX",
                description="DeFi platform on BSC",
                examples=["Staking rewards", "Liquidity mining", "Lottery"],
                benefits=["Yield farming", "Passive income", "Platform participation"],
                risks=["High inflation", "Dependency on BSC", "DEX competition"]
            ),
            UtilityToken(
                name="Aave",
                symbol="AAVE",
                utility_type=UtilityType.GOVERNANCE,
                platform="Aave Protocol",
                description="DeFi lending platform",
                examples=["Governance voting", "Risk parameters", "Treasury"],
                benefits=["Community control", "Protocol improvements", "DeFi innovation"],
                risks=["Governance attacks", "Low participation", "Vulnerabilities"]
            ),
            UtilityToken(
                name="Filecoin",
                symbol="FIL",
                utility_type=UtilityType.STORAGE,
                platform="Filecoin Network",
                description="Decentralized storage network",
                examples=["Pay for storage", "Mining rewards"],
                benefits=["Decentralized storage", "Data persistence", "Redundant backups"],
                risks=["Competition", "Storage demand", "Network issues"]
            )
        ]
        
        print("\n📋 Utility Token Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Type':>15} | {'Platform':>20} | {'Description':>30}")
        print("-" * 95)
        
        for token in tokens:
            print(f" {token.name:>15} | {token.symbol:>8} | {token.utility_type.value[:15]:>15} | "
                  f"{token.platform[:20]:>20} | {token.description[:30]:>30}")
        
        print("\n📋 Benefits & Risks:")
        for token in tokens[:3]:
            print(f"\n  {token.name} ({token.symbol}):")
            print(f"    Benefits: {', '.join(token.benefits)}")
            print(f"    Risks: {', '.join(token.risks)}")
    
    def explain_utility_use_cases(self) -> None:
        """Explain utility token use cases"""
        print("\n 🎯 UTILITY TOKEN USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Governance": {
                "description": "Vote on protocol changes and decisions",
                "examples": ["UNI proposal votes", "Aave risk parameters"],
                "benefits": ["Democratic control", "Community ownership", "Protocol evolution"],
                "platforms": ["Uniswap", "Aave", "Compound"]
            },
            "Fee Payment": {
                "description": "Pay for transaction fees and services",
                "examples": ["MATIC gas fees", "BNB for BSC gas"],
                "benefits": ["Discounted fees", "Network access", "Transaction settlement"],
                "platforms": ["Polygon", "BNB Chain", "Ethereum"]
            },
            "Access & Premium": {
                "description": "Access platform features and services",
                "examples": ["LINK oracle services", "FIL storage access"],
                "benefits": ["Platform utility", "Premium features", "Service access"],
                "platforms": ["Chainlink", "Filecoin", "Arweave"]
            },
            "Staking & Rewards": {
                "description": "Earn rewards through token staking",
                "examples": ["CAKE staking", "CRV liquidity mining"],
                "benefits": ["Passive income", "Yield farming", "Platform incentives"],
                "platforms": ["PancakeSwap", "Curve", "SushiSwap"]
            }
        }
        
        print("\n📋 Application Areas:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Examples: {', '.join(details['examples'])}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Platforms: {', '.join(details['platforms'])}")

class UtilityAnalytics:
    """Additional analysis tools for utility tokens"""
    
    @staticmethod
    def compare_utility_types() -> None:
        """Compare different utility token types"""
        print("\n 📊 UTILITY TOKEN TYPE COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Purpose", "Value Source", "Holders", "Examples", "Risks"],
            "Governance": ["Protocol decisions", "Activity", "Active users", "UNI, AAVE", "Low participation"],
            "Fee": ["Transaction costs", "Usage", "Users", "MATIC, BNB", "Network dependency"],
            "Access": ["Platform features", "Demand", "Service users", "LINK, FIL", "Service quality"],
            "Reward": ["Yield/incentives", "Locked value", "Yield farmers", "CAKE, CRV", "Inflation risk"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Governance':>20} | {'Fee':>20} | {'Access':>20} | {'Reward':>20}")
        print("-" * 105)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            gov = comparison["Governance"][i]
            fee = comparison["Fee"][i]
            access = comparison["Access"][i]
            reward = comparison["Reward"][i]
            
            print(f" {attr:>20} | {gov:>20} | {fee:>20} | {access:>20} | {reward:>20}")
    
    @staticmethod
    def analyze_utility_value() -> None:
        """Analyze utility token value proposition"""
        print("\n 📈 UTILITY TOKEN VALUE ANALYSIS")
        print("-" * 40)
        
        value_factors = {
            "Factor": [
                "Platform Usage",
                "Token Velocity",
                "Community Engagement",
                "Development Activity",
                "Partnerships",
                "Regulatory Status"
            ],
            "Impact": [
                "High usage = High demand",
                "Lower velocity = Higher value",
                "Active community = Stronger ecosystem",
                "Active development = Innovation",
                "Strategic partnerships = Growth",
                "Clear regulation = Stability"
            ],
            "Examples": [
                "Uniswap: $1B+ volume",
                "LINK: Store of value",
                "AAVE: Governance participation",
                "MATIC: Continuous upgrades",
                "FIL: Storage provider deals",
                "Utility tokens: Vary by jurisdiction"
            ]
        }
        
        print("\n📋 Value Drivers:")
        print(f" {'Factor':>25} | {'Impact':>35} | {'Examples':>30}")
        print("-" * 95)
        
        for i in range(len(value_factors["Factor"])):
            factor = value_factors["Factor"][i]
            impact = value_factors["Impact"][i]
            example = value_factors["Examples"][i]
            print(f" {factor:>25} | {impact:>35} | {example:>30}")

def demonstrate_utility_token_engine():
    """Execute comprehensive utility token demonstration"""
    print("=" * 60)
    print(" UTILITY TOKEN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = UtilityTokenEngine()
    
    # Run demonstrations
    engine.explain_utility_overview()
    engine.list_utility_tokens()
    engine.explain_utility_use_cases()
    
    # Additional analytics
    UtilityAnalytics.compare_utility_types()
    UtilityAnalytics.analyze_utility_value()
    
    print("\n" + "=" * 60)
    print(" UTILITY TOKEN SUMMARY:")
    print("   ✓ Utility Tokens = Token with platform utility")
    print("   ✓ Types: Governance, Fee, Access, Rewards")
    print("   ✓ Examples: UNI, MATIC, LINK, CAKE")
    print("   ✓ Benefits: Access, governance, fees, rewards")
    print("   ✓ Risks: Platform dependency, volatility, regulation")
    print("   ✓ Position: Essential for platform functionality")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_utility_token_engine()

4.9 Governance Tokens

What are Governance Tokens?

Governance tokens give holders the right to vote on decisions in decentralized protocols. They enable community-driven governance and decentralization.

Governance Token Features:

FeatureDescription
VotingVote on proposals
ProposalsSubmit changes
DelegationDelegate votes
TreasuryControl funds

Examples: UNI (Uniswap), AAVE (Aave), COMP (Compound), MKR (MakerDAO)

Code Example – Governance Tokens:

"""
GOVERNANCE TOKEN FUNDAMENTALS FRAMEWORK
========================================
Complete governance token overview, participation, and ecosystem analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class GovernanceType(Enum):
    """Classification of governance mechanisms"""
    TOKEN_WEIGHTED = "Token-Weighted Voting"
    REPUTATION_BASED = "Reputation-Based"
    PLUTOCRACY = "Plutocratic (Whale-Favored)"
    DEMOCRATIC = "Democratic (One-Token-One-Vote)"

@dataclass
class GovernanceToken:
    """Represents a governance token with its properties"""
    name: str
    symbol: str
    platform: str
    governance_type: GovernanceType
    voting_power: str
    examples: List[str]
    benefits: List[str]
    risks: List[str]

@dataclass
class GovernanceProposal:
    """Represents a governance proposal"""
    title: str
    description: str
    proposer: str
    votes_for: int
    votes_against: int
    status: str
    quorum: int

class GovernanceTokenEngine:
    """Complete governance token fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" GOVERNANCE TOKEN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_governance_overview(self) -> None:
        """Provide comprehensive governance token overview"""
        print("\n 🗳️  GOVERNANCE TOKEN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  GOVERNANCE TOKENS - DECENTRALIZED DECISION-MAKING       │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Governance Tokens = Voting Rights           │
│  Purpose: Enable decentralized decision-making            │
│                                                           │
│  HOW IT WORKS:                                           │
│  1. Token holders vote on proposals                       │
│  2. Voting power weighted by token holdings              │
│  3. Proposals can include:                               │
│     • Protocol changes (upgrades)                        │
│     • Treasury allocation                               │
│     • Fee structures                                    │
│     • Parameter adjustments                             │
│     • Partnership approvals                             │
│                                                           │
│  GOVERNANCE MECHANISMS:                                  │
│                                                           │
│  1. Token-Weighted Voting                                │
│     • More tokens = More votes                           │
│     • Examples: UNI, AAVE                               │
│     • Advantage: Simple, aligned with economic interest  │
│     • Disadvantage: Whale dominance                     │
│                                                           │
│  2. Reputation-Based                                    │
│     • Based on contributions                             │
│     • Examples: Optimism, Gitcoin                       │
│     • Advantage: Merit-based                            │
│     • Disadvantage: Complex evaluation                  │
│                                                           │
│  3. Quadratic Voting                                    │
│     • Square root of tokens                              │
│     • Reduces whale power                                │
│     • Examples: Experimental                            │
│     • Advantage: More democratic                        │
│     • Disadvantage: Complex math                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_governance_tokens(self) -> None:
        """List major governance tokens with their properties"""
        print("\n 📊 MAJOR GOVERNANCE TOKENS")
        print("-" * 40)
        
        tokens = [
            GovernanceToken(
                name="Uniswap",
                symbol="UNI",
                platform="Uniswap Protocol",
                governance_type=GovernanceType.TOKEN_WEIGHTED,
                voting_power="1 UNI = 1 Vote",
                examples=["Fee switch", "Treasury allocation", "Protocol upgrades"],
                benefits=["Community governance", "Protocol direction", "Treasury access"],
                risks=["Whale dominance", "Low participation", "Governance attacks"]
            ),
            GovernanceToken(
                name="Aave",
                symbol="AAVE",
                platform="Aave Protocol",
                governance_type=GovernanceType.TOKEN_WEIGHTED,
                voting_power="1 AAVE = 1 Vote",
                examples=["Risk parameters", "Lending rates", "New assets"],
                benefits=["Risk management", "Protocol control", "Community voting"],
                risks=["Slow decisions", "Whale influence", "Low turnout"]
            ),
            GovernanceToken(
                name="Compound",
                symbol="COMP",
                platform="Compound Protocol",
                governance_type=GovernanceType.TOKEN_WEIGHTED,
                voting_power="1 COMP = 1 Vote",
                examples=["Collateral factors", "Interest rates", "Treasury"],
                benefits=["Protocol control", "Community governance", "Innovation"],
                risks=["Governance capture", "Low participation", "Complex proposals"]
            ),
            GovernanceToken(
                name="Maker",
                symbol="MKR",
                platform="MakerDAO",
                governance_type=GovernanceType.TOKEN_WEIGHTED,
                voting_power="1 MKR = 1 Vote",
                examples=["Stability fees", "Collateral types", "Treasury"],
                benefits=["Protocol stability", "Risk management", "Community control"],
                risks=["Governance attacks", "Critical decisions", "Complexity"]
            )
        ]
        
        print("\n📋 Governance Token Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Platform':>20} | {'Voting Power':>20} | {'Type':>15}")
        print("-" * 85)
        
        for token in tokens:
            print(f" {token.name:>15} | {token.symbol:>8} | {token.platform[:20]:>20} | "
                  f"{token.voting_power[:20]:>20} | {token.governance_type.value[:15]:>15}")
        
        print("\n📋 Benefits & Risks:")
        for token in tokens[:3]:
            print(f"\n  {token.name} ({token.symbol}):")
            print(f"    Benefits: {', '.join(token.benefits)}")
            print(f"    Risks: {', '.join(token.risks)}")
    
    def explain_governance_process(self) -> None:
        """Explain the governance proposal process"""
        print("\n 📋 GOVERNANCE PROPOSAL PROCESS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  PROPOSAL LIFECYCLE                                      │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1. DISCUSSION PHASE                                     │
│     • Community forum discussion                          │
│     • Idea refinement                                     │
│     • Feedback gathering                                  │
│     • Duration: Days to weeks                             │
│                                                           │
│  2. PROPOSAL CREATION                                    │
│     • Formal proposal written                             │
│     • Technical specifications                            │
│     • Implementation details                              │
│     • Duration: 1-2 days                                  │
│                                                           │
│  3. VOTING PHASE                                         │
│     • Token holders vote                                  │
│     • Quorum requirement                                  │
│     • Voting period (3-7 days)                           │
│     • Weighted by tokens                                  │
│                                                           │
│  4. EXECUTION                                            │
│     • If approved, proposal executes                      │
│     • Timelock for safety                                 │
│     • Implementation                                     │
│     • Monitoring                                          │
│                                                           │
│  5. POST-IMPLEMENTATION                                  │
│     • Monitoring and evaluation                          │
│     • Adjustments if needed                               │
│     • Community feedback                                  │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_voting_mechanisms(self) -> None:
        """Explain different voting mechanisms"""
        print("\n 🔄 VOTING MECHANISMS")
        print("-" * 40)
        
        mechanisms = {
            "Token-Weighted Voting": {
                "description": "Voting power = token balance",
                "pros": ["Simple", "Aligned incentives", "Easy to implement"],
                "cons": ["Whale dominance", "Plutocratic", "Low participation"],
                "examples": ["UNI", "AAVE", "COMP"]
            },
            "Quadratic Voting": {
                "description": "Votes = sqrt(tokens)",
                "pros": ["More democratic", "Reduces whale power", "Better representation"],
                "cons": ["Complex math", "Can be gamed", "Experimental"],
                "examples": ["Gitcoin", "Experimental DAOs"]
            },
            "Delegate Voting": {
                "description": "Delegate votes to representatives",
                "pros": ["Expert representation", "Less voter fatigue", "Better decisions"],
                "cons": ["Centralization risk", "Delegation power", "Accountability issues"],
                "examples": ["Uniswap", "Aave", "ENS"]
            },
            "Reputation-Based": {
                "description": "Voting power based on contributions",
                "pros": ["Merit-based", "Expert-driven", "Quality decisions"],
                "cons": ["Complex evaluation", "Can be subjective", "Exclusionary"],
                "examples": ["Optimism", "Gitcoin"]
            }
        }
        
        print("\n📋 Voting Mechanisms:")
        for mechanism, details in mechanisms.items():
            print(f"\n  {mechanism}:")
            print(f"    Description: {details['description']}")
            print(f"    Pros: {', '.join(details['pros'])}")
            print(f"    Cons: {', '.join(details['cons'])}")
            print(f"    Examples: {', '.join(details['examples'])}")

class GovernanceAnalytics:
    """Additional analysis tools for governance tokens"""
    
    @staticmethod
    def analyze_participation() -> None:
        """Analyze governance participation metrics"""
        print("\n 📊 GOVERNANCE PARTICIPATION ANALYSIS")
        print("-" * 40)
        
        metrics = {
            "Metric": [
                "Average Voter Turnout",
                "Proposal Success Rate",
                "Voting Period Duration",
                "Quorum Requirement",
                "Delegation Rate",
                "Whale Dominance"
            ],
            "Value": [
                "~10-30%",
                "~70-80%",
                "3-7 days",
                "4-10% of supply",
                "~50-70%",
                "~30-50%"
            ],
            "Trend": [
                "Improving",
                "Stable",
                "Standardized",
                "Optimizing",
                "Increasing",
                "Decreasing"
            ]
        }
        
        print("\n📈 Participation Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Trend':>15}")
        print("-" * 65)
        
        for i in range(len(metrics["Metric"])):
            metric = metrics["Metric"][i]
            value = metrics["Value"][i]
            trend = metrics["Trend"][i]
            print(f" {metric:>25} | {value:>20} | {trend:>15}")
    
    @staticmethod
    def analyze_governance_risks() -> None:
        """Analyze governance token risks"""
        print("\n ⚠️  GOVERNANCE TOKEN RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Governance Attack": {
                "description": "Malicious proposal passing",
                "impact": "Protocol compromise, theft",
                "mitigation": "Timelocks, multisig, veto rights",
                "example": "Beehive hack"
            },
            "Whale Dominance": {
                "description": "Large holders control decisions",
                "impact": "Plutocratic governance",
                "mitigation": "Quadratic voting, reputation",
                "example": "Uniswap whale voting"
            },
            "Voter Apathy": {
                "description": "Low participation rates",
                "impact": "Governance capture, poor decisions",
                "mitigation": "Incentives, education",
                "example": "Compound low turnout"
            },
            "Proposal Spam": {
                "description": "Low-quality proposals",
                "impact": "Wasted time, confusion",
                "mitigation": "Minimum requirements, fees",
                "example": "DAO spam proposals"
            },
            "Bribery": {
                "description": "Vote buying and incentives",
                "impact": "Corrupted decisions",
                "mitigation": "Transparency, penalties",
                "example": "Vote buying in DAOs"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")
            print(f"    Example: {details['example']}")

def demonstrate_governance_engine():
    """Execute comprehensive governance token demonstration"""
    print("=" * 60)
    print(" GOVERNANCE TOKEN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GovernanceTokenEngine()
    
    # Run demonstrations
    engine.explain_governance_overview()
    engine.list_governance_tokens()
    engine.explain_governance_process()
    engine.explain_voting_mechanisms()
    
    # Additional analytics
    GovernanceAnalytics.analyze_participation()
    GovernanceAnalytics.analyze_governance_risks()
    
    print("\n" + "=" * 60)
    print(" GOVERNANCE TOKEN SUMMARY:")
    print("   ✓ Governance Tokens = Voting Rights")
    print("   ✓ Purpose: Decentralized decision-making")
    print("   ✓ Major: UNI, AAVE, COMP, MKR")
    print("   ✓ Mechanisms: Token-weighted, quadratic, delegation")
    print("   ✓ Process: Discussion → Proposal → Vote → Execution")
    print("   ✓ Benefits: Community ownership, decentralization")
    print("   ✓ Risks: Whale dominance, low participation, attacks")
    print("   ✓ Position: Foundation of DAOs")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_governance_engine()

4.10 Security Tokens

What are Security Tokens?

Security tokens represent ownership or economic rights in real-world assets, such as stocks, bonds, or real estate. They are subject to securities regulations and represent investment contracts.

Security Token Features:

FeatureDescription
Asset-BackedRepresent real assets
RegulatedSubject to securities laws
DividendsMay pay dividends
OwnershipRepresent ownership

Code Example – Security Tokens:

"""
SECURITY TOKEN FUNDAMENTALS FRAMEWORK
======================================
Complete security token overview, asset types, and regulatory considerations
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class AssetType(Enum):
    """Classification of security token asset types"""
    REAL_ESTATE = "Real Estate"
    EQUITY = "Equity (Stocks)"
    DEBT = "Debt (Bonds)"
    COMMODITY = "Commodity"
    PRIVATE_EQUITY = "Private Equity"
    FUND = "Investment Fund"

@dataclass
class SecurityToken:
    """Represents a security token with its properties"""
    name: str
    asset_type: AssetType
    issuer: str
    jurisdiction: str
    description: str
    examples: List[str]
    benefits: List[str]
    risks: List[str]

@dataclass
class RegulatoryRequirement:
    """Represents a regulatory requirement for security tokens"""
    requirement: str
    description: str
    jurisdiction: str
    compliance_effort: str

class SecurityTokenEngine:
    """Complete security token fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" SECURITY TOKEN FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_security_overview(self) -> None:
        """Provide comprehensive security token overview"""
        print("\n 📜 SECURITY TOKEN OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SECURITY TOKENS - ASSET-BACKED TOKENS                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Security Tokens = Asset-backed tokens       │
│  Purpose: Tokenize real-world assets                     │
│  Classification: Subject to securities regulations       │
│                                                           │
│  ASSET TYPES:                                            │
│  • Real Estate: Property tokenization                     │
│  • Equity: Company stocks                                │
│  • Debt: Bonds and loans                                 │
│  • Commodities: Gold, silver, oil                        │
│  • Private Equity: Venture capital                        │
│  • Investment Funds: Mutual funds, hedge funds           │
│                                                           │
│  KEY FEATURES:                                           │
│  ✓ Asset-Backed: Tangible value support                  │
│  ✓ Regulated: Subject to securities laws                 │
│  ✓ Dividends: Share in profits                          │
│  ✓ Voting Rights: Governance participation               │
│  ✓ Fractional Ownership: Split assets into shares        │
│  ✓ Liquidity: Easier to trade                           │
│                                                           │
│  REGULATORY COMPLIANCE:                                  │
│  • KYC/AML requirements                                  │
│  • Accredited investor rules                            │
│  • SEC registration (US)                                 │
│  • Prospectus requirements                               │
│  • Transfer restrictions                                 │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_security_tokens(self) -> None:
        """List major security token examples"""
        print("\n 📊 SECURITY TOKEN EXAMPLES")
        print("-" * 40)
        
        tokens = [
            SecurityToken(
                name="Real Estate Token",
                asset_type=AssetType.REAL_ESTATE,
                issuer="Various Real Estate Firms",
                jurisdiction="US, Europe, Asia",
                description="Fractional ownership of real estate properties",
                examples=["Residential buildings", "Commercial real estate", "Mixed-use developments"],
                benefits=["Fractional ownership", "Liquidity", "Dividend income", "Appreciation"],
                risks=["Property market volatility", "Illiquidity", "Maintenance costs"]
            ),
            SecurityToken(
                name="Equity Token",
                asset_type=AssetType.EQUITY,
                issuer="Companies/Startups",
                jurisdiction="Global",
                description="Tokenized company shares",
                examples=["Startup shares", "Private company equity", "Public company stock"],
                benefits=["Easy transfer", "Global access", "24/7 trading", "Dividends"],
                risks=["Market risk", "Company performance", "Regulatory changes"]
            ),
            SecurityToken(
                name="Debt Token",
                asset_type=AssetType.DEBT,
                issuer="Corporations/Governments",
                jurisdiction="US, Europe",
                description="Tokenized bonds and loans",
                examples=["Corporate bonds", "Government bonds", "Convertible notes"],
                benefits=["Fixed income", "Risk management", "Portfolio diversification"],
                risks=["Default risk", "Interest rate risk", "Credit risk"]
            ),
            SecurityToken(
                name="Commodity Token",
                asset_type=AssetType.COMMODITY,
                issuer="Commodity Firms",
                jurisdiction="Global",
                description="Tokenized physical commodities",
                examples=["Gold-backed tokens", "Silver-backed tokens", "Oil-backed tokens"],
                benefits=["Physical asset backing", "Price stability", "Hedge against inflation"],
                risks=["Storage costs", "Price volatility", "Counterparty risk"]
            )
        ]
        
        print("\n📋 Security Token Details:")
        print(f" {'Name':>20} | {'Asset Type':>15} | {'Jurisdiction':>15} | {'Description':>35}")
        print("-" * 90)
        
        for token in tokens:
            print(f" {token.name[:20]:>20} | {token.asset_type.value[:15]:>15} | "
                  f"{token.jurisdiction[:15]:>15} | {token.description[:35]:>35}")
        
        print("\n📋 Benefits & Risks:")
        for token in tokens[:3]:
            print(f"\n  {token.name}:")
            print(f"    Benefits: {', '.join(token.benefits)}")
            print(f"    Risks: {', '.join(token.risks)}")
    
    def explain_regulatory_requirements(self) -> None:
        """Explain regulatory requirements for security tokens"""
        print("\n ⚖️  REGULATORY REQUIREMENTS")
        print("-" * 40)
        
        regulations = [
            RegulatoryRequirement(
                requirement="KYC/AML",
                description="Identity verification and anti-money laundering checks",
                jurisdiction="Global",
                compliance_effort="High"
            ),
            RegulatoryRequirement(
                requirement="Accredited Investor",
                description="Investor must meet net worth/income requirements",
                jurisdiction="US",
                compliance_effort="Medium"
            ),
            RegulatoryRequirement(
                requirement="SEC Registration",
                description="Register with Securities and Exchange Commission",
                jurisdiction="US",
                compliance_effort="Very High"
            ),
            RegulatoryRequirement(
                requirement="Prospectus",
                description="Detailed disclosure document",
                jurisdiction="Global",
                compliance_effort="High"
            ),
            RegulatoryRequirement(
                requirement="Transfer Restrictions",
                description="Lock-up periods and transfer limits",
                jurisdiction="Global",
                compliance_effort="Medium"
            ),
            RegulatoryRequirement(
                requirement="Auditing",
                description="Regular financial and compliance audits",
                jurisdiction="Global",
                compliance_effort="High"
            )
        ]
        
        print("\n📋 Regulatory Requirements:")
        print(f" {'Requirement':>25} | {'Description':>35} | {'Jurisdiction':>15} | {'Compliance':>15}")
        print("-" * 95)
        
        for reg in regulations:
            print(f" {reg.requirement:>25} | {reg.description[:35]:>35} | "
                  f"{reg.jurisdiction:>15} | {reg.compliance_effort:>15}")
    
    def explain_security_token_benefits(self) -> None:
        """Explain benefits of security tokens"""
        print("\n 💎 SECURITY TOKEN BENEFITS")
        print("-" * 40)
        
        benefits = {
            "Fractional Ownership": {
                "description": "Split assets into smaller shares",
                "impact": "More accessible to retail investors",
                "example": "Properties split into $1,000 shares"
            },
            "Liquidity": {
                "description": "Easier to buy and sell",
                "impact": "Reduced holding periods",
                "example": "24/7 trading on crypto exchanges"
            },
            "Transparency": {
                "description": "Clear ownership and valuation",
                "impact": "Reduced fraud and disputes",
                "example": "On-chain provenance and records"
            },
            "Accessibility": {
                "description": "Global investor access",
                "impact": "International capital flow",
                "example": "Investors from multiple countries"
            },
            "Automation": {
                "description": "Smart contract automation",
                "impact": "Reduced administrative costs",
                "example": "Automated dividend distribution"
            },
            "Programmable Compliance": {
                "description": "Built-in regulatory compliance",
                "impact": "Reduced compliance costs",
                "example": "Transfer restrictions in smart contracts"
            }
        }
        
        print("\n📋 Key Benefits:")
        for benefit, details in benefits.items():
            print(f"\n  {benefit}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Example: {details['example']}")

class SecurityAnalytics:
    """Additional analysis tools for security tokens"""
    
    @staticmethod
    def analyze_market_comparison() -> None:
        """Compare security tokens with traditional assets"""
        print("\n 📊 SECURITY TOKENS VS TRADITIONAL ASSETS")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Liquidity", "Access", "Trading Hours", "Settlement", "Fractional Ownership"],
            "Traditional": ["Low", "Restricted", "Market Hours", "Days", "Limited"],
            "Security Tokens": ["High", "Global", "24/7", "Minutes", "Yes"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>25} | {'Traditional Assets':>25} | {'Security Tokens':>25}")
        print("-" * 80)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            trad = comparison["Traditional"][i]
            token = comparison["Security Tokens"][i]
            print(f" {attr:>25} | {trad:>25} | {token:>25}")
    
    @staticmethod
    def analyze_risks() -> None:
        """Analyze security token risks"""
        print("\n ⚠️  SECURITY TOKEN RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Regulatory Risk": {
                "description": "Changes in securities laws",
                "impact": "Compliance costs, restrictions",
                "mitigation": "Legal counsel, compliance team"
            },
            "Counterparty Risk": {
                "description": "Dependency on issuers",
                "impact": "Loss of asset value",
                "mitigation": "Due diligence, audits"
            },
            "Liquidity Risk": {
                "description": "Limited trading volume",
                "impact": "Price discounts",
                "mitigation": "Market making, exchange listings"
            },
            "Technical Risk": {
                "description": "Smart contract vulnerabilities",
                "impact": "Asset loss, hacks",
                "mitigation": "Audits, insurance"
            },
            "Valuation Risk": {
                "description": "Price discovery challenges",
                "impact": "Volatility, mispricing",
                "mitigation": "Transparency, reporting"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_security_token_engine():
    """Execute comprehensive security token demonstration"""
    print("=" * 60)
    print(" SECURITY TOKEN FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = SecurityTokenEngine()
    
    # Run demonstrations
    engine.explain_security_overview()
    engine.list_security_tokens()
    engine.explain_regulatory_requirements()
    engine.explain_security_token_benefits()
    
    # Additional analytics
    SecurityAnalytics.analyze_market_comparison()
    SecurityAnalytics.analyze_risks()
    
    print("\n" + "=" * 60)
    print(" SECURITY TOKEN SUMMARY:")
    print("   ✓ Security Tokens = Asset-backed tokens")
    print("   ✓ Asset Types: Real estate, equity, debt, commodities")
    print("   ✓ Benefits: Fractional ownership, liquidity, transparency")
    print("   ✓ Risks: Regulatory, counterparty, liquidity, technical")
    print("   ✓ Compliance: KYC/AML, accredited investor, SEC registration")
    print("   ✓ Position: Bridge between traditional and crypto finance")
    print("   ✓ Future: Tokenization of real-world assets")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_security_token_engine()

4.11 Tokenomics

What is Tokenomics?

Tokenomics (token economics) is the study of how cryptocurrency tokens work economically. It covers token supply, distribution, utility, and economic incentives.

Key Tokenomics Concepts:

ConceptDescription
SupplyTotal tokens available
DistributionHow tokens are allocated
UtilityWhat tokens do
IncentivesWhy people hold tokens

Code Example – Tokenomics:

"""
TOKENOMICS FUNDAMENTALS FRAMEWORK
==================================
Complete token economics overview, models, and analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class SupplyType(Enum):
    """Classification of token supply models"""
    FIXED = "Fixed Supply"
    INFLATIONARY = "Inflationary"
    DEFLATIONARY = "Deflationary"
    DYNAMIC = "Dynamic/Algorithmic"

class DistributionType(Enum):
    """Classification of token distribution methods"""
    ICO = "Initial Coin Offering"
    IDO = "Initial DEX Offering"
    AIRDROP = "Airdrop"
    MINING = "Mining/Staking"
    TEAM = "Team/Foundation"
    PUBLIC = "Public Sale"

@dataclass
class TokenomicsModel:
    """Represents a tokenomics model with its properties"""
    name: str
    token_symbol: str
    supply_type: SupplyType
    total_supply: str
    distribution: List[DistributionType]
    utility: List[str]
    incentives: List[str]
    burn_mechanism: bool

@dataclass
class TokenomicsMetric:
    """Represents a tokenomics metric"""
    metric: str
    value: str
    description: str
    category: str

class TokenomicsEngine:
    """Complete token economics demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" TOKENOMICS FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_tokenomics_overview(self) -> None:
        """Provide comprehensive tokenomics overview"""
        print("\n 📊 TOKENOMICS OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  TOKENOMICS - TOKEN ECONOMICS                             │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Tokenomics = Token Economics                │
│  Purpose: Design token's economic model                   │
│                                                           │
│  COMPONENTS:                                             │
│                                                           │
│  1. SUPPLY MODEL                                         │
│     • Fixed: BTC (21M), ADA (45B)                       │
│     • Inflationary: ETH (no cap)                        │
│     • Deflationary: Burn mechanisms                     │
│     • Dynamic: Algorithmic adjustments                   │
│                                                           │
│  2. DISTRIBUTION PLAN                                    │
│     • Initial Coin Offering (ICO)                       │
│     • Initial DEX Offering (IDO)                       │
│     • Airdrops to community                             │
│     • Mining/Staking rewards                            │
│     • Team/Foundation allocation                        │
│     • Public sale                                       │
│                                                           │
│  3. UTILITY VALUE                                        │
│     • Payment for services                               │
│     • Governance voting                                  │
│     • Staking for rewards                                │
│     • Access to features                                 │
│     • Collateral in DeFi                                │
│                                                           │
│  4. INCENTIVE STRUCTURE                                  │
│     • Staking rewards                                    │
│     • Liquidity mining                                   │
│     • Referral programs                                  │
│     • Governance participation                           │
│     • Ecosystem growth                                   │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_tokenomics_models(self) -> None:
        """List major tokenomics models"""
        print("\n 📈 TOKENOMICS MODELS")
        print("-" * 40)
        
        models = [
            TokenomicsModel(
                name="Bitcoin",
                token_symbol="BTC",
                supply_type=SupplyType.FIXED,
                total_supply="21,000,000",
                distribution=[DistributionType.MINING],
                utility=["Store of Value", "Payment", "Collateral"],
                incentives=["Block rewards", "Transaction fees"],
                burn_mechanism=False
            ),
            TokenomicsModel(
                name="Ethereum",
                token_symbol="ETH",
                supply_type=SupplyType.INFLATIONARY,
                total_supply="~120,000,000 (No cap)",
                distribution=[DistributionType.MINING, DistributionType.PUBLIC],
                utility=["Gas fees", "Staking", "DeFi", "NFTs"],
                incentives=["Staking rewards"],
                burn_mechanism=True
            ),
            TokenomicsModel(
                name="Uniswap",
                token_symbol="UNI",
                supply_type=SupplyType.FIXED,
                total_supply="1,000,000,000",
                distribution=[DistributionType.AIRDROP, DistributionType.PUBLIC],
                utility=["Governance", "Fee discount"],
                incentives=["Governance participation"],
                burn_mechanism=False
            ),
            TokenomicsModel(
                name="Solana",
                token_symbol="SOL",
                supply_type=SupplyType.INFLATIONARY,
                total_supply="~489,000,000 (Inflationary)",
                distribution=[DistributionType.PUBLIC, DistributionType.MINING],
                utility=["Gas fees", "Staking", "DeFi"],
                incentives=["Staking rewards", "Transaction fees"],
                burn_mechanism=True
            )
        ]
        
        print("\n📋 Tokenomics Model Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Supply Type':>20} | {'Total Supply':>20} | {'Burn':>8}")
        print("-" * 75)
        
        for model in models:
            print(f" {model.name:>15} | {model.token_symbol:>8} | {model.supply_type.value[:20]:>20} | "
                  f"{model.total_supply[:20]:>20} | {'✅' if model.burn_mechanism else '❌':>8}")
        
        print("\n📋 Distribution & Utility:")
        for model in models[:3]:
            print(f"\n  {model.name} ({model.token_symbol}):")
            print(f"    Distribution: {', '.join([d.value for d in model.distribution])}")
            print(f"    Utility: {', '.join(model.utility)}")
            print(f"    Incentives: {', '.join(model.incentives)}")
    
    def explain_tokenomics_components(self) -> None:
        """Explain tokenomics components in detail"""
        print("\n 🔧 TOKENOMICS COMPONENTS")
        print("-" * 40)
        
        components = {
            "Supply Economics": {
                "description": "How tokens are created and managed",
                "types": ["Fixed (BTC)", "Inflationary (ETH)", "Deflationary (Burn)"],
                "importance": "Determines scarcity and value"
            },
            "Distribution Strategy": {
                "description": "How tokens are allocated",
                "types": ["Public Sale", "Team Allocation", "Airdrops", "Mining/Staking"],
                "importance": "Ensures fair and decentralized distribution"
            },
            "Utility Design": {
                "description": "What tokens can do",
                "types": ["Governance", "Payments", "Staking", "Access"],
                "importance": "Creates demand and value"
            },
            "Incentive Alignment": {
                "description": "How participants are rewarded",
                "types": ["Staking rewards", "Liquidity mining", "Referral programs"],
                "importance": "Drives participation and growth"
            }
        }
        
        print("\n📋 Component Details:")
        for component, details in components.items():
            print(f"\n  {component}:")
            print(f"    Description: {details['description']}")
            print(f"    Types: {', '.join(details['types'])}")
            print(f"    Importance: {details['importance']}")
    
    def explain_tokenomics_analysis(self) -> None:
        """Explain how to analyze tokenomics"""
        print("\n 📊 TOKENOMICS ANALYSIS FRAMEWORK")
        print("-" * 40)
        
        analysis_factors = {
            "Supply Analysis": {
                "questions": [
                    "Is supply capped or infinite?",
                    "What is the inflation rate?",
                    "Is there a burn mechanism?",
                    "How is new supply created?"
                ],
                "importance": "Determines long-term value potential"
            },
            "Distribution Analysis": {
                "questions": [
                    "How are tokens distributed?",
                    "Is there a fair launch?",
                    "What's the team allocation?",
                    "Are there vesting schedules?"
                ],
                "importance": "Affects decentralization and market dynamics"
            },
            "Utility Analysis": {
                "questions": [
                    "What can tokens do?",
                    "Is there real demand?",
                    "How is value captured?",
                    "Are there competitive advantages?"
                ],
                "importance": "Drives token value and adoption"
            },
            "Incentive Analysis": {
                "questions": [
                    "How are participants rewarded?",
                    "Are incentives sustainable?",
                    "What are the token velocity metrics?",
                    "Is there value accumulation?"
                ],
                "importance": "Determines user retention and growth"
            }
        }
        
        print("\n📋 Analysis Framework:")
        for factor, details in analysis_factors.items():
            print(f"\n  {factor}:")
            print(f"    Questions:")
            for question in details['questions']:
                print(f"      • {question}")
            print(f"    Importance: {details['importance']}")

class TokenomicsAnalytics:
    """Additional analysis tools for tokenomics"""
    
    @staticmethod
    def analyze_supply_models() -> None:
        """Analyze different supply models"""
        print("\n 📈 SUPPLY MODEL ANALYSIS")
        print("-" * 40)
        
        supply_models = {
            "Attribute": ["Supply Cap", "Inflation", "Deflation", "Scarcity", "Value Appreciation"],
            "Fixed": ["Yes", "No", "No", "High", "Potential"],
            "Inflationary": ["No", "Yes", "Variable", "Medium", "Variable"],
            "Deflationary": ["Yes", "No", "Yes", "Very High", "High"],
            "Dynamic": ["Variable", "Variable", "Variable", "Variable", "Variable"]
        }
        
        print("\n📋 Supply Model Comparison:")
        print(f" {'Attribute':>20} | {'Fixed':>15} | {'Inflationary':>15} | {'Deflationary':>15} | {'Dynamic':>15}")
        print("-" * 85)
        
        for i in range(len(supply_models["Attribute"])):
            attr = supply_models["Attribute"][i]
            fixed = supply_models["Fixed"][i]
            inflationary = supply_models["Inflationary"][i]
            deflationary = supply_models["Deflationary"][i]
            dynamic = supply_models["Dynamic"][i]
            
            print(f" {attr:>20} | {fixed:>15} | {inflationary:>15} | {deflationary:>15} | {dynamic:>15}")
    
    @staticmethod
    def analyze_token_velocity() -> None:
        """Analyze token velocity and its impact"""
        print("\n 📊 TOKEN VELOCITY ANALYSIS")
        print("-" * 40)
        
        velocity = {
            "Factor": [
                "Transaction Frequency",
                "Value Locked",
                "Burn Rate",
                "Staking Percentage",
                "Velocity Rate"
            ],
            "Low Velocity": [
                "Store of Value",
                "High",
                "Low",
                "High",
                "Low"
            ],
            "High Velocity": [
                "Utility/Currency",
                "Low",
                "High",
                "Low",
                "High"
            ]
        }
        
        print("\n📋 Velocity Impact:")
        print(f" {'Factor':>25} | {'Low Velocity (Store of Value)':>30} | {'High Velocity (Utility)':>30}")
        print("-" * 90)
        
        for i in range(len(velocity["Factor"])):
            factor = velocity["Factor"][i]
            low = velocity["Low Velocity"][i]
            high = velocity["High Velocity"][i]
            print(f" {factor:>25} | {low:>30} | {high:>30}")

def demonstrate_tokenomics_engine():
    """Execute comprehensive tokenomics demonstration"""
    print("=" * 60)
    print(" TOKENOMICS FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = TokenomicsEngine()
    
    # Run demonstrations
    engine.explain_tokenomics_overview()
    engine.list_tokenomics_models()
    engine.explain_tokenomics_components()
    engine.explain_tokenomics_analysis()
    
    # Additional analytics
    TokenomicsAnalytics.analyze_supply_models()
    TokenomicsAnalytics.analyze_token_velocity()
    
    print("\n" + "=" * 60)
    print(" TOKENOMICS SUMMARY:")
    print("   ✓ Tokenomics = Token Economics")
    print("   ✓ Components: Supply, Distribution, Utility, Incentives")
    print("   ✓ Supply Types: Fixed, Inflationary, Deflationary")
    print("   ✓ Distribution: ICO, IDO, Airdrops, Mining")
    print("   ✓ Utility: Governance, Payments, Staking, Access")
    print("   ✓ Incentives: Rewards, Yield, Participation")
    print("   ✓ Analysis: Supply, Distribution, Utility, Incentives")
    print("   ✓ Tokenomics determines token success")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_tokenomics_engine()

4.12 Supply Models

Supply Models:

ModelDescriptionExamples
Fixed SupplyCapped totalBTC (21M)
InflationaryUnlimited supplyETH, DOGE
DeflationaryDecreasing supplyBNB (burn)

Code Example – Supply Models:

"""
TOKEN SUPPLY MODEL FRAMEWORK
=============================
Complete token supply model analysis and comparison
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class SupplyModelType(Enum):
    """Classification of token supply models"""
    FIXED = "Fixed (Deflationary)"
    INFLATIONARY = "Inflationary"
    DEFLATIONARY = "Deflationary"
    DYNAMIC = "Dynamic/Algorithmic"
    BONDED = "Bonded (Elastic)"

@dataclass
class SupplyModel:
    """Represents a token supply model with its properties"""
    name: str
    supply_type: SupplyModelType
    description: str
    examples: List[str]
    advantages: List[str]
    disadvantages: List[str]
    key_metrics: Dict[str, str]

@dataclass
class SupplyMetric:
    """Represents a supply metric"""
    metric: str
    value: str
    interpretation: str
    category: str

class SupplyModelEngine:
    """Complete token supply model demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" TOKEN SUPPLY MODEL ENGINE")
        print("=" * 60)
    
    def explain_supply_models(self) -> None:
        """Explain different supply models"""
        print("\n 📊 SUPPLY MODELS OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  TOKEN SUPPLY MODELS                                     │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1. FIXED SUPPLY (Deflationary)                          │
│     • Total supply capped                                 │
│     • No new tokens after cap                            │
│     • Example: Bitcoin (21M)                            │
│     • Effect: Scarcity → Price appreciation             │
│     • Best for: Store of value                           │
│                                                           │
│  2. INFLATIONARY                                         │
│     • Unlimited supply                                    │
│     • Continuous minting                                 │
│     • Example: Ethereum (no cap)                        │
│     • Effect: Inflationary pressure                      │
│     • Best for: Utility/Currency                         │
│                                                           │
│  3. DEFLATIONARY                                         │
│     • Supply decreases over time                         │
│     • Token burning mechanisms                           │
│     • Example: BNB (regular burns)                       │
│     • Effect: Scarcity increases                         │
│     • Best for: Value appreciation                       │
│                                                           │
│  4. DYNAMIC/ALGORITHMIC                                  │
│     • Algorithm adjusts supply                           │
│     • Maintains stability                                │
│     • Example: UST (failed)                             │
│     • Effect: Stability                                  │
│     • Best for: Stablecoins                             │
│                                                           │
│  5. BONDED (Elastic)                                    │
│     • Supply expands/contracts based on demand          │
│     • Example: AMPL                                     │
│     • Effect: Price stability                            │
│     • Best for: Experimental models                     │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_supply_models(self) -> None:
        """List major token supply models"""
        print("\n 📈 MAJOR SUPPLY MODELS")
        print("-" * 40)
        
        models = [
            SupplyModel(
                name="Bitcoin Model",
                supply_type=SupplyModelType.FIXED,
                description="Fixed supply with halving events",
                examples=["Bitcoin (BTC)", "Litecoin (LTC)", "Cardano (ADA)"],
                advantages=["Scarcity", "Store of value", "Predictable"],
                disadvantages=["Limited for payments", "No utility", "Speculative"],
                key_metrics={
                    "Total Supply": "21,000,000",
                    "Circulating Supply": "~19.6M",
                    "Halving Schedule": "Every 4 years",
                    "Inflation Rate": "Decreasing"
                }
            ),
            SupplyModel(
                name="Ethereum Model",
                supply_type=SupplyModelType.INFLATIONARY,
                description="Inflationary with burn mechanism",
                examples=["Ethereum (ETH)", "Solana (SOL)"],
                advantages=["Utility", "Gas fees", "Staking rewards"],
                disadvantages=["Inflationary pressure", "Uncertain supply"],
                key_metrics={
                    "Total Supply": "No cap (inflationary)",
                    "Current Supply": "~120M",
                    "Issuance Rate": "~0.5% per year",
                    "Burn Rate": "Variable"
                }
            ),
            SupplyModel(
                name="Binance Model",
                supply_type=SupplyModelType.DEFLATIONARY,
                description="Deflationary with burn mechanism",
                examples=["BNB", "FLOKI"],
                advantages=["Scarcity", "Price appreciation", "Utility"],
                disadvantages=["Centralized", "Burns can be gamed"],
                key_metrics={
                    "Total Supply": "200,000,000",
                    "Current Supply": "~160M",
                    "Burn Schedule": "Quarterly",
                    "Burn Rate": "Automatic"
                }
            ),
            SupplyModel(
                name="Algorithmic Model",
                supply_type=SupplyModelType.DYNAMIC,
                description="Algorithm adjusts supply",
                examples=["UST (failed)", "FRAX"],
                advantages=["Stability", "Programmable"],
                disadvantages=["Complex", "Can fail (UST)"],
                key_metrics={
                    "Total Supply": "Variable",
                    "Current Supply": "Algorithm-determined",
                    "Adjustment Rate": "Automatic",
                    "Stability Mechanism": "Algorithmic"
                }
            ),
            SupplyModel(
                name="Elastic Model",
                supply_type=SupplyModelType.BONDED,
                description="Supply expands/contracts",
                examples=["AMPL", "Rebasing tokens"],
                advantages=["Price stability", "Innovative"],
                disadvantages=["Complex", "Unpredictable holdings"],
                key_metrics={
                    "Total Supply": "Variable",
                    "Rebasing Frequency": "Daily",
                    "Price Target": "$1.00",
                    "Adjustment Mechanism": "Rebasing"
                }
            )
        ]
        
        print("\n📋 Supply Model Details:")
        print(f" {'Name':>20} | {'Type':>20} | {'Examples':>30} | {'Advantages':>30}")
        print("-" * 105)
        
        for model in models:
            print(f" {model.name[:20]:>20} | {model.supply_type.value[:20]:>20} | "
                  f"{', '.join(model.examples)[:30]:>30} | {', '.join(model.advantages)[:30]:>30}")
        
        print("\n📋 Key Metrics:")
        for model in models[:3]:
            print(f"\n  {model.name}:")
            for metric, value in model.key_metrics.items():
                print(f"    {metric}: {value}")
    
    def explain_supply_impact(self) -> None:
        """Explain how supply models impact token value"""
        print("\n 💰 SUPPLY IMPACT ON VALUE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SUPPLY MODEL IMPACT ON TOKEN VALUE                      │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  FIXED SUPPLY:                                           │
│  • Scarcity drives value                                 │
│  • Supply and demand dynamics                            │
│  • Limited supply = Higher potential                     │
│  • Best for: Long-term holding                           │
│                                                           │
│  INFLATIONARY:                                           │
│  • Value from utility                                    │
│  • Demand determines value                               │
│  • Continuous issuance                                   │
│  • Best for: Active use                                  │
│                                                           │
│  DEFLATIONARY:                                           │
│  • Decreasing supply increases value                     │
│  • Burns create scarcity                                 │
│  • Supply decreases over time                            │
│  • Best for: Value appreciation                          │
│                                                           │
│  DYNAMIC:                                                │
│  • Value from stability                                  │
│  • Algorithm adjusts supply                              │
│  • Maintains target price                                │
│  • Best for: Stability                                   │
│                                                           │
│  KEY FORMULA:                                            │
│  Token Price = Total Value / Circulating Supply         │
│                                                           │
│  Increase value by:                                      │
│  1. Decreasing supply (burning)                         │
│  2. Increasing demand (utility)                         │
│  3. Improving tokenomics                                 │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_supply_metrics(self) -> None:
        """Explain key supply metrics"""
        print("\n 📊 SUPPLY METRICS")
        print("-" * 40)
        
        metrics = [
            SupplyMetric(
                metric="Total Supply",
                value="Maximum tokens that will ever exist",
                interpretation="Determines scarcity potential",
                category="Fundamental"
            ),
            SupplyMetric(
                metric="Circulating Supply",
                value="Tokens currently available in market",
                interpretation="Affects current price and liquidity",
                category="Market"
            ),
            SupplyMetric(
                metric="Market Cap",
                value="Circulating Supply × Price",
                interpretation="Shows total value of token",
                category="Valuation"
            ),
            SupplyMetric(
                metric="Fully Diluted Valuation (FDV)",
                value="Total Supply × Price",
                interpretation="Potential value if all tokens in circulation",
                category="Valuation"
            ),
            SupplyMetric(
                metric="Inflation Rate",
                value="% of new tokens issued annually",
                interpretation="Dilution rate of existing holders",
                category="Economic"
            ),
            SupplyMetric(
                metric="Burn Rate",
                value="% of tokens burned annually",
                interpretation="Deflation rate",
                category="Economic"
            )
        ]
        
        print("\n📋 Supply Metrics:")
        print(f" {'Metric':>25} | {'Description':>45} | {'Category':>15}")
        print("-" * 90)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:45]:>45} | {metric.category:>15}")

class SupplyAnalytics:
    """Additional analysis tools for supply models"""
    
    @staticmethod
    def compare_supply_models() -> None:
        """Compare supply models across key dimensions"""
        print("\n 📈 SUPPLY MODEL COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Scarcity", "Value Appreciation", "Inflation Risk", "Utility", "Complexity"],
            "Fixed": ["High", "High", "Low", "Medium", "Low"],
            "Inflationary": ["Low", "Medium", "High", "High", "Low"],
            "Deflationary": ["Very High", "Very High", "None", "Medium", "Medium"],
            "Dynamic": ["Variable", "Low", "Variable", "Low", "High"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Fixed':>15} | {'Inflationary':>15} | {'Deflationary':>15} | {'Dynamic':>15}")
        print("-" * 85)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            fixed = comparison["Fixed"][i]
            inflationary = comparison["Inflationary"][i]
            deflationary = comparison["Deflationary"][i]
            dynamic = comparison["Dynamic"][i]
            
            print(f" {attr:>20} | {fixed:>15} | {inflationary:>15} | {deflationary:>15} | {dynamic:>15}")
    
    @staticmethod
    def analyze_halving_impact() -> None:
        """Analyze the impact of halving events"""
        print("\n ⏳ HALVING IMPACT ANALYSIS")
        print("-" * 40)
        
        halving_data = {
            "Event": ["Genesis", "2012 Halving", "2016 Halving", "2020 Halving", "2024 Halving"],
            "Year": [2009, 2012, 2016, 2020, 2024],
            "Block": [0, 210000, 420000, 630000, 840000],
            "Reward": ["50 BTC", "25 BTC", "12.5 BTC", "6.25 BTC", "3.125 BTC"],
            "Supply": ["0", "10.5M", "15.75M", "18.375M", "19.6875M"],
            "Impact": ["Launch", "Price surge", "Bull run", "Institutional", "Post-ETF"]
        }
        
        print("\n📋 Halving History:")
        print(f" {'Event':>15} | {'Year':>8} | {'Block':>12} | {'Reward':>12} | {'Supply':>12} | {'Impact':>20}")
        print("-" * 85)
        
        for i in range(len(halving_data["Event"])):
            event = halving_data["Event"][i]
            year = halving_data["Year"][i]
            block = halving_data["Block"][i]
            reward = halving_data["Reward"][i]
            supply = halving_data["Supply"][i]
            impact = halving_data["Impact"][i]
            
            print(f" {event:>15} | {year:>8} | {block:>12} | {reward:>12} | {supply:>12} | {impact:>20}")

def demonstrate_supply_model_engine():
    """Execute comprehensive supply model demonstration"""
    print("=" * 60)
    print(" TOKEN SUPPLY MODEL ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = SupplyModelEngine()
    
    # Run demonstrations
    engine.explain_supply_models()
    engine.list_supply_models()
    engine.explain_supply_impact()
    engine.explain_supply_metrics()
    
    # Additional analytics
    SupplyAnalytics.compare_supply_models()
    SupplyAnalytics.analyze_halving_impact()
    
    print("\n" + "=" * 60)
    print(" SUPPLY MODEL SUMMARY:")
    print("   ✓ Supply Models: Fixed, Inflationary, Deflationary, Dynamic")
    print("   ✓ Fixed: Scarcity, store of value (BTC)")
    print("   ✓ Inflationary: Utility, spending (ETH)")
    print("   ✓ Deflationary: Price appreciation (BNB)")
    print("   ✓ Dynamic: Stability (Algorithmic)")
    print("   ✓ Supply Impacts: Scarcity, inflation, deflation")
    print("   ✓ Metrics: Total supply, circulating, market cap, FDV")
    print("   ✓ Token Price = Total Value / Circulating Supply")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_supply_model_engine()

4.13 Inflation

Inflation in Crypto:

Inflation refers to the increase in supply of a cryptocurrency over time. Some cryptocurrencies are designed to be inflationary, while others are deflationary.

Inflationary Cryptocurrencies:

CoinInflation RatePurpose
Ethereum~0.5% (PoS)Staking rewards
Dogecoin~3.5%Transaction fees
Polka~10%Ecosystem growth

Code Example – Inflation:

"""
CRYPTOCURRENCY INFLATION FRAMEWORK
==================================
Complete inflation analysis for cryptocurrency tokenomics
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class InflationType(Enum):
    """Classification of inflation mechanisms"""
    CONTROLLED = "Controlled Inflation"
    UNCONTROLLED = "Uncontrolled Inflation"
    DEFLATIONARY = "Deflationary"
    DISINFLATIONARY = "Disinflationary"
    HYPERINFLATIONARY = "Hyperinflationary"

@dataclass
class InflationModel:
    """Represents a cryptocurrency inflation model"""
    name: str
    inflation_type: InflationType
    annual_rate: str
    mechanism: str
    examples: List[str]
    impact: str
    benefits: List[str]
    risks: List[str]

@dataclass
class InflationMetric:
    """Represents an inflation metric"""
    metric: str
    value: str
    description: str
    significance: str

class InflationEngine:
    """Complete cryptocurrency inflation demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOCURRENCY INFLATION ENGINE")
        print("=" * 60)
    
    def explain_inflation_overview(self) -> None:
        """Provide comprehensive inflation overview"""
        print("\n 📊 INFLATION IN CRYPTOCURRENCY")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTOCURRENCY INFLATION                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Inflation = Increase in token supply        │
│  Purpose: Economic incentive mechanism                    │
│                                                           │
│  INFLATION TYPES:                                        │
│                                                           │
│  1. CONTROLLED INFLATION                                 │
│     • Predictable issuance rate                          │
│     • Aligned with network growth                        │
│     • Example: Ethereum (PoS) ~0.5%                     │
│     • Effect: Stable, predictable                         │
│                                                           │
│  2. UNCONTROLLED INFLATION                               │
│     • Unpredictable issuance                             │
│     • Can be catastrophic                                │
│     • Example: UST (Terra) - Failed                      │
│     • Effect: Loss of confidence, collapse              │
│                                                           │
│  3. DEFLATIONARY                                         │
│     • Supply decreases over time                        │
│     • Burning mechanisms                                 │
│     • Example: BNB, ETH (EIP-1559)                      │
│     • Effect: Scarcity, value appreciation              │
│                                                           │
│  4. DISINFLATIONARY                                      │
│     • Inflation rate decreases over time                │
│     • Halving events                                     │
│     • Example: Bitcoin (halving)                         │
│     • Effect: Decreasing inflation                       │
│                                                           │
│  5. HYPERINFLATIONARY                                    │
│     • Extremely high inflation rate                     │
│     • Rapid devaluation                                  │
│     • Example: Failed projects                          │
│     • Effect: Token death                               │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_inflation_models(self) -> None:
        """List major inflation models"""
        print("\n 📈 MAJOR INFLATION MODELS")
        print("-" * 40)
        
        models = [
            InflationModel(
                name="Ethereum PoS",
                inflation_type=InflationType.CONTROLLED,
                annual_rate="~0.5%",
                mechanism="Staking rewards + Burn (EIP-1559)",
                examples=["ETH"],
                impact="Moderate inflation with deflationary pressure",
                benefits=["Staking rewards", "Network security", "Controlled growth"],
                risks=["Variable rates", "Dependent on usage"]
            ),
            InflationModel(
                name="Dogecoin",
                inflation_type=InflationType.CONTROLLED,
                annual_rate="~3.5%",
                mechanism="Fixed annual issuance (10,000 DOGE/block)",
                examples=["DOGE"],
                impact="Steady inflation for spending",
                benefits=["Encourages spending", "Stable supply growth", "Predictable"],
                risks=["Inflationary pressure", "No supply cap"]
            ),
            InflationModel(
                name="Polkadot",
                inflation_type=InflationType.CONTROLLED,
                annual_rate="~10%",
                mechanism="Staking rewards + Treasury",
                examples=["DOT"],
                impact="High inflation for staking rewards",
                benefits=["High staking rewards", "Network growth", "Treasury funding"],
                risks=["Dilution risk", "High inflation rate"]
            ),
            InflationModel(
                name="Bitcoin",
                inflation_type=InflationType.DISINFLATIONARY,
                annual_rate="Decreasing (Halving)",
                mechanism="Halving every ~4 years",
                examples=["BTC"],
                impact="Decreasing inflation to 0",
                benefits=["Scarcity", "Store of value", "Predictable"],
                risks=["No staking rewards", "Security depend on fees"]
            ),
            InflationModel(
                name="BNB",
                inflation_type=InflationType.DEFLATIONARY,
                annual_rate="Deflationary (Burning)",
                mechanism="Quarterly burns, auto-burn",
                examples=["BNB"],
                impact="Decreasing supply over time",
                benefits=["Scarcity", "Value appreciation", "Utility"],
                risks=["Centralized burns", "Dependent on usage"]
            )
        ]
        
        print("\n📋 Inflation Model Details:")
        print(f" {'Name':>20} | {'Type':>20} | {'Rate':>12} | {'Mechanism':>30} | {'Examples':>15}")
        print("-" * 100)
        
        for model in models:
            print(f" {model.name[:20]:>20} | {model.inflation_type.value[:20]:>20} | "
                  f"{model.annual_rate:>12} | {model.mechanism[:30]:>30} | "
                  f"{', '.join(model.examples)[:15]:>15}")
        
        print("\n📋 Impact & Risks:")
        for model in models[:3]:
            print(f"\n  {model.name}:")
            print(f"    Impact: {model.impact}")
            print(f"    Benefits: {', '.join(model.benefits)}")
            print(f"    Risks: {', '.join(model.risks)}")
    
    def explain_inflation_impact(self) -> None:
        """Explain inflation's impact on token value"""
        print("\n 💰 INFLATION IMPACT ON TOKEN VALUE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  INFLATION IMPACT                                         │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  POSITIVE IMPACTS:                                       │
│  • Rewards stakers and validators                         │
│  • Funds network development                              │
│  • Encourages spending and usage                          │
│  • Attracts new participants                              │
│  • Supports network growth                                │
│                                                           │
│  NEGATIVE IMPACTS:                                       │
│  • Dilutes existing holdings                              │
│  • Creates sell pressure                                  │
│  • Reduces store of value potential                      │
│  • Can lead to hyperinflation                            │
│  • Loss of confidence                                    │
│                                                           │
│  KEY RELATIONSHIP:                                       │
│  Token Price = Total Value / Circulating Supply          │
│                                                           │
│  If supply increases faster than value:                  │
│  → Price decreases                                       │
│                                                           │
│  If value increases faster than supply:                  │
│  → Price increases                                       │
│                                                           │
│  INFLATION OPTIMIZATION:                                 │
│  1. Match inflation to network growth                     │
│  2. Implement burning mechanisms                         │
│  3. Create demand through utility                        │
│  4. Align incentives                                     │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_inflation_metrics(self) -> None:
        """Explain key inflation metrics"""
        print("\n 📊 INFLATION METRICS")
        print("-" * 40)
        
        metrics = [
            InflationMetric(
                metric="Annual Inflation Rate",
                value="% of supply issued per year",
                description="Year-over-year supply increase",
                significance="Shows dilution rate"
            ),
            InflationMetric(
                metric="Staking APR",
                value="% reward for staking",
                description="Annual return for staking",
                significance="Shows incentive alignment"
            ),
            InflationMetric(
                metric="Net Inflation",
                value="Inflation - Burns",
                description="Actual supply increase",
                significance="Shows true inflation impact"
            ),
            InflationMetric(
                metric="Velocity",
                value="Transactions per day",
                description="How often tokens change hands",
                significance="Shows utility and demand"
            ),
            InflationMetric(
                metric="Real Yield",
                value="Staking APR - Inflation",
                description="Actual return after inflation",
                significance="Shows true value growth"
            )
        ]
        
        print("\n📋 Inflation Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")

class InflationAnalytics:
    """Additional analysis tools for inflation"""
    
    @staticmethod
    def compare_inflation_rates() -> None:
        """Compare inflation rates across cryptocurrencies"""
        print("\n 📈 INFLATION RATE COMPARISON")
        print("-" * 40)
        
        rates = {
            "Asset": ["BTC", "ETH", "DOGE", "DOT", "SOL", "ADA", "BNB"],
            "Inflation Rate": ["~1.8%", "~0.5%", "~3.5%", "~10%", "~5%", "~2.5%", "Deflationary"],
            "Type": ["Disinflationary", "Controlled", "Controlled", "Controlled", "Controlled", "Controlled", "Deflationary"],
            "Token": ["Store of Value", "Utility", "Spending", "Governance", "Utility", "Governance", "Utility"],
            "Risk Level": ["Low", "Low", "Medium", "High", "Medium", "Low", "Low"]
        }
        
        print("\n📋 Rate Comparison:")
        print(f" {'Asset':>10} | {'Rate':>15} | {'Type':>20} | {'Token':>15} | {'Risk Level':>15}")
        print("-" * 80)
        
        for i in range(len(rates["Asset"])):
            asset = rates["Asset"][i]
            rate = rates["Inflation Rate"][i]
            typ = rates["Type"][i]
            token = rates["Token"][i]
            risk = rates["Risk Level"][i]
            
            print(f" {asset:>10} | {rate:>15} | {typ:>20} | {token:>15} | {risk:>15}")
    
    @staticmethod
    def analyze_deflationary_mechanisms() -> None:
        """Analyze deflationary mechanisms"""
        print("\n 🔥 DEFLATIONARY MECHANISM ANALYSIS")
        print("-" * 40)
        
        mechanisms = {
            "Token Burning": {
                "description": "Permanent removal of tokens from circulation",
                "examples": ["BNB burns", "ETH EIP-1559", "SHIB burns"],
                "impact": "Reduces supply, increases scarcity",
                "effectiveness": "High (if regular)"
            },
            "Buy-and-Burn": {
                "description": "Buy tokens from market and burn",
                "examples": ["Binance quarterly burns", "XRP burns"],
                "impact": "Creates buy pressure, reduces supply",
                "effectiveness": "Medium-High"
            },
            "Transaction Fee Burning": {
                "description": "Burn a portion of transaction fees",
                "examples": ["ETH EIP-1559", "Base fee burning"],
                "impact": "Continuous deflationary pressure",
                "effectiveness": "High (if network active)"
            },
            "Staking Requirements": {
                "description": "Lock tokens for staking",
                "examples": ["Proof of Stake", "Locking mechanisms"],
                "impact": "Reduces circulating supply",
                "effectiveness": "Medium (temporary)"
            }
        }
        
        print("\n📋 Deflationary Mechanisms:")
        for mechanism, details in mechanisms.items():
            print(f"\n  {mechanism}:")
            print(f"    Description: {details['description']}")
            print(f"    Examples: {', '.join(details['examples'])}")
            print(f"    Impact: {details['impact']}")
            print(f"    Effectiveness: {details['effectiveness']}")

def demonstrate_inflation_engine():
    """Execute comprehensive inflation demonstration"""
    print("=" * 60)
    print(" CRYPTOCURRENCY INFLATION ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = InflationEngine()
    
    # Run demonstrations
    engine.explain_inflation_overview()
    engine.list_inflation_models()
    engine.explain_inflation_impact()
    engine.explain_inflation_metrics()
    
    # Additional analytics
    InflationAnalytics.compare_inflation_rates()
    InflationAnalytics.analyze_deflationary_mechanisms()
    
    print("\n" + "=" * 60)
    print(" INFLATION SUMMARY:")
    print("   ✓ Inflation = Increase in token supply")
    print("   ✓ Types: Controlled, Uncontrolled, Deflationary")
    print("   ✓ Impact: Dilution vs. Incentives")
    print("   ✓ Metrics: Rate, Staking APR, Net inflation")
    print("   ✓ Deflationary: Burning mechanisms")
    print("   ✓ Token Price = Total Value / Circulating Supply")
    print("   ✓ Balance inflation with growth and utility")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_inflation_engine()

4.14 Deflation

Deflation in Crypto:

Deflation occurs when the supply of a cryptocurrency decreases over time. This can happen through token burning, limited supply, or decreased emissions.

Deflationary Mechanisms:

MechanismDescriptionExamples
BurningTokens destroyedBNB, ETH (EIP-1559)
Limited SupplyCapped totalBTC (21M)
Decreased EmissionsReduced rewardsHalving events

Code Example – Deflation:

"""
CRYPTOCURRENCY DEFLATION FRAMEWORK
==================================
Complete deflation analysis for cryptocurrency tokenomics
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class DeflationType(Enum):
    """Classification of deflation mechanisms"""
    TOKEN_BURNING = "Token Burning"
    FIXED_SUPPLY = "Fixed Supply"
    REDUCED_EMISSIONS = "Reduced Emissions"
    TRANSACTION_BURN = "Transaction Fee Burning"
    DYNAMIC_BURN = "Dynamic Burn"

@dataclass
class DeflationModel:
    """Represents a cryptocurrency deflation model"""
    name: str
    deflation_type: DeflationType
    annual_rate: str
    mechanism: str
    examples: List[str]
    impact: str
    benefits: List[str]
    risks: List[str]

@dataclass
class DeflationMetric:
    """Represents a deflation metric"""
    metric: str
    value: str
    description: str
    significance: str

class DeflationEngine:
    """Complete cryptocurrency deflation demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOCURRENCY DEFLATION ENGINE")
        print("=" * 60)
    
    def explain_deflation_overview(self) -> None:
        """Provide comprehensive deflation overview"""
        print("\n 📊 DEFLATION IN CRYPTOCURRENCY")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTOCURRENCY DEFLATION                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Deflation = Decrease in token supply        │
│  Purpose: Create scarcity and value appreciation          │
│                                                           │
│  DEFLATION MECHANISMS:                                   │
│                                                           │
│  1. TOKEN BURNING                                        │
│     • Permanent removal of tokens                        │
│     • Often programmed                                   │
│     • Example: BNB quarterly burns                      │
│     • Effect: Immediate scarcity                         │
│                                                           │
│  2. FIXED SUPPLY                                         │
│     • Total supply capped                                │
│     • No new tokens                                      │
│     • Example: Bitcoin (21M)                            │
│     • Effect: Natural scarcity                           │
│                                                           │
│  3. REDUCED EMISSIONS                                    │
│     • Decreasing issuance rate                          │
│     • Halving events                                     │
│     • Example: Bitcoin halving                          │
│     • Effect: Gradual scarcity                           │
│                                                           │
│  4. TRANSACTION BURN                                     │
│     • Burn portion of fees                              │
│     • EIP-1559 mechanism                                │
│     • Example: Ethereum base fee burn                  │
│     • Effect: Usage-based scarcity                      │
│                                                           │
│  5. DYNAMIC BURN                                         │
│     • Algorithm adjusts burn rate                      │
│     • Variable burning                                   │
│     • Example: FRAX burns                               │
│     • Effect: Algorithmic scarcity                      │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_deflation_models(self) -> None:
        """List major deflation models"""
        print("\n 📈 MAJOR DEFLATION MODELS")
        print("-" * 40)
        
        models = [
            DeflationModel(
                name="Bitcoin Model",
                deflation_type=DeflationType.FIXED_SUPPLY,
                annual_rate="0% (after 2140)",
                mechanism="Fixed supply of 21M, halving",
                examples=["BTC"],
                impact="Store of value, digital gold",
                benefits=["Scarcity", "Value appreciation", "Predictable"],
                risks=["No new rewards for miners", "Security concerns"]
            ),
            DeflationModel(
                name="Ethereum EIP-1559",
                deflation_type=DeflationType.TRANSACTION_BURN,
                annual_rate="Variable (Deflationary in high usage)",
                mechanism="Burn base fee from transactions",
                examples=["ETH"],
                impact="Potential deflation during high usage",
                benefits=["Scarcity", "Utility value", "Network usage"],
                risks=["Dependent on network activity", "Variable burns"]
            ),
            DeflationModel(
                name="Binance Model",
                deflation_type=DeflationType.TOKEN_BURNING,
                annual_rate="~20% (Quarterly burns)",
                mechanism="Burn BNB tokens quarterly",
                examples=["BNB"],
                impact="Decreasing supply, increasing scarcity",
                benefits=["Value appreciation", "Utility", "Predictable burns"],
                risks=["Centralized", "Variable burn amounts"]
            ),
            DeflationModel(
                name="Shiba Inu Model",
                deflation_type=DeflationType.DYNAMIC_BURN,
                annual_rate="Variable",
                mechanism="Community-driven burns",
                examples=["SHIB"],
                impact="Supply reduction",
                benefits=["Community engagement", "Scarcity"],
                risks=["Unpredictable", "Burns not guaranteed"]
            )
        ]
        
        print("\n📋 Deflation Model Details:")
        print(f" {'Name':>20} | {'Type':>20} | {'Rate':>15} | {'Mechanism':>35} | {'Examples':>15}")
        print("-" * 110)
        
        for model in models:
            print(f" {model.name[:20]:>20} | {model.deflation_type.value[:20]:>20} | "
                  f"{model.annual_rate[:15]:>15} | {model.mechanism[:35]:>35} | "
                  f"{', '.join(model.examples)[:15]:>15}")
        
        print("\n📋 Impact & Risks:")
        for model in models[:3]:
            print(f"\n  {model.name}:")
            print(f"    Impact: {model.impact}")
            print(f"    Benefits: {', '.join(model.benefits)}")
            print(f"    Risks: {', '.join(model.risks)}")
    
    def explain_deflation_impact(self) -> None:
        """Explain deflation's impact on token value"""
        print("\n 💰 DEFLATION IMPACT ON TOKEN VALUE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  DEFLATION IMPACT                                        │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  POSITIVE IMPACTS:                                       │
│  • Increases scarcity                                     │
│  • Creates value appreciation potential                   │
│  • Encourages holding                                     │
│  • Reduces sell pressure                                  │
│  • Supports store of value narrative                     │
│                                                           │
│  NEGATIVE IMPACTS:                                       │
│  • Can lead to hoarding                                  │
│  • Reduces spending and usage                            │
│  • May create bubbles                                    │
│  • Can become too volatile                               │
│  • May limit utility                                     │
│                                                           │
│  KEY RELATIONSHIP:                                       │
│  Token Value ∝ 1 / Supply                               │
│                                                           │
│  As supply decreases:                                     │
│  → Scarcity increases                                     │
│  → Potential value increases                              │
│                                                           │
│  DEFLATION OPTIMIZATION:                                 │
│  1. Balance deflation with utility                       │
│  2. Create sustainable burns                             │
│  3. Maintain network security                            │
│  4. Encourage healthy usage                              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_deflation_metrics(self) -> None:
        """Explain key deflation metrics"""
        print("\n 📊 DEFLATION METRICS")
        print("-" * 40)
        
        metrics = [
            DeflationMetric(
                metric="Burn Rate",
                value="Tokens burned per year",
                description="Annual deflation rate",
                significance="Shows scarcity creation"
            ),
            DeflationMetric(
                metric="Total Burned",
                value="Cumulative tokens burned",
                description="Total deflation to date",
                significance="Shows historical scarcity"
            ),
            DeflationMetric(
                metric="Net Supply Change",
                value="New supply - Burns",
                description="Actual supply change",
                significance="Shows true supply dynamics"
            ),
            DeflationMetric(
                metric="Deflationary Pressure",
                value="Burn rate / Total supply",
                description="Relative deflation",
                significance="Shows deflation intensity"
            ),
            DeflationMetric(
                metric="Circulating Supply",
                value="Supply available",
                description="Market-available supply",
                significance="Shows current scarcity"
            )
        ]
        
        print("\n📋 Deflation Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")

class DeflationAnalytics:
    """Additional analysis tools for deflation"""
    
    @staticmethod
    def compare_deflation_mechanisms() -> None:
        """Compare deflation mechanisms"""
        print("\n 📈 DEFLATION MECHANISM COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Effectiveness", "Predictability", "Complexity", "Centralization", "Sustainability"],
            "Token Burning": ["High", "High", "Low", "Variable", "High"],
            "Fixed Supply": ["High", "Very High", "Low", "Low", "High"],
            "Reduced Emissions": ["Medium", "High", "Low", "Low", "Medium"],
            "Transaction Burn": ["Variable", "Medium", "Medium", "Low", "Medium"],
            "Dynamic Burn": ["Variable", "Low", "High", "Medium", "Variable"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Burning':>15} | {'Fixed':>15} | {'Reduced':>15} | {'Tx Burn':>15} | {'Dynamic':>15}")
        print("-" * 100)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            burning = comparison["Token Burning"][i]
            fixed = comparison["Fixed Supply"][i]
            reduced = comparison["Reduced Emissions"][i]
            tx_burn = comparison["Transaction Burn"][i]
            dynamic = comparison["Dynamic Burn"][i]
            
            print(f" {attr:>20} | {burning:>15} | {fixed:>15} | {reduced:>15} | {tx_burn:>15} | {dynamic:>15}")
    
    @staticmethod
    def analyze_burn_impact() -> None:
        """Analyze burn impact on supply"""
        print("\n 🔥 BURN IMPACT ANALYSIS")
        print("-" * 40)
        
        burn_scenarios = {
            "Scenario": ["Small Burns", "Medium Burns", "Large Burns", "Massive Burns"],
            "Burn Rate": ["1%", "5%", "20%", "50%"],
            "Supply Impact": ["Minor", "Noticeable", "Significant", "Major"],
            "Price Impact": ["Small", "Moderate", "Large", "Massive"],
            "Risk Level": ["Low", "Low", "Medium", "High"]
        }
        
        print("\n📋 Burn Scenarios:")
        print(f" {'Scenario':>15} | {'Burn Rate':>12} | {'Supply Impact':>20} | {'Price Impact':>20} | {'Risk':>15}")
        print("-" * 85)
        
        for i in range(len(burn_scenarios["Scenario"])):
            scenario = burn_scenarios["Scenario"][i]
            rate = burn_scenarios["Burn Rate"][i]
            supply = burn_scenarios["Supply Impact"][i]
            price = burn_scenarios["Price Impact"][i]
            risk = burn_scenarios["Risk Level"][i]
            
            print(f" {scenario:>15} | {rate:>12} | {supply:>20} | {price:>20} | {risk:>15}")

def demonstrate_deflation_engine():
    """Execute comprehensive deflation demonstration"""
    print("=" * 60)
    print(" CRYPTOCURRENCY DEFLATION ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = DeflationEngine()
    
    # Run demonstrations
    engine.explain_deflation_overview()
    engine.list_deflation_models()
    engine.explain_deflation_impact()
    engine.explain_deflation_metrics()
    
    # Additional analytics
    DeflationAnalytics.compare_deflation_mechanisms()
    DeflationAnalytics.analyze_burn_impact()
    
    print("\n" + "=" * 60)
    print(" DEFLATION SUMMARY:")
    print("   ✓ Deflation = Decrease in token supply")
    print("   ✓ Mechanisms: Burning, Fixed supply, Reduced emissions")
    print("   ✓ Impact: Scarcity, value appreciation")
    print("   ✓ Metrics: Burn rate, Total burned, Net supply change")
    print("   ✓ Benefits: Value appreciation, store of value")
    print("   ✓ Risks: Hoarding, bubbles, limited utility")
    print("   ✓ Balance deflation with utility for success")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_deflation_engine()

4.15 Halving

What is Halving?

Halving is an event where the block reward for mining a cryptocurrency is cut in half. This reduces the rate at which new coins are created, leading to increased scarcity.

Halving Schedule:

EventYearBlock Reward
Genesis200950 BTC
Halving 1201225 BTC
Halving 2201612.5 BTC
Halving 320206.25 BTC
Halving 420243.125 BTC

Code Example – Halving:

"""
BITCOIN HALVING FRAMEWORK
==========================
Complete Bitcoin halving analysis including schedule, impact, and market effects
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class HalvingEvent:
    """Represents a Bitcoin halving event"""
    event_name: str
    year: int
    block_height: int
    block_reward: float
    supply_mined: float
    price_at_halving: str
    price_after_1y: str
    miner_revenue: str

@dataclass
class HalvingMetric:
    """Represents a halving-related metric"""
    metric: str
    value: str
    description: str
    significance: str

class HalvingEngine:
    """Complete Bitcoin halving demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" BITCOIN HALVING ENGINE")
        print("=" * 60)
    
    def explain_halving_overview(self) -> None:
        """Provide comprehensive halving overview"""
        print("\n ⏳ BITCOIN HALVING OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BITCOIN HALVING                                         │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Halving = Block reward cut in half         │
│  Purpose: Control Bitcoin supply, create scarcity        │
│                                                           │
│  SCHEDULE:                                               │
│  • Occurs every 210,000 blocks                           │
│  • Approximately every 4 years                           │
│  • Continues until ~2140 (21M BTC)                      │
│                                                           │
│  EFFECTS:                                                │
│                                                           │
│  1. SUPPLY IMPACT                                       │
│     • Reduced new supply                                 │
│     • Increased scarcity                                 │
│     • Deflationary pressure                              │
│                                                           │
│  2. PRICE IMPACT                                        │
│     • Historically bullish                              │
│     • Supply shock                                      │
│     • Increased demand                                   │
│                                                           │
│  3. MINER IMPACT                                        │
│     • Reduced revenue                                    │
│     • Miner consolidation                                │
│     • Fee importance increases                           │
│                                                           │
│  4. MARKET SENTIMENT                                    │
│     • Increased attention                                │
│     • Media coverage                                     │
│     • Retail/institutional interest                      │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_halving_events(self) -> None:
        """List Bitcoin halving events"""
        print("\n 📊 BITCOIN HALVING EVENTS")
        print("-" * 40)
        
        events = [
            HalvingEvent(
                event_name="Genesis",
                year=2009,
                block_height=0,
                block_reward=50.0,
                supply_mined=0,
                price_at_halving="$0.00",
                price_after_1y="$0.00",
                miner_revenue="Mining start"
            ),
            HalvingEvent(
                event_name="First Halving",
                year=2012,
                block_height=210000,
                block_reward=25.0,
                supply_mined=10500000,
                price_at_halving="$12.00",
                price_after_1y="$150.00",
                miner_revenue="12.5M BTC/year"
            ),
            HalvingEvent(
                event_name="Second Halving",
                year=2016,
                block_height=420000,
                block_reward=12.5,
                supply_mined=15750000,
                price_at_halving="$650.00",
                price_after_1y="$2,500.00",
                miner_revenue="6.25M BTC/year"
            ),
            HalvingEvent(
                event_name="Third Halving",
                year=2020,
                block_height=630000,
                block_reward=6.25,
                supply_mined=18375000,
                price_at_halving="$8,500.00",
                price_after_1y="$50,000.00",
                miner_revenue="3.125M BTC/year"
            ),
            HalvingEvent(
                event_name="Fourth Halving",
                year=2024,
                block_height=840000,
                block_reward=3.125,
                supply_mined=19687500,
                price_at_halving="$62,000.00",
                price_after_1y="TBD",
                miner_revenue="1.5625M BTC/year"
            ),
            HalvingEvent(
                event_name="Fifth Halving",
                year=2028,
                block_height=1050000,
                block_reward=1.5625,
                supply_mined=20343750,
                price_at_halving="TBD",
                price_after_1y="TBD",
                miner_revenue="0.78125M BTC/year"
            )
        ]
        
        print("\n📋 Halving Events:")
        print(f" {'Event':>15} | {'Year':>8} | {'Block':>12} | {'Reward':>12} | {'Supply':>15} | {'Price':>12}")
        print("-" * 80)
        
        for event in events:
            print(f" {event.event_name:>15} | {event.year:>8} | {event.block_height:>12,} | "
                  f"{event.block_reward:>12.2f} | {event.supply_mined:>15,} | {event.price_at_halving:>12}")
        
        print("\n📋 Miner Revenue Impact:")
        for event in events[1:5]:  # Show historical events
            print(f"  • {event.event_name} ({event.year}): {event.miner_revenue}")
    
    def explain_halving_impact(self) -> None:
        """Explain halving impact on Bitcoin ecosystem"""
        print("\n 💰 HALVING IMPACT ANALYSIS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  HALVING IMPACT ANALYSIS                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  SUPPLY IMPACT:                                          │
│  • New supply rate decreases                             │
│  • Scarcity increases                                    │
│  • Deflationary pressure                                 │
│  • Stock-to-flow ratio increases                         │
│                                                           │
│  PRICE IMPACT:                                           │
│  • Supply shock creates demand                          │
│  • Historical 12-18 month bull runs                     │
│  • Increased volatility                                  │
│  • Long-term appreciation                                │
│                                                           │
│  MINING IMPACT:                                         │
│  • Revenue halves for miners                            │
│  • Less efficient miners exit                           │
│  • Hash rate temporarily drops                          │
│  • Difficulty adjusts                                   │
│  • Fee revenue becomes more important                   │
│                                                           │
│  MARKET IMPACT:                                         │
│  • Media attention increases                            │
│  • Retail investor interest                              │
│  • Institutional adoption                               │
│  • Regulatory attention                                 │
│                                                           │
│  KEY FORMULA:                                            │
│  Halving Effect = (Demand) / (Supply Reduction)         │
│                                                           │
│  If demand stays constant and supply halves:            │
│  → Price should theoretically double                    │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_halving_metrics(self) -> None:
        """Explain halving metrics"""
        print("\n 📊 HALVING METRICS")
        print("-" * 40)
        
        metrics = [
            HalvingMetric(
                metric="Block Reward",
                value="BTC per block",
                description="New BTC created per block",
                significance="Determines new supply"
            ),
            HalvingMetric(
                metric="Annual Supply",
                value="BTC per year",
                description="New BTC issued annually",
                significance="Shows inflation rate"
            ),
            HalvingMetric(
                metric="Stock-to-Flow",
                value="Stock / Flow",
                description="Total supply / Annual supply",
                significance="Shows scarcity level"
            ),
            HalvingMetric(
                metric="Miner Revenue",
                value="BTC/Year",
                description="Total miner earnings",
                significance="Shows mining economics"
            ),
            HalvingMetric(
                metric="Hash Rate",
                value="EH/s",
                description="Total mining power",
                significance="Shows network security"
            )
        ]
        
        print("\n📋 Halving Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")

class HalvingAnalytics:
    """Additional analysis tools for halving"""
    
    @staticmethod
    def analyze_halving_cycles() -> None:
        """Analyze halving cycles and price patterns"""
        print("\n 📈 HALVING CYCLE ANALYSIS")
        print("-" * 40)
        
        cycles = {
            "Cycle": ["2012-2016", "2016-2020", "2020-2024", "2024-2028"],
            "Halving": ["First", "Second", "Third", "Fourth"],
            "Price Low": ["$2", "$200", "$3,000", "$16,000"],
            "Price High": ["$1,000", "$20,000", "$69,000", "TBD"],
            "ROI": ["50,000%", "10,000%", "2,300%", "TBD"],
            "Days to Peak": ["~700", "~1,000", "~1,200", "TBD"]
        }
        
        print("\n📋 Cycle Analysis:")
        print(f" {'Cycle':>15} | {'Halving':>10} | {'Price Low':>12} | {'Price High':>12} | {'ROI':>12} | {'Peak (Days)':>15}")
        print("-" * 85)
        
        for i in range(len(cycles["Cycle"])):
            cycle = cycles["Cycle"][i]
            halving = cycles["Halving"][i]
            low = cycles["Price Low"][i]
            high = cycles["Price High"][i]
            roi = cycles["ROI"][i]
            days = cycles["Days to Peak"][i]
            
            print(f" {cycle:>15} | {halving:>10} | {low:>12} | {high:>12} | {roi:>12} | {days:>15}")
    
    @staticmethod
    def analyze_miner_economics() -> None:
        """Analyze miner economics post-halving"""
        print("\n ⛏️  MINER ECONOMICS ANALYSIS")
        print("-" * 40)
        
        economics = {
            "Post-Halving": ["Immediate", "6 Months", "1 Year", "2 Years"],
            "Hash Rate Drop": ["5-10%", "Recovering", "New ATH", "Stable"],
            "Miner Revenue": ["Halved", "Recovering", "Growing", "High"],
            "Difficulty Adjustment": ["Down", "Up", "Up", "Up"],
            "Miner Profitability": ["Low", "Medium", "High", "Very High"]
        }
        
        print("\n📋 Mining Economics:")
        print(f" {'Time Period':>15} | {'Hash Rate':>15} | {'Revenue':>15} | {'Difficulty':>15} | {'Profitability':>15}")
        print("-" * 80)
        
        for i in range(len(economics["Post-Halving"])):
            time_period = economics["Post-Halving"][i]
            hash_rate = economics["Hash Rate Drop"][i]
            revenue = economics["Miner Revenue"][i]
            difficulty = economics["Difficulty Adjustment"][i]
            profitability = economics["Miner Profitability"][i]
            
            print(f" {time_period:>15} | {hash_rate:>15} | {revenue:>15} | {difficulty:>15} | {profitability:>15}")

def demonstrate_halving_engine():
    """Execute comprehensive halving demonstration"""
    print("=" * 60)
    print(" BITCOIN HALVING ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = HalvingEngine()
    
    # Run demonstrations
    engine.explain_halving_overview()
    engine.list_halving_events()
    engine.explain_halving_impact()
    engine.explain_halving_metrics()
    
    # Additional analytics
    HalvingAnalytics.analyze_halving_cycles()
    HalvingAnalytics.analyze_miner_economics()
    
    print("\n" + "=" * 60)
    print(" HALVING SUMMARY:")
    print("   ✓ Halving = Block reward cut in half")
    print("   ✓ Occurs every 210,000 blocks (~4 years)")
    print("   ✓ Schedule: 2009 (50), 2012 (25), 2016 (12.5), 2020 (6.25), 2024 (3.125)")
    print("   ✓ Impact: Supply scarcity, price appreciation")
    print("   ✓ Mining: Revenue halves, consolidation")
    print("   ✓ Market: Increased attention and adoption")
    print("   ✓ Future: Last Bitcoin mined ~2140")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_halving_engine()

4.16 Liquidity

What is Liquidity?

Liquidity measures how easily an asset can be bought or sold in the market without causing a significant change in its price. High liquidity means many buyers and sellers, low spreads, and efficient price discovery.

Liquidity Metrics:

MetricDescription
Trading VolumeAmount traded daily
Order Book DepthBuy/sell orders
SpreadBid-ask difference
SlippagePrice impact of trades

Code Example – Liquidity:

"""
CRYPTOCURRENCY LIQUIDITY FRAMEWORK
==================================
Complete liquidity analysis including sources, metrics, and market impact
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class LiquidityType(Enum):
    """Classification of liquidity types"""
    HIGH = "High Liquidity"
    MEDIUM = "Medium Liquidity"
    LOW = "Low Liquidity"
    DEEP = "Deep Liquidity"
    SHALLOW = "Shallow Liquidity"

@dataclass
class LiquiditySource:
    """Represents a liquidity source"""
    name: str
    type: str
    volume_24h: str
    liquidity_depth: str
    spread: str
    examples: List[str]

@dataclass
class LiquidityMetric:
    """Represents a liquidity metric"""
    metric: str
    value: str
    description: str
    significance: str

@dataclass
class TradingPairLiquidity:
    """Represents liquidity for a trading pair"""
    pair: str
    volume: str
    depth: str
    spread: str
    slippage: str
    exchange: str

class LiquidityEngine:
    """Complete liquidity demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTOCURRENCY LIQUIDITY ENGINE")
        print("=" * 60)
    
    def explain_liquidity_overview(self) -> None:
        """Provide comprehensive liquidity overview"""
        print("\n 💧 LIQUIDITY OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTOCURRENCY LIQUIDITY                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Liquidity = Ease of buying/selling           │
│  Importance: Determines market efficiency                 │
│                                                           │
│  HIGH LIQUIDITY:                                         │
│  • Many buyers and sellers                               │
│  • Tight spreads (0.01-0.1%)                             │
│  • Minimal slippage                                      │
│  • Quick execution                                       │
│  • Efficient price discovery                             │
│                                                           │
│  LOW LIQUIDITY:                                          │
│  • Few market participants                               │
│  • Wide spreads (1-10%)                                 │
│  • High slippage                                         │
│  • Slow execution                                        │
│  • Inefficient pricing                                  │
│                                                           │
│  LIQUIDITY SOURCES:                                      │
│  • Centralized Exchanges (CEX)                          │
│    - Binance, Coinbase, Kraken                          │
│  • Decentralized Exchanges (DEX)                        │
│    - Uniswap, SushiSwap, Curve                          │
│  • Market Makers                                        │
│    - Professional traders providing liquidity           │
│  • Liquidity Providers                                  │
│    - Users supplying liquidity to DEX pools            │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_liquidity_sources(self) -> None:
        """List major liquidity sources"""
        print("\n 📊 LIQUIDITY SOURCES")
        print("-" * 40)
        
        sources = [
            LiquiditySource(
                name="Binance",
                type="CEX",
                volume_24h="$50B+",
                liquidity_depth="Very Deep",
                spread="0.01-0.05%",
                examples=["BTC/USDT", "ETH/USDT", "BNB/USDT"]
            ),
            LiquiditySource(
                name="Uniswap",
                type="DEX",
                volume_24h="$5B+",
                liquidity_depth="Deep",
                spread="0.05-0.5%",
                examples=["ETH/USDC", "USDC/USDT", "WBTC/ETH"]
            ),
            LiquiditySource(
                name="Coinbase",
                type="CEX",
                volume_24h="$10B+",
                liquidity_depth="Deep",
                spread="0.05-0.1%",
                examples=["BTC/USD", "ETH/USD", "SOL/USD"]
            ),
            LiquiditySource(
                name="SushiSwap",
                type="DEX",
                volume_24h="$1B+",
                liquidity_depth="Medium",
                spread="0.1-1%",
                examples=["ETH/DAI", "USDC/DAI", "WBTC/ETH"]
            ),
            LiquiditySource(
                name="Kraken",
                type="CEX",
                volume_24h="$5B+",
                liquidity_depth="Deep",
                spread="0.05-0.1%",
                examples=["BTC/USD", "ETH/USD", "XRP/USD"]
            )
        ]
        
        print("\n📋 Liquidity Sources:")
        print(f" {'Name':>15} | {'Type':>8} | {'Volume (24h)':>15} | {'Liquidity':>15} | {'Spread':>12} | {'Examples':>25}")
        print("-" * 95)
        
        for source in sources:
            print(f" {source.name:>15} | {source.type:>8} | {source.volume_24h:>15} | "
                  f"{source.liquidity_depth[:15]:>15} | {source.spread:>12} | "
                  f"{', '.join(source.examples)[:25]:>25}")
    
    def explain_liquidity_metrics(self) -> None:
        """Explain liquidity metrics"""
        print("\n 📊 LIQUIDITY METRICS")
        print("-" * 40)
        
        metrics = [
            LiquidityMetric(
                metric="Order Book Depth",
                value="Buy/Sell volume",
                description="Volume at different price levels",
                significance="Shows market depth and support"
            ),
            LiquidityMetric(
                metric="Bid-Ask Spread",
                value="Price difference",
                description="Difference between buy and sell price",
                significance="Indicates trading costs"
            ),
            LiquidityMetric(
                metric="Volume (24h)",
                value="Trading volume",
                description="Total traded in 24 hours",
                significance="Shows market activity"
            ),
            LiquidityMetric(
                metric="Slippage",
                value="% price change",
                description="Price impact of large orders",
                significance="Shows market resilience"
            ),
            LiquidityMetric(
                metric="Market Depth",
                value="% of volume",
                description="Distribution of orders",
                significance="Shows liquidity concentration"
            )
        ]
        
        print("\n📋 Liquidity Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")
    
    def explain_liquidity_importance(self) -> None:
        """Explain the importance of liquidity"""
        print("\n 🎯 IMPORTANCE OF LIQUIDITY")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  WHY LIQUIDITY MATTERS                                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  FOR TRADERS:                                            │
│  • Lower transaction costs                               │
│  • Better execution prices                               │
│  • Faster trade execution                                │
│  • Reduced price impact                                  │
│  • More reliable markets                                 │
│                                                           │
│  FOR EXCHANGES:                                          │
│  • Attracts more users                                  │
│  • Increases revenue                                    │
│  • Builds reputation                                    │
│  • Competitive advantage                                │
│                                                           │
│  FOR PROJECTS:                                          │
│  • Easier token accumulation                            │
│  • Better price stability                               │
│  • Increased adoption                                   │
│  • Higher valuation                                     │
│                                                           │
│  FOR DEFI:                                              │
│  • Efficient trading                                    │
│  • Lower impermanent loss                               │
│  • Better LP rewards                                    │
│  • Sustainable protocols                                │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_liquidity_pairs(self) -> None:
        """Demonstrate liquidity for different trading pairs"""
        print("\n 📈 LIQUIDITY BY TRADING PAIR")
        print("-" * 40)
        
        pairs = [
            TradingPairLiquidity(
                pair="BTC/USDT",
                volume="High",
                depth="Very Deep",
                spread="0.01-0.02%",
                slippage="<0.1%",
                exchange="Binance"
            ),
            TradingPairLiquidity(
                pair="BTC/USD",
                volume="High",
                depth="Deep",
                spread="0.02-0.05%",
                slippage="<0.2%",
                exchange="Coinbase"
            ),
            TradingPairLiquidity(
                pair="ETH/USDT",
                volume="High",
                depth="Deep",
                spread="0.02-0.03%",
                slippage="<0.15%",
                exchange="Binance"
            ),
            TradingPairLiquidity(
                pair="ETH/USDC",
                volume="Medium",
                depth="Medium",
                spread="0.05-0.1%",
                slippage="0.5-1%",
                exchange="Uniswap"
            ),
            TradingPairLiquidity(
                pair="SHIB/USDT",
                volume="Medium",
                depth="Shallow",
                spread="0.1-0.5%",
                slippage="1-3%",
                exchange="Binance"
            )
        ]
        
        print("\n📋 Trading Pair Liquidity:")
        print(f" {'Pair':>12} | {'Volume':>10} | {'Depth':>15} | {'Spread':>15} | {'Slippage':>12} | {'Exchange':>12}")
        print("-" * 80)
        
        for pair in pairs:
            print(f" {pair.pair:>12} | {pair.volume:>10} | {pair.depth:>15} | {pair.spread:>15} | "
                  f"{pair.slippage:>12} | {pair.exchange:>12}")

class LiquidityAnalytics:
    """Additional analysis tools for liquidity"""
    
    @staticmethod
    def compare_liquidity_levels() -> None:
        """Compare liquidity levels across different assets"""
        print("\n 📊 LIQUIDITY LEVEL COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Asset": ["Bitcoin", "Ethereum", "Solana", "Dogecoin", "Shitcoin"],
            "Liquidity Level": ["Very High", "High", "Medium", "Medium", "Very Low"],
            "Spread": ["0.01%", "0.02%", "0.05%", "0.1%", "1-5%"],
            "Slippage (10k)": ["<0.01%", "<0.02%", "<0.05%", "<0.1%", "5-10%"],
            "Market Makers": ["Many", "Many", "Some", "Some", "Few"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Asset':>15} | {'Liquidity':>15} | {'Spread':>12} | {'Slippage':>15} | {'Makers':>15}")
        print("-" * 75)
        
        for i in range(len(comparison["Asset"])):
            asset = comparison["Asset"][i]
            liquidity = comparison["Liquidity Level"][i]
            spread = comparison["Spread"][i]
            slippage = comparison["Slippage (10k)"][i]
            makers = comparison["Market Makers"][i]
            
            print(f" {asset:>15} | {liquidity:>15} | {spread:>12} | {slippage:>15} | {makers:>15}")
    
    @staticmethod
    def analyze_liquidity_risks() -> None:
        """Analyze liquidity risks"""
        print("\n ⚠️  LIQUIDITY RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Liquidity Crunch": {
                "description": "Sudden drop in available liquidity",
                "impact": "Price manipulation, high slippage",
                "mitigation": "Trade on deep liquidity platforms"
            },
            "Impermanent Loss": {
                "description": "Loss from providing liquidity in DEX",
                "impact": "Reduced value from price divergence",
                "mitigation": "Stable pairs, careful selection"
            },
            "Flash Crash": {
                "description": "Rapid price drop in low liquidity",
                "impact": "Liquidation, loss of value",
                "mitigation": "Use limit orders, monitor positions"
            },
            "Spread Widening": {
                "description": "Increased bid-ask spread",
                "impact": "Higher trading costs",
                "mitigation": "Trade during high liquidity hours"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_liquidity_engine():
    """Execute comprehensive liquidity demonstration"""
    print("=" * 60)
    print(" CRYPTOCURRENCY LIQUIDITY ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = LiquidityEngine()
    
    # Run demonstrations
    engine.explain_liquidity_overview()
    engine.list_liquidity_sources()
    engine.explain_liquidity_metrics()
    engine.explain_liquidity_importance()
    engine.demonstrate_liquidity_pairs()
    
    # Additional analytics
    LiquidityAnalytics.compare_liquidity_levels()
    LiquidityAnalytics.analyze_liquidity_risks()
    
    print("\n" + "=" * 60)
    print(" LIQUIDITY SUMMARY:")
    print("   ✓ Liquidity = Ease of trading")
    print("   ✓ High Liquidity: Tight spreads, minimal slippage")
    print("   ✓ Low Liquidity: Wide spreads, high slippage")
    print("   ✓ Sources: CEX, DEX, Market Makers, LP Providers")
    print("   ✓ Metrics: Depth, Spread, Volume, Slippage")
    print("   ✓ Importance: Efficient markets, better prices")
    print("   ✓ Risks: Liquidity crunch, impermanent loss")
    print("   ✓ Check liquidity before trading")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_liquidity_engine()

4.17 Market Capitalization

What is Market Capitalization?

Market capitalization (market cap) is the total value of a cryptocurrency. It’s calculated by multiplying the current price by the total supply.

Formula:

Market Cap = Price × Circulating Supply

Market Cap Categories:

CategoryMarket CapExamples
Large Cap> $10BBTC, ETH, BNB
Mid Cap$1B – $10BADA, DOT, LINK
Small Cap< $1BNew projects

Code Example – Market Cap:

"""
MARKET CAPITALIZATION FRAMEWORK
================================
Complete market cap analysis for cryptocurrency valuation
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class MarketCapCategory(Enum):
    """Classification of market cap categories"""
    LARGE_CAP = "Large Cap (>$10B)"
    MID_CAP = "Mid Cap ($1B-$10B)"
    SMALL_CAP = "Small Cap ($100M-$1B)"
    MICRO_CAP = "Micro Cap (<$100M)"
    NANO_CAP = "Nano Cap (<$10M)"

@dataclass
class MarketCapAsset:
    """Represents a crypto asset with market cap details"""
    name: str
    symbol: str
    price: str
    circulating_supply: str
    market_cap: str
    category: MarketCapCategory
    volume_24h: str
    rank: int

@dataclass
class MarketCapMetric:
    """Represents a market cap metric"""
    metric: str
    value: str
    description: str
    significance: str

class MarketCapEngine:
    """Complete market capitalization demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" MARKET CAPITALIZATION ENGINE")
        print("=" * 60)
    
    def explain_market_cap_overview(self) -> None:
        """Provide comprehensive market cap overview"""
        print("\n 📊 MARKET CAPITALIZATION OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  MARKET CAPITALIZATION                                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Market Cap = Price × Circulating Supply     │
│  Purpose: Measure of total value and market position      │
│                                                           │
│  CATEGORIES:                                             │
│                                                           │
│  LARGE CAP (> $10B)                                     │
│  • BTC: ~$1.2T, ETH: ~$400B                            │
│  • Characteristics:                                     │
│    - More stable                                        │
│    - Higher liquidity                                    │
│    - More established                                   │
│    - Lower risk                                         │
│                                                           │
│  MID CAP ($1B - $10B)                                  │
│  • ADA: ~$15B, DOT: ~$10B                              │
│  • Characteristics:                                     │
│    - Moderate stability                                 │
│    - Growing liquidity                                   │
│    - Developing projects                                │
│    - Medium risk                                        │
│                                                           │
│  SMALL CAP ($100M - $1B)                                │
│  • Newer projects                                       │
│  • Characteristics:                                     │
│    - Higher volatility                                  │
│    - Lower liquidity                                    │
│    - Higher growth potential                            │
│    - Higher risk                                        │
│                                                           │
│  MICRO CAP (< $100M)                                   │
│  • Very small projects                                 │
│  • Characteristics:                                     │
│    - Extreme volatility                                 │
│    - Very low liquidity                                 │
│    - Speculative                                        │
│    - Very high risk                                     │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_market_cap_assets(self) -> None:
        """List crypto assets by market cap"""
        print("\n 📈 CRYPTO ASSETS BY MARKET CAP")
        print("-" * 40)
        
        assets = [
            MarketCapAsset(
                name="Bitcoin",
                symbol="BTC",
                price="~$60,000",
                circulating_supply="~19.6M",
                market_cap="~$1.18T",
                category=MarketCapCategory.LARGE_CAP,
                volume_24h="~$25B",
                rank=1
            ),
            MarketCapAsset(
                name="Ethereum",
                symbol="ETH",
                price="~$3,200",
                circulating_supply="~120M",
                market_cap="~$384B",
                category=MarketCapCategory.LARGE_CAP,
                volume_24h="~$15B",
                rank=2
            ),
            MarketCapAsset(
                name="BNB",
                symbol="BNB",
                price="~$550",
                circulating_supply="~153M",
                market_cap="~$84B",
                category=MarketCapCategory.LARGE_CAP,
                volume_24h="~$2B",
                rank=3
            ),
            MarketCapAsset(
                name="Solana",
                symbol="SOL",
                price="~$150",
                circulating_supply="~450M",
                market_cap="~$67B",
                category=MarketCapCategory.LARGE_CAP,
                volume_24h="~$3B",
                rank=4
            ),
            MarketCapAsset(
                name="Cardano",
                symbol="ADA",
                price="~$0.40",
                circulating_supply="~35B",
                market_cap="~$14B",
                category=MarketCapCategory.MID_CAP,
                volume_24h="~$500M",
                rank=10
            ),
            MarketCapAsset(
                name="Chainlink",
                symbol="LINK",
                price="~$14",
                circulating_supply="~500M",
                market_cap="~$7B",
                category=MarketCapCategory.MID_CAP,
                volume_24h="~$400M",
                rank=15
            )
        ]
        
        print("\n📋 Asset Details:")
        print(f" {'Rank':>6} | {'Name':>15} | {'Symbol':>8} | {'Price':>12} | {'Supply':>15} | {'Market Cap':>15} | {'24h Volume':>15}")
        print("-" * 90)
        
        for asset in assets:
            print(f" {asset.rank:>6} | {asset.name[:15]:>15} | {asset.symbol:>8} | {asset.price:>12} | "
                  f"{asset.circulating_supply:>15} | {asset.market_cap:>15} | {asset.volume_24h:>15}")
        
        print("\n📋 Category Breakdown:")
        for asset in assets:
            print(f"  • {asset.name} ({asset.symbol}): {asset.category.value}")
    
    def explain_market_cap_metrics(self) -> None:
        """Explain key market cap metrics"""
        print("\n 📊 MARKET CAP METRICS")
        print("-" * 40)
        
        metrics = [
            MarketCapMetric(
                metric="Market Cap",
                value="Price × Supply",
                description="Total value of cryptocurrency",
                significance="Shows overall market position"
            ),
            MarketCapMetric(
                metric="Fully Diluted Cap (FDV)",
                value="Price × Total Supply",
                description="Potential value if all tokens circulating",
                significance="Shows potential dilution"
            ),
            MarketCapMetric(
                metric="Dominance",
                value="Asset MC / Total MC",
                description="Percentage of total crypto market",
                significance="Shows market control"
            ),
            MarketCapMetric(
                metric="Volume/MC Ratio",
                value="24h Volume / Market Cap",
                description="Trading activity relative to size",
                significance="Shows liquidity and activity"
            ),
            MarketCapMetric(
                metric="Price to Supply",
                value="Price per token",
                description="Individual token value",
                significance="Shows affordability"
            )
        ]
        
        print("\n📋 Market Cap Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")
    
    def explain_market_cap_importance(self) -> None:
        """Explain the importance of market cap"""
        print("\n 🎯 WHY MARKET CAP MATTERS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  MARKET CAP IMPORTANCE                                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  INVESTMENT DECISIONS:                                  │
│  • Larger cap = More established                         │
│  • Smaller cap = Higher growth potential                  │
│  • Category determines risk profile                      │
│  • Diversification across caps                            │
│                                                           │
│  RISK ASSESSMENT:                                       │
│  • Large Cap: Low risk, stable                          │
│  • Mid Cap: Moderate risk, growth potential             │
│  • Small Cap: High risk, speculative                     │
│  • Micro Cap: Very high risk, extreme volatility         │
│                                                           │
│  LIQUIDITY ANALYSIS:                                    │
│  • Large cap: Highly liquid                              │
│  • Mid cap: Good liquidity                               │
│  • Small cap: Limited liquidity                          │
│  • Micro cap: Very low liquidity                         │
│                                                           │
│  PORTFOLIO STRATEGY:                                    │
│  • Large Cap: Core holdings                              │
│  • Mid Cap: Growth investments                           │
│  • Small Cap: Speculative plays                          │
│  • Micro Cap: High-risk bets                            │
└─────────────────────────────────────────────────────────────┘
        """)

class MarketCapAnalytics:
    """Additional analysis tools for market cap"""
    
    @staticmethod
    def analyze_category_characteristics() -> None:
        """Analyze characteristics of different market cap categories"""
        print("\n 📊 MARKET CAP CATEGORY CHARACTERISTICS")
        print("-" * 40)
        
        categories = {
            "Attribute": ["Risk Level", "Volatility", "Liquidity", "Growth Potential", "Stability"],
            "Large Cap": ["Low", "Low", "High", "Moderate", "High"],
            "Mid Cap": ["Medium", "Medium", "Medium", "High", "Medium"],
            "Small Cap": ["High", "High", "Low", "Very High", "Low"],
            "Micro Cap": ["Very High", "Very High", "Very Low", "Extreme", "Very Low"]
        }
        
        print("\n📋 Category Comparison:")
        print(f" {'Attribute':>20} | {'Large Cap':>15} | {'Mid Cap':>15} | {'Small Cap':>15} | {'Micro Cap':>15}")
        print("-" * 85)
        
        for i in range(len(categories["Attribute"])):
            attr = categories["Attribute"][i]
            large = categories["Large Cap"][i]
            mid = categories["Mid Cap"][i]
            small = categories["Small Cap"][i]
            micro = categories["Micro Cap"][i]
            
            print(f" {attr:>20} | {large:>15} | {mid:>15} | {small:>15} | {micro:>15}")
    
    @staticmethod
    def analyze_top_10_dominance() -> None:
        """Analyze market cap dominance of top cryptocurrencies"""
        print("\n 📈 TOP 10 MARKET CAP DOMINANCE")
        print("-" * 40)
        
        dominance = {
            "Asset": ["BTC", "ETH", "USDT", "BNB", "SOL", "XRP", "USDC", "ADA", "DOGE", "AVAX"],
            "Market Cap": ["$1.18T", "$384B", "$100B", "$84B", "$67B", "$30B", "$25B", "$14B", "$12B", "$10B"],
            "Dominance": ["55%", "18%", "4.7%", "3.9%", "3.1%", "1.4%", "1.2%", "0.7%", "0.6%", "0.5%"],
            "Category": ["Large", "Large", "Large", "Large", "Large", "Mid", "Mid", "Mid", "Mid", "Mid"]
        }
        
        print("\n📋 Top 10 Assets:")
        print(f" {'Asset':>8} | {'Market Cap':>15} | {'Dominance':>12} | {'Category':>12}")
        print("-" * 55)
        
        for i in range(len(dominance["Asset"])):
            asset = dominance["Asset"][i]
            cap = dominance["Market Cap"][i]
            dom = dominance["Dominance"][i]
            category = dominance["Category"][i]
            
            print(f" {asset:>8} | {cap:>15} | {dom:>12} | {category:>12}")

def demonstrate_market_cap_engine():
    """Execute comprehensive market cap demonstration"""
    print("=" * 60)
    print(" MARKET CAPITALIZATION ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = MarketCapEngine()
    
    # Run demonstrations
    engine.explain_market_cap_overview()
    engine.list_market_cap_assets()
    engine.explain_market_cap_metrics()
    engine.explain_market_cap_importance()
    
    # Additional analytics
    MarketCapAnalytics.analyze_category_characteristics()
    MarketCapAnalytics.analyze_top_10_dominance()
    
    print("\n" + "=" * 60)
    print(" MARKET CAP SUMMARY:")
    print("   ✓ Market Cap = Price × Circulating Supply")
    print("   ✓ Categories: Large, Mid, Small, Micro")
    print("   ✓ Large Cap: >$10B (BTC, ETH)")
    print("   ✓ Mid Cap: $1B-$10B (ADA, DOT)")
    print("   ✓ Small Cap: $100M-$1B")
    print("   ✓ Micro Cap: <$100M")
    print("   ✓ Use Cases: Risk assessment, investment decisions")
    print("   ✓ Compare market caps, not just prices")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_market_cap_engine()

4.18 FDV

What is FDV?

Fully Diluted Valuation (FDV) is the market cap if all tokens were in circulation. It represents the maximum potential market cap.

Formula:

FDV = Price × Total Supply (Max Supply)

FDV vs Market Cap:

AspectMarket CapFDV
DefinitionCurrent valuePotential value
SupplyCirculatingTotal
ComparisonActualTheoretical

Code Example – FDV:

"""
FULLY DILUTED VALUATION FRAMEWORK
==================================
Complete FDV analysis and comparison for cryptocurrency valuation
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class FDVAsset:
    """Represents a crypto asset with FDV details"""
    name: str
    symbol: str
    price: str
    circulating_supply: str
    total_supply: str
    market_cap: str
    fdv: str
    fdv_mc_ratio: float
    unlock_schedule: str

@dataclass
class FDVMetric:
    """Represents an FDV metric"""
    metric: str
    value: str
    description: str
    significance: str

class FDVEngine:
    """Complete FDV demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" FULLY DILUTED VALUATION ENGINE")
        print("=" * 60)
    
    def explain_fdv_overview(self) -> None:
        """Provide comprehensive FDV overview"""
        print("\n 📊 FULLY DILUTED VALUATION OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  FULLY DILUTED VALUATION (FDV)                           │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: FDV = Price × Total Supply                  │
│  Purpose: Maximum potential market cap                    │
│                                                           │
│  FORMULA:                                                │
│  Market Cap = Price × Circulating Supply                 │
│  FDV = Price × Total Supply                              │
│                                                           │
│  EXAMPLE:                                                │
│  • Token Price: $10                                      │
│  • Circulating Supply: 10M                               │
│  • Total Supply: 100M                                    │
│                                                           │
│  Market Cap = $10 × 10M = $100M                         │
│  FDV = $10 × 100M = $1B                                 │
│                                                           │
│  FDV/MC RATIO = 10x                                      │
│                                                           │
│  WHY FDV MATTERS:                                       │
│  • Shows potential dilution                              │
│  • Reveals true valuation                                 │
│  • Indicates token unlock pressure                       │
│  • Helps compare projects                                │
│                                                           │
│  INTERPRETATION:                                        │
│  • Low FDV/MC Ratio (<2x): Less dilution risk           │
│  • Medium FDV/MC Ratio (2-5x): Moderate dilution        │
│  • High FDV/MC Ratio (>5x): High dilution risk          │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_fdv_assets(self) -> None:
        """List crypto assets with FDV details"""
        print("\n 📈 CRYPTO ASSETS WITH FDV")
        print("-" * 40)
        
        assets = [
            FDVAsset(
                name="Ethereum",
                symbol="ETH",
                price="$3,200",
                circulating_supply="120M",
                total_supply="120M (No cap)",
                market_cap="$384B",
                fdv="$384B",
                fdv_mc_ratio=1.0,
                unlock_schedule="No fixed cap"
            ),
            FDVAsset(
                name="Solana",
                symbol="SOL",
                price="$150",
                circulating_supply="450M",
                total_supply="489M",
                market_cap="$67.5B",
                fdv="$73.4B",
                fdv_mc_ratio=1.09,
                unlock_schedule="Inflationary"
            ),
            FDVAsset(
                name="Optimism",
                symbol="OP",
                price="$3.00",
                circulating_supply="1B",
                total_supply="4.3B",
                market_cap="$3B",
                fdv="$12.9B",
                fdv_mc_ratio=4.3,
                unlock_schedule="Vested over 4 years"
            ),
            FDVAsset(
                name="Arbitrum",
                symbol="ARB",
                price="$1.50",
                circulating_supply="1.3B",
                total_supply="10B",
                market_cap="$1.95B",
                fdv="$15B",
                fdv_mc_ratio=7.7,
                unlock_schedule="Vested over 4 years"
            ),
            FDVAsset(
                name="Aptos",
                symbol="APT",
                price="$10.00",
                circulating_supply="300M",
                total_supply="1B",
                market_cap="$3B",
                fdv="$10B",
                fdv_mc_ratio=3.33,
                unlock_schedule="Vested over 10 years"
            )
        ]
        
        print("\n📋 FDV Details:")
        print(f" {'Name':>15} | {'Symbol':>8} | {'Price':>12} | {'Circ Supply':>15} | {'Total Supply':>15} | {'MC':>15} | {'FDV':>15} | {'Ratio':>8}")
        print("-" * 110)
        
        for asset in assets:
            print(f" {asset.name[:15]:>15} | {asset.symbol:>8} | {asset.price:>12} | "
                  f"{asset.circulating_supply:>15} | {asset.total_supply[:15]:>15} | {asset.market_cap:>15} | "
                  f"{asset.fdv:>15} | {asset.fdv_mc_ratio:>7.1f}x")
        
        print("\n📋 Unlock Schedule:")
        for asset in assets:
            print(f"  • {asset.name} ({asset.symbol}): {asset.unlock_schedule}")
    
    def explain_fdv_metrics(self) -> None:
        """Explain key FDV metrics"""
        print("\n 📊 FDV METRICS")
        print("-" * 40)
        
        metrics = [
            FDVMetric(
                metric="FDV/MC Ratio",
                value="Total Supply / Circulating Supply",
                description="Ratio of total to circulating supply",
                significance="Shows dilution potential"
            ),
            FDVMetric(
                metric="Token Unlock Schedule",
                value="Vesting timeline",
                description="When tokens become available",
                significance="Shows future supply pressure"
            ),
            FDVMetric(
                metric="Dilution Risk",
                value="Potential price impact",
                description="Risk from new tokens entering market",
                significance="Affects long-term valuation"
            ),
            FDVMetric(
                metric="FDV Ranking",
                value="Comparative valuation",
                description="FDV compared to market cap",
                significance="Shows over/under valuation"
            ),
            FDVMetric(
                metric="Vesting Cliff",
                value="Lockup period",
                description="Time before tokens unlock",
                significance="Shows initial supply"
            )
        ]
        
        print("\n📋 FDV Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")
    
    def explain_fdv_importance(self) -> None:
        """Explain the importance of FDV"""
        print("\n 🎯 WHY FDV MATTERS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  FDV IMPORTANCE                                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  INVESTMENT ANALYSIS:                                   │
│  • Compare projects fairly                               │
│  • Assess dilution risk                                  │
│  • Understand true valuation                             │
│  • Evaluate tokenomics                                   │
│                                                           │
│  RISK ASSESSMENT:                                       │
│  • High FDV/MC Ratio = High dilution risk               │
│  • Unlock schedule = Price pressure timeline            │
│  • Team/VC allocations = Supply distribution            │
│  • Community allocation = Decentralization              │
│                                                           │
│  PRICE IMPACT:                                          │
│  • New tokens entering market                           │
│  • Sell pressure from unlocks                           │
│  • Supply-demand dynamics                               │
│  • Long-term price trends                               │
│                                                           │
│  PROJECT COMPARISON:                                   │
│  • Same supply? Compare MC/FDV                         │
│  • Different supplies? Use FDV                         │
│  • Unlocked tokens? Consider dilution                  │
│  • Vesting schedules? Assess timing                    │
└─────────────────────────────────────────────────────────────┘
        """)

class FDVAnalytics:
    """Additional analysis tools for FDV"""
    
    @staticmethod
    def compare_fdv_ratios() -> None:
        """Compare FDV ratios across assets"""
        print("\n 📊 FDV RATIO COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Asset": ["BTC", "ETH", "SOL", "OP", "ARB", "APT"],
            "FDV/MC": ["~1.0x", "~1.0x", "~1.1x", "~4.3x", "~7.7x", "~3.3x"],
            "Unlock Risk": ["Low", "Low", "Low", "High", "Very High", "Medium"],
            "Dilution Potential": ["None", "Low", "Low", "High", "Very High", "Medium"],
            "Vesting Period": ["N/A", "N/A", "N/A", "4 Years", "4 Years", "10 Years"]
        }
        
        print("\n📋 FDV Comparison:")
        print(f" {'Asset':>10} | {'FDV/MC':>12} | {'Unlock Risk':>15} | {'Dilution':>15} | {'Vesting':>15}")
        print("-" * 70)
        
        for i in range(len(comparison["Asset"])):
            asset = comparison["Asset"][i]
            ratio = comparison["FDV/MC"][i]
            risk = comparison["Unlock Risk"][i]
            dilution = comparison["Dilution Potential"][i]
            vesting = comparison["Vesting Period"][i]
            
            print(f" {asset:>10} | {ratio:>12} | {risk:>15} | {dilution:>15} | {vesting:>15}")
    
    @staticmethod
    def analyze_unlock_impact() -> None:
        """Analyze impact of token unlocks on price"""
        print("\n 📈 UNLOCK IMPACT ANALYSIS")
        print("-" * 40)
        
        unlock_scenarios = {
            "Scenario": ["Small Unlock", "Medium Unlock", "Large Unlock", "Massive Unlock"],
            "Unlock Size": ["1% Supply", "5% Supply", "20% Supply", "50% Supply"],
            "Price Impact": ["Minimal", "Moderate", "Significant", "Major"],
            "Duration": ["1-2 Weeks", "1 Month", "2-3 Months", "6+ Months"],
            "Risk Level": ["Low", "Medium", "High", "Very High"]
        }
        
        print("\n📋 Unlock Impact Scenarios:")
        print(f" {'Scenario':>15} | {'Unlock Size':>15} | {'Price Impact':>20} | {'Duration':>20} | {'Risk':>15}")
        print("-" * 90)
        
        for i in range(len(unlock_scenarios["Scenario"])):
            scenario = unlock_scenarios["Scenario"][i]
            size = unlock_scenarios["Unlock Size"][i]
            impact = unlock_scenarios["Price Impact"][i]
            duration = unlock_scenarios["Duration"][i]
            risk = unlock_scenarios["Risk Level"][i]
            
            print(f" {scenario:>15} | {size:>15} | {impact:>20} | {duration:>20} | {risk:>15}")

def demonstrate_fdv_engine():
    """Execute comprehensive FDV demonstration"""
    print("=" * 60)
    print(" FULLY DILUTED VALUATION ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = FDVEngine()
    
    # Run demonstrations
    engine.explain_fdv_overview()
    engine.list_fdv_assets()
    engine.explain_fdv_metrics()
    engine.explain_fdv_importance()
    
    # Additional analytics
    FDVAnalytics.compare_fdv_ratios()
    FDVAnalytics.analyze_unlock_impact()
    
    print("\n" + "=" * 60)
    print(" FDV SUMMARY:")
    print("   ✓ FDV = Price × Total Supply")
    print("   ✓ Formula: FDV = Market Cap × (Total Supply / Circulating Supply)")
    print("   ✓ Purpose: Shows potential market cap")
    print("   ✓ FDV/MC Ratio: Low (<2x) = Low dilution risk")
    print("   ✓ FDV/MC Ratio: High (>5x) = High dilution risk")
    print("   ✓ Unlock Schedule: Shows future supply pressure")
    print("   ✓ Use: Compare valuations, assess dilution")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_fdv_engine()

4.19 TVL

What is TVL?

The total value of assets deposited or locked in a DeFi protocol or decentralized application. It measures protocol size, liquidity, and adoption.

TVL Components:

ComponentDescription
LendingDeposits in lending protocols
DEXLiquidity in DEX pools
StakingStaked tokens
YieldYield farming deposits

Code Example – TVL:

"""
TOTAL VALUE LOCKED FRAMEWORK
=============================
Complete TVL analysis for DeFi protocols
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class TVLCategory(Enum):
    """Classification of TVL categories"""
    LENDING = "Lending"
    DEX = "DEX Liquidity"
    STAKING = "Staking"
    YIELD = "Yield Farming"
    BRIDGE = "Bridge"

@dataclass
class TVLProtocol:
    """Represents a DeFi protocol with TVL details"""
    name: str
    category: TVLCategory
    tvl: str
    tvl_change_24h: str
    chain: str
    token: str
    features: List[str]

@dataclass
class TVLMetric:
    """Represents a TVL metric"""
    metric: str
    value: str
    description: str
    significance: str

class TVLEngine:
    """Complete TVL demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" TOTAL VALUE LOCKED ENGINE")
        print("=" * 60)
    
    def explain_tvl_overview(self) -> None:
        """Provide comprehensive TVL overview"""
        print("\n 📊 TOTAL VALUE LOCKED OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  TOTAL VALUE LOCKED (TVL)                                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: TVL = Value of assets in DeFi protocols     │
│  Purpose: Measure of DeFi adoption and liquidity          │
│                                                           │
│  COMPONENTS:                                             │
│                                                           │
│  1. LENDING                                             │
│     • Users deposit collateral                            │
│     • Borrowers take loans                               │
│     • Examples: Aave, Compound, Maker                    │
│                                                           │
│  2. DEX LIQUIDITY                                       │
│     • Liquidity pools                                    │
│     • Trading pairs                                      │
│     • Examples: Uniswap, Curve, Balancer                │
│                                                           │
│  3. STAKING                                             │
│     • Token staking                                      │
│     • Validator deposits                                 │
│     • Examples: Lido, Rocket Pool, Marinade             │
│                                                           │
│  4. YIELD FARMING                                       │
│     • Yield optimization                                 │
│     • Auto-compounding                                   │
│     • Examples: Yearn, Convex, Beefy                   │
│                                                           │
│  5. BRIDGES                                              │
│     • Cross-chain liquidity                              │
│     • Asset bridges                                      │
│     • Examples: Wormhole, Multichain                   │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_top_protocols(self) -> None:
        """List top protocols by TVL"""
        print("\n 📈 TOP PROTOCOLS BY TVL")
        print("-" * 40)
        
        protocols = [
            TVLProtocol(
                name="Lido",
                category=TVLCategory.STAKING,
                tvl="$35B",
                tvl_change_24h="+2.5%",
                chain="Ethereum",
                token="stETH",
                features=["Liquid staking", "Ethereum PoS", "Easy staking"]
            ),
            TVLProtocol(
                name="Aave",
                category=TVLCategory.LENDING,
                tvl="$12B",
                tvl_change_24h="+1.8%",
                chain="Ethereum",
                token="AAVE",
                features=["Lending", "Borrowing", "Flash loans"]
            ),
            TVLProtocol(
                name="Uniswap",
                category=TVLCategory.DEX,
                tvl="$5.5B",
                tvl_change_24h="+3.2%",
                chain="Ethereum",
                token="UNI",
                features=["DEX", "Liquidity pools", "Trading"]
            ),
            TVLProtocol(
                name="Curve",
                category=TVLCategory.DEX,
                tvl="$4.2B",
                tvl_change_24h="-1.5%",
                chain="Ethereum",
                token="CRV",
                features=["Stable swaps", "Trading", "LP rewards"]
            ),
            TVLProtocol(
                name="MakerDAO",
                category=TVLCategory.LENDING,
                tvl="$8.0B",
                tvl_change_24h="+0.8%",
                chain="Ethereum",
                token="DAI",
                features=["DAI stable", "CDP", "Governance"]
            ),
            TVLProtocol(
                name="Compound",
                category=TVLCategory.LENDING,
                tvl="$3.5B",
                tvl_change_24h="-0.5%",
                chain="Ethereum",
                token="COMP",
                features=["Lending", "Borrowing", "Interest"]
            )
        ]
        
        print("\n📋 Protocol Details:")
        print(f" {'Name':>15} | {'Category':>12} | {'TVL':>12} | {'24h Change':>12} | {'Chain':>12} | {'Token':>8}")
        print("-" * 80)
        
        for protocol in protocols:
            print(f" {protocol.name[:15]:>15} | {protocol.category.value[:12]:>12} | {protocol.tvl:>12} | "
                  f"{protocol.tvl_change_24h:>12} | {protocol.chain[:12]:>12} | {protocol.token:>8}")
        
        print("\n📋 Features:")
        for protocol in protocols[:3]:
            print(f"  • {protocol.name}: {', '.join(protocol.features)}")
    
    def explain_tvl_metrics(self) -> None:
        """Explain key TVL metrics"""
        print("\n 📊 TVL METRICS")
        print("-" * 40)
        
        metrics = [
            TVLMetric(
                metric="Total TVL",
                value="Sum of all assets",
                description="Overall value locked",
                significance="Shows DeFi ecosystem size"
            ),
            TVLMetric(
                metric="Protocol TVL",
                value="Value in protocol",
                description="Assets in specific protocol",
                significance="Shows protocol adoption"
            ),
            TVLMetric(
                metric="TVL Growth Rate",
                value="% change over time",
                description="TVL growth or decline",
                significance="Shows trends and momentum"
            ),
            TVLMetric(
                metric="TVL/Volume",
                value="Locked value to trading",
                description="Capital efficiency",
                significance="Shows liquidity utilization"
            ),
            TVLMetric(
                metric="Dominance",
                value="% of total TVL",
                description="Protocol market share",
                significance="Shows competitive position"
            )
        ]
        
        print("\n📋 TVL Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric:>25} | {metric.value[:20]:>20} | {metric.description[:30]:>30} | "
                  f"{metric.significance[:30]:>30}")
    
    def explain_tvl_importance(self) -> None:
        """Explain the importance of TVL"""
        print("\n 🎯 WHY TVL MATTERS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  TVL IMPORTANCE                                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  FOR USERS:                                              │
│  • Indicates protocol safety                             │
│  • Shows liquidity depth                                 │
│  • Better yields                                          │
│  • Lower slippage                                         │
│  • More trust                                             │
│                                                           │
│  FOR PROTOCOLS:                                         │
│  • Attracts more users                                   │
│  • Increases revenue                                     │
│  • Builds reputation                                     │
│  • Competitive advantage                                 │
│                                                           │
│  FOR INVESTORS:                                         │
│  • Adoption metric                                       │
│  • Growth indicator                                      │
│  • Comparative analysis                                  │
│  • Risk assessment                                      │
│                                                           │
│  FOR ECOSYSTEM:                                         │
│  • Shows DeFi health                                     │
│  • Indicates innovation                                  │
│  • Measures growth                                       │
│  • Attracts capital                                      │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_tvl_by_chain(self) -> None:
        """Demonstrate TVL distribution by blockchain"""
        print("\n 📊 TVL BY BLOCKCHAIN")
        print("-" * 40)
        
        chains = {
            "Ethereum": {"TVL": "$65B", "Protocols": "500+", "Dominance": "60%"},
            "BSC": {"TVL": "$10B", "Protocols": "300+", "Dominance": "10%"},
            "Solana": {"TVL": "$5B", "Protocols": "100+", "Dominance": "5%"},
            "Arbitrum": {"TVL": "$8B", "Protocols": "150+", "Dominance": "7%"},
            "Optimism": {"TVL": "$4B", "Protocols": "100+", "Dominance": "4%"},
            "Polygon": {"TVL": "$3B", "Protocols": "200+", "Dominance": "3%"},
            "Other": {"TVL": "$10B", "Protocols": "500+", "Dominance": "11%"}
        }
        
        print("\n📋 TVL Distribution:")
        print(f" {'Chain':>15} | {'TVL':>15} | {'Protocols':>15} | {'Dominance':>15}")
        print("-" * 65)
        
        for chain, data in chains.items():
            print(f" {chain[:15]:>15} | {data['TVL']:>15} | {data['Protocols']:>15} | {data['Dominance']:>15}")

class TVLAnalytics:
    """Additional analysis tools for TVL"""
    
    @staticmethod
    def analyze_tvl_growth() -> None:
        """Analyze TVL growth trends"""
        print("\n 📈 TVL GROWTH ANALYSIS")
        print("-" * 40)
        
        growth_data = {
            "Year": ["2020", "2021", "2022", "2023", "2024"],
            "TVL (B)": ["$1B", "$100B", "$50B", "$80B", "$110B"],
            "Growth": ["N/A", "+9,900%", "-50%", "+60%", "+37.5%"],
            "Trend": ["Starting", "Explosion", "Correction", "Recovery", "Growth"]
        }
        
        print("\n📋 TVL Growth History:")
        print(f" {'Year':>10} | {'TVL':>15} | {'Growth':>15} | {'Trend':>15}")
        print("-" * 60)
        
        for i in range(len(growth_data["Year"])):
            year = growth_data["Year"][i]
            tvl = growth_data["TVL (B)"][i]
            growth = growth_data["Growth"][i]
            trend = growth_data["Trend"][i]
            
            print(f" {year:>10} | {tvl:>15} | {growth:>15} | {trend:>15}")
    
    @staticmethod
    def analyze_tvl_risks() -> None:
        """Analyze TVL risks"""
        print("\n ⚠️  TVL RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Liquidity Risk": {
                "description": "Sudden withdrawal of liquidity",
                "impact": "Protocol instability",
                "mitigation": "Insurance, diversification"
            },
            "Smart Contract Risk": {
                "description": "Code vulnerabilities",
                "impact": "Funds loss, hacks",
                "mitigation": "Audits, bug bounties"
            },
            "Oracle Risk": {
                "description": "Price feed manipulation",
                "impact": "Wrong valuations, liquidations",
                "mitigation": "Multi-oracle, decentralization"
            },
            "Regulatory Risk": {
                "description": "Changing regulations",
                "impact": "Protocol restrictions",
                "mitigation": "Legal compliance"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_tvl_engine():
    """Execute comprehensive TVL demonstration"""
    print("=" * 60)
    print(" TOTAL VALUE LOCKED ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = TVLEngine()
    
    # Run demonstrations
    engine.explain_tvl_overview()
    engine.list_top_protocols()
    engine.explain_tvl_metrics()
    engine.explain_tvl_importance()
    engine.demonstrate_tvl_by_chain()
    
    # Additional analytics
    TVLAnalytics.analyze_tvl_growth()
    TVLAnalytics.analyze_tvl_risks()
    
    print("\n" + "=" * 60)
    print(" TVL SUMMARY:")
    print("   ✓ TVL = Total Value Locked in DeFi")
    print("   ✓ Categories: Lending, DEX, Staking, Yield")
    print("   ✓ Top Protocols: Lido ($35B), Aave ($12B)")
    print("   ✓ Metrics: Growth rate, protocol share")
    print("   ✓ Importance: Adoption, liquidity, trust")
    print("   ✓ Risks: Liquidity, smart contracts, regulation")
    print("   ✓ Use: Compare DeFi protocols")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_tvl_engine()

5. Wallets & Transactions

5.1 Wallet Fundamentals

What is a Crypto Wallet?

A software application or hardware device that securely manages the private and public keys used to access and transact with cryptocurrency. It enables users to send, receive, and store cryptocurrencies.

Wallet Components:

ComponentPurpose
Private KeySign transactions
Public KeyReceive funds
AddressShare with others
Seed PhraseBackup and recovery

Code Example – Wallet Fundamentals:

"""
CRYPTO WALLET FUNDAMENTALS FRAMEWORK
=====================================
Complete understanding of crypto wallets, keys, and security
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class WalletType(Enum):
    """Classification of wallet types"""
    HARDWARE = "Hardware Wallet"
    SOFTWARE = "Software Wallet"
    PAPER = "Paper Wallet"
    WEB = "Web Wallet"
    MOBILE = "Mobile Wallet"

@dataclass
class WalletComponent:
    """Represents a wallet component"""
    name: str
    description: str
    purpose: str
    security_level: str
    example: str

@dataclass
class WalletFeature:
    """Represents a wallet feature"""
    feature: str
    description: str
    importance: str
    supported_by: List[str]

class WalletEngine:
    """Complete wallet fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CRYPTO WALLET FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_wallet_overview(self) -> None:
        """Provide comprehensive wallet overview"""
        print("\n 👛 WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CRYPTO WALLET FUNDAMENTALS                              │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Crypto Wallet = Key Management Tool         │
│  Purpose: Manage private keys and interact with blockchain│
│                                                           │
│  WHAT A WALLET DOES:                                    │
│  ✓ Stores private keys                                    │
│  ✓ Signs transactions                                     │
│  ✓ Receives funds                                         │
│  ✓ Displays balances                                      │
│  ✓ Backs up recovery phrase                               │
│  ✓ Connects to dApps                                      │
│                                                           │
│  KEY COMPONENTS:                                        │
│                                                           │
│  1. PRIVATE KEY                                         │
│     • Secret, never share                                 │
│     • Signs transactions                                  │
│     • Proves ownership                                    │
│     • 256-bit random number                              │
│                                                           │
│  2. PUBLIC KEY                                          │
│     • Derived from private key                           │
│     • Used to receive funds                              │
│     • Shared openly                                       │
│     • Generated cryptographically                         │
│                                                           │
│  3. WALLET ADDRESS                                      │
│     • Hashed public key                                  │
│     • Shareable                                           │
│     • Human-readable format                              │
│     • Unique identifier                                  │
│                                                           │
│  4. SEED PHRASE                                         │
│     • 12-24 word backup                                   │
│     • Recovery mechanism                                  │
│     • Must be stored offline                             │
│     • Master key generator                               │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_wallet_types(self) -> None:
        """List different wallet types"""
        print("\n 📊 WALLET TYPES")
        print("-" * 40)
        
        wallet_types = {
            "Hardware Wallet": {
                "description": "Physical device storing private keys",
                "examples": ["Ledger", "Trezor", "SafePal"],
                "security": "Very High",
                "cost": "$50-200",
                "use": "Long-term storage, high security"
            },
            "Software Wallet": {
                "description": "Desktop or mobile application",
                "examples": ["Metamask", "Trust Wallet", "Phantom"],
                "security": "Medium-High",
                "cost": "Free",
                "use": "Daily transactions, DeFi"
            },
            "Paper Wallet": {
                "description": "Physical print of keys",
                "examples": ["Generated offline", "Bitaddress"],
                "security": "High (if stored securely)",
                "cost": "Free",
                "use": "Cold storage, gifts"
            },
            "Web Wallet": {
                "description": "Browser-based wallet",
                "examples": ["Coinbase Wallet", "Binance Wallet"],
                "security": "Medium",
                "cost": "Free",
                "use": "Trading, beginners"
            },
            "Mobile Wallet": {
                "description": "Smartphone application",
                "examples": ["Trust Wallet", "Coinbase", "Exodus"],
                "security": "Medium",
                "cost": "Free",
                "use": "Daily use, payments"
            }
        }
        
        print("\n📋 Wallet Types:")
        print(f" {'Type':>15} | {'Description':>30} | {'Security':>15} | {'Cost':>12} | {'Examples':>25}")
        print("-" * 100)
        
        for wallet_type, details in wallet_types.items():
            print(f" {wallet_type[:15]:>15} | {details['description'][:30]:>30} | "
                  f"{details['security']:>15} | {details['cost']:>12} | "
                  f"{', '.join(details['examples'][:2])[:25]:>25}")
    
    def explain_wallet_components(self) -> None:
        """Explain wallet components in detail"""
        print("\n 🔧 WALLET COMPONENTS")
        print("-" * 40)
        
        components = [
            WalletComponent(
                name="Private Key",
                description="256-bit random number",
                purpose="Sign transactions, prove ownership",
                security_level="Critical (must never share)",
                example="5Kb8kLf9zgWQnogidDA76MzPL6TsZZY36hWXMssSzNydYXYB9KF"
            ),
            WalletComponent(
                name="Public Key",
                description="Derived from private key",
                purpose="Receive funds, verify signatures",
                security_level="Public (can share)",
                example="04f028892bad7ed57d2fb57bf33081d5cfcf6f9ed3d3d7f9c4e2a2b6b5e5a5d5"
            ),
            WalletComponent(
                name="Wallet Address",
                description="Hashed public key",
                purpose="Receive funds (human-readable)",
                security_level="Public (can share)",
                example="1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
            ),
            WalletComponent(
                name="Seed Phrase",
                description="12-24 word backup phrase",
                purpose="Recover wallet, generate keys",
                security_level="Critical (must never share)",
                example="abandon ability able about above absent absorb abstract absurd abuse access accident"
            )
        ]
        
        print("\n📋 Component Details:")
        print(f" {'Component':>15} | {'Description':>30} | {'Purpose':>30} | {'Security':>15} | {'Example':>20}")
        print("-" * 115)
        
        for component in components:
            print(f" {component.name[:15]:>15} | {component.description[:30]:>30} | "
                  f"{component.purpose[:30]:>30} | {component.security_level[:15]:>15} | "
                  f"{component.example[:20]:>20}")
    
    def explain_wallet_security(self) -> None:
        """Explain wallet security best practices"""
        print("\n 🛡️  WALLET SECURITY")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  WALLET SECURITY BEST PRACTICES                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DO:                                                    │
│  ✅ Use hardware wallets for large holdings              │
│  ✅ Store seed phrase offline (paper, steel)             │
│  ✅ Keep multiple backups                                 │
│  ✅ Use strong passwords                                  │
│  ✅ Enable 2FA where possible                            │
│  ✅ Verify transaction details before signing            │
│  ✅ Keep software updated                                 │
│  ✅ Use secure networks                                   │
│                                                           │
│  DON'T:                                                 │
│  ❌ Never share private keys                              │
│  ❌ Never share seed phrase                               │
│  ❌ Never screenshot seed phrase                          │
│  ❌ Never store seed digitally                            │
│  ❌ Never enter seed on suspicious sites                 │
│  ❌ Never use public Wi-Fi for transactions              │
│  ❌ Never use centralized exchanges as wallets           │
│  ❌ Never ignore security warnings                       │
│                                                           │
│  COMMON ATTACKS:                                        │
│  • Phishing attempts                                     │
│  • Malware/keyloggers                                    │
│  • Social engineering                                    │
│  • Fake wallet apps                                     │
│  • SIM swapping                                          │
│  • Clipboard hijacking                                   │
└─────────────────────────────────────────────────────────────┘
        """)

class WalletAnalytics:
    """Additional analysis tools for wallets"""
    
    @staticmethod
    def compare_wallet_security() -> None:
        """Compare wallet security levels"""
        print("\n 📊 WALLET SECURITY COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Private Key Storage", "Online Access", "Phishing Risk", "Malware Risk", "Physical Theft"],
            "Hardware": ["Offline", "Limited", "Low", "Low", "Medium"],
            "Software": ["Encrypted", "Full", "Medium", "High", "Low"],
            "Web": ["Online", "Full", "High", "High", "Low"],
            "Paper": ["Offline", "None", "Low", "Low", "High"]
        }
        
        print("\n📋 Security Matrix:")
        print(f" {'Attribute':>25} | {'Hardware':>15} | {'Software':>15} | {'Web':>15} | {'Paper':>15}")
        print("-" * 85)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            hardware = comparison["Hardware"][i]
            software = comparison["Software"][i]
            web = comparison["Web"][i]
            paper = comparison["Paper"][i]
            
            print(f" {attr:>25} | {hardware:>15} | {software:>15} | {web:>15} | {paper:>15}")
    
    @staticmethod
    def analyze_wallet_usage() -> None:
        """Analyze wallet usage patterns"""
        print("\n 📈 WALLET USAGE PATTERNS")
        print("-" * 40)
        
        usage_patterns = {
            "Pattern": ["Daily Trading", "Long-term Storage", "DeFi Users", "NFT Collectors", "Beginners"],
            "Recommended": ["Software/Mobile", "Hardware", "Software/Hardware", "Software", "Software/Web"],
            "Security": ["Medium", "Very High", "High", "Medium", "Low-Medium"],
            "Convenience": ["High", "Low", "Medium", "Medium", "High"]
        }
        
        print("\n📋 Usage Recommendations:")
        print(f" {'Pattern':>20} | {'Recommended':>25} | {'Security':>15} | {'Convenience':>15}")
        print("-" * 80)
        
        for i in range(len(usage_patterns["Pattern"])):
            pattern = usage_patterns["Pattern"][i]
            recommended = usage_patterns["Recommended"][i]
            security = usage_patterns["Security"][i]
            convenience = usage_patterns["Convenience"][i]
            
            print(f" {pattern:>20} | {recommended:>25} | {security:>15} | {convenience:>15}")

def demonstrate_wallet_engine():
    """Execute comprehensive wallet demonstration"""
    print("=" * 60)
    print(" CRYPTO WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = WalletEngine()
    
    # Run demonstrations
    engine.explain_wallet_overview()
    engine.list_wallet_types()
    engine.explain_wallet_components()
    engine.explain_wallet_security()
    
    # Additional analytics
    WalletAnalytics.compare_wallet_security()
    WalletAnalytics.analyze_wallet_usage()
    
    print("\n" + "=" * 60)
    print(" WALLET FUNDAMENTALS SUMMARY:")
    print("   ✓ Wallet = Key Management Tool")
    print("   ✓ Components: Private Key, Public Key, Address, Seed")
    print("   ✓ Types: Hardware, Software, Web, Paper")
    print("   ✓ Security: Hardware > Software > Web")
    print("   ✓ Never share private keys or seed phrase")
    print("   ✓ Hardware wallets recommended for large holdings")
    print("   ✓ Backup seed phrase securely offline")
    print("   ✓ Always verify transactions before signing")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_wallet_engine()

5.2 Hot Wallets

What are Hot Wallets?

Hot wallets are cryptocurrency wallets that are connected to the internet. They are convenient for frequent transactions but less secure than cold wallets.

Hot Wallet Examples:

WalletTypePlatform
MetaMaskBrowser ExtensionDesktop
Trust WalletMobile AppiOS/Android
Coinbase WalletMobile AppiOS/Android

Code Example – Hot Wallets:

"""
HOT WALLET FRAMEWORK
=====================
Complete hot wallet fundamentals and security analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class HotWalletType(Enum):
    """Classification of hot wallet types"""
    BROWSER_EXTENSION = "Browser Extension"
    MOBILE_APP = "Mobile Application"
    DESKTOP_APP = "Desktop Application"
    WEB_BASED = "Web-Based"

@dataclass
class HotWallet:
    """Represents a hot wallet with its properties"""
    name: str
    type: HotWalletType
    supported_chains: List[str]
    security_level: str
    convenience_score: str
    risk_factors: List[str]
    best_use_case: str

@dataclass
class HotWalletFeature:
    """Represents a hot wallet feature"""
    feature: str
    description: str
    benefit: str
    risk: str

class HotWalletEngine:
    """Complete hot wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" HOT WALLET ENGINE")
        print("=" * 60)
    
    def explain_hot_wallet_overview(self) -> None:
        """Provide comprehensive hot wallet overview"""
        print("\n 🔥 HOT WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  HOT WALLETS - INTERNET-CONNECTED WALLETS                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Hot Wallet = Internet-connected wallet      │
│  Purpose: Convenient and fast access to crypto assets     │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Always online                                          │
│  ✓ Easy to use                                           │
│  ✓ Fast transactions                                      │
│  ✓ Lower security                                         │
│  ✓ Vulnerable to hacks                                    │
│  ✓ Integrated with dApps                                 │
│                                                           │
│  TYPES:                                                  │
│                                                           │
│  1. BROWSER EXTENSION                                    │
│     • MetaMask, Phantom, Keplr                           │
│     • Access dApps directly                              │
│     • Connected to browser                               │
│     • Higher phishing risk                               │
│                                                           │
│  2. MOBILE APP                                           │
│     • Trust Wallet, Coinbase Wallet                     │
│     • Always with you                                    │
│     • QR code scanning                                   │
│     • Mobile security risks                              │
│                                                           │
│  3. DESKTOP APP                                          │
│     • Exodus, Electrum                                  │
│     • More features                                      │
│     • Desktop security                                   │
│     • More control                                       │
│                                                           │
│  4. WEB-BASED                                            │
│     • Online wallets                                     │
│     • Exchange wallets                                   │
│     • Most convenient                                    │
│     • Highest risk                                       │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_hot_wallets(self) -> None:
        """List popular hot wallets"""
        print("\n 📊 POPULAR HOT WALLETS")
        print("-" * 40)
        
        wallets = [
            HotWallet(
                name="MetaMask",
                type=HotWalletType.BROWSER_EXTENSION,
                supported_chains=["Ethereum", "BSC", "Polygon", "Arbitrum"],
                security_level="Medium",
                convenience_score="Very High",
                risk_factors=["Phishing", "Malicious dApps", "Browser vulnerabilities"],
                best_use_case="DeFi, dApps, NFTs"
            ),
            HotWallet(
                name="Trust Wallet",
                type=HotWalletType.MOBILE_APP,
                supported_chains=["Ethereum", "BSC", "Solana", "Polygon"],
                security_level="Medium",
                convenience_score="High",
                risk_factors=["Mobile malware", "Phishing", "Device theft"],
                best_use_case="Mobile crypto, DeFi"
            ),
            HotWallet(
                name="Phantom",
                type=HotWalletType.BROWSER_EXTENSION,
                supported_chains=["Solana", "Ethereum", "Polygon"],
                security_level="Medium",
                convenience_score="Very High",
                risk_factors=["Phishing", "Solana-specific exploits"],
                best_use_case="Solana ecosystem, NFTs"
            ),
            HotWallet(
                name="Exodus",
                type=HotWalletType.DESKTOP_APP,
                supported_chains=["Bitcoin", "Ethereum", "Solana", "Cardano"],
                security_level="Medium-High",
                convenience_score="High",
                risk_factors=["Desktop malware", "Keylogging"],
                best_use_case="Multi-asset management"
            ),
            HotWallet(
                name="Coinbase Wallet",
                type=HotWalletType.MOBILE_APP,
                supported_chains=["Ethereum", "BSC", "Polygon", "Solana"],
                security_level="Medium",
                convenience_score="High",
                risk_factors=["Mobile risks", "Exchange integration"],
                best_use_case="Beginners, easy access"
            )
        ]
        
        print("\n📋 Hot Wallet Details:")
        print(f" {'Name':>15} | {'Type':>20} | {'Chains':>30} | {'Security':>15} | {'Convenience':>15}")
        print("-" * 100)
        
        for wallet in wallets:
            chains = ', '.join(wallet.supported_chains[:3])
            if len(wallet.supported_chains) > 3:
                chains += f" +{len(wallet.supported_chains)-3} more"
            
            print(f" {wallet.name[:15]:>15} | {wallet.type.value[:20]:>20} | "
                  f"{chains[:30]:>30} | {wallet.security_level[:15]:>15} | {wallet.convenience_score[:15]:>15}")
        
        print("\n📋 Risk Factors & Use Cases:")
        for wallet in wallets[:3]:
            print(f"  • {wallet.name}:")
            print(f"    Risks: {', '.join(wallet.risk_factors)}")
            print(f"    Best For: {wallet.best_use_case}")
    
    def explain_hot_wallet_security(self) -> None:
        """Explain hot wallet security considerations"""
        print("\n 🛡️  HOT WALLET SECURITY")
        print("-" * 40)
        
        security_considerations = {
            "Private Key Storage": {
                "description": "Keys stored encrypted on device",
                "risk": "Exposure if device compromised",
                "best_practice": "Hardware wallet integration"
            },
            "Phishing Attacks": {
                "description": "Fake websites and dApps",
                "risk": "Seed phrase theft",
                "best_practice": "Always verify URLs, use bookmarks"
            },
            "Malware Threats": {
                "description": "Keyloggers, clipboard hijackers",
                "risk": "Private key capture",
                "best_practice": "Keep antivirus updated"
            },
            "Device Security": {
                "description": "Device loss or theft",
                "risk": "Asset loss if no backup",
                "best_practice": "Strong passwords, encryption"
            },
            "dApp Permissions": {
                "description": "Unlimited token approvals",
                "risk": "Funds drained by malicious dApps",
                "best_practice": "Review permissions, revoke when done"
            }
        }
        
        print("\n📋 Security Considerations:")
        for risk, details in security_considerations.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Best Practice: {details['best_practice']}")
    
    def explain_hot_wallet_use_cases(self) -> None:
        """Explain hot wallet use cases"""
        print("\n 🎯 HOT WALLET USE CASES")
        print("-" * 40)
        
        use_cases = {
            "DeFi Trading": {
                "description": "Access to DEXs and lending protocols",
                "benefits": ["Quick transactions", "dApp integration", "Low fees"],
                "risks": ["Smart contract risk", "Impermanent loss"],
                "best_wallet": "MetaMask, Trust Wallet"
            },
            "NFT Collecting": {
                "description": "Buying, selling, and storing NFTs",
                "benefits": ["Marketplace integration", "Easy buying", "Gallery view"],
                "risks": ["NFT scams", "Phishing"],
                "best_wallet": "MetaMask, Phantom"
            },
            "Daily Spending": {
                "description": "Everyday crypto payments",
                "benefits": ["Convenience", "Speed", "Mobile access"],
                "risks": ["Loss if device stolen"],
                "best_wallet": "Trust Wallet, Coinbase Wallet"
            },
            "Gaming": {
                "description": "Blockchain game interactions",
                "benefits": ["Easy in-game transactions", "Asset management"],
                "risks": ["Game-specific risks"],
                "best_wallet": "MetaMask, Phantom"
            }
        }
        
        print("\n📋 Use Case Analysis:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Risks: {', '.join(details['risks'])}")
            print(f"    Best Wallet: {details['best_wallet']}")

class HotWalletAnalytics:
    """Additional analysis tools for hot wallets"""
    
    @staticmethod
    def compare_hot_vs_cold() -> None:
        """Compare hot wallets with cold wallets"""
        print("\n 📊 HOT VS COLD WALLET COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Security", "Convenience", "Speed", "Cost", "Best For"],
            "Hot Wallet": ["Medium", "Very High", "Fast", "Free", "Daily Use"],
            "Cold Wallet": ["Very High", "Low", "Slow", "$50-200", "Long-term Storage"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Hot Wallet':>25} | {'Cold Wallet':>25}")
        print("-" * 75)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            hot = comparison["Hot Wallet"][i]
            cold = comparison["Cold Wallet"][i]
            
            print(f" {attr:>20} | {hot:>25} | {cold:>25}")
    
    @staticmethod
    def analyze_hot_wallet_risks() -> None:
        """Analyze hot wallet risks in detail"""
        print("\n ⚠️  HOT WALLET RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Phishing Attacks": {
                "frequency": "High",
                "impact": "Critical (seed phrase theft)",
                "prevention": "Bookmark trusted sites, verify URLs"
            },
            "Malware Infections": {
                "frequency": "Medium",
                "impact": "High (keylogging, clipboard theft)",
                "prevention": "Antivirus, avoid suspicious downloads"
            },
            "Device Loss": {
                "frequency": "Medium",
                "impact": "Medium (if backed up)",
                "prevention": "Seed phrase backup, device tracking"
            },
            "Smart Contract Risk": {
                "frequency": "Low",
                "impact": "High (funds drained)",
                "prevention": "Audit contracts, revoke approvals"
            },
            "Zero-Day Exploits": {
                "frequency": "Low",
                "impact": "Critical (unpatched vulnerabilities)",
                "prevention": "Keep software updated"
            }
        }
        
        print("\n📋 Risk Assessment:")
        print(f" {'Risk':>20} | {'Frequency':>12} | {'Impact':>12} | {'Prevention':>30}")
        print("-" * 80)
        
        for risk, details in risks.items():
            print(f" {risk[:20]:>20} | {details['frequency']:>12} | {details['impact']:>12} | "
                  f"{details['prevention'][:30]:>30}")

def demonstrate_hot_wallet_engine():
    """Execute comprehensive hot wallet demonstration"""
    print("=" * 60)
    print(" HOT WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = HotWalletEngine()
    
    # Run demonstrations
    engine.explain_hot_wallet_overview()
    engine.list_hot_wallets()
    engine.explain_hot_wallet_security()
    engine.explain_hot_wallet_use_cases()
    
    # Additional analytics
    HotWalletAnalytics.compare_hot_vs_cold()
    HotWalletAnalytics.analyze_hot_wallet_risks()
    
    print("\n" + "=" * 60)
    print(" HOT WALLET SUMMARY:")
    print("   ✓ Hot Wallet = Internet-connected wallet")
    print("   ✓ Types: Browser, Mobile, Desktop, Web")
    print("   ✓ Popular: MetaMask, Trust Wallet, Phantom")
    print("   ✓ Security: Medium (vulnerable to hacks)")
    print("   ✓ Convenience: Very High (quick access)")
    print("   ✓ Best For: Daily use, DeFi, NFTs")
    print("   ✓ Risk: Phishing, malware, device loss")
    print("   ✓ Use for small amounts, cold for long-term")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_hot_wallet_engine()

5.3 Cold Wallets

What are Cold Wallets?

Cold wallets are cryptocurrency wallets that are not connected to the internet. They are the most secure way to store cryptocurrencies for long-term holding.

Cold Wallet Types:

TypeDescriptionExamples
Hardware WalletPhysical deviceLedger, Trezor
Paper WalletPrinted keysPaper, metal
Air-GappedOffline computerDedicated device

Code Example – Cold Wallets:

"""
COLD WALLET FRAMEWORK
======================
Complete cold wallet fundamentals and security analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class ColdWalletType(Enum):
    """Classification of cold wallet types"""
    HARDWARE = "Hardware Wallet"
    PAPER = "Paper Wallet"
    METAL = "Metal/Steel Wallet"
    AIR_GAPPED = "Air-Gapped Device"

@dataclass
class ColdWallet:
    """Represents a cold wallet with its properties"""
    name: str
    type: ColdWalletType
    supported_chains: List[str]
    security_level: str
    convenience_score: str
    cost: str
    best_use_case: str

@dataclass
class ColdWalletFeature:
    """Represents a cold wallet feature"""
    feature: str
    description: str
    benefit: str
    consideration: str

class ColdWalletEngine:
    """Complete cold wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" COLD WALLET ENGINE")
        print("=" * 60)
    
    def explain_cold_wallet_overview(self) -> None:
        """Provide comprehensive cold wallet overview"""
        print("\n 🧊 COLD WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  COLD WALLETS - OFFLINE STORAGE                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Cold Wallet = Offline key storage           │
│  Purpose: Maximum security for long-term asset storage    │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Maximum security                                       │
│  ✓ No internet connection                                 │
│  ✓ Immune to remote hacks                                 │
│  ✓ Private keys offline                                   │
│  ✓ Less convenient                                        │
│  ✓ Harder to access                                       │
│                                                           │
│  TYPES:                                                  │
│                                                           │
│  1. HARDWARE WALLET                                     │
│     • Ledger, Trezor, SafePal                            │
│     • Physical device                                     │
│     • PIN protected                                      │
│     • Transaction verification on device                │
│     • Most popular cold storage                          │
│                                                           │
│  2. PAPER WALLET                                        │
│     • Keys printed on paper                              │
│     • Generated offline                                  │
│     • Free/low cost                                      │
│     • No device needed                                   │
│     • Physical vulnerability                             │
│                                                           │
│  3. METAL/STEEL WALLET                                  │
│     • Fireproof backup                                   │
│     • Engraved seed phrase                               │
│     • Indestructible                                     │
│     • Higher cost                                        │
│     • Permanent backup                                   │
│                                                           │
│  4. AIR-GAPPED DEVICE                                   │
│     • Dedicated offline device                           │
│     • No network connection                              │
│     • Transaction signing offline                       │
│     • Highest security                                   │
│     • Expensive                                          │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_cold_wallets(self) -> None:
        """List popular cold wallets"""
        print("\n 📊 POPULAR COLD WALLETS")
        print("-" * 40)
        
        wallets = [
            ColdWallet(
                name="Ledger Nano X",
                type=ColdWalletType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "Solana", "Cardano", "Polkadot"],
                security_level="Very High",
                convenience_score="Medium",
                cost="$149",
                best_use_case="Multi-asset long-term storage"
            ),
            ColdWallet(
                name="Trezor Model T",
                type=ColdWalletType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "Litecoin", "Dash"],
                security_level="Very High",
                convenience_score="Medium",
                cost="$219",
                best_use_case="Bitcoin-focused storage"
            ),
            ColdWallet(
                name="Ledger Nano S",
                type=ColdWalletType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "Cardano"],
                security_level="Very High",
                convenience_score="Low-Medium",
                cost="$79",
                best_use_case="Budget hardware storage"
            ),
            ColdWallet(
                name="SafePal S1",
                type=ColdWalletType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "BSC", "Solana"],
                security_level="Very High",
                convenience_score="Medium",
                cost="$99",
                best_use_case="Binance ecosystem storage"
            ),
            ColdWallet(
                name="Paper Wallet",
                type=ColdWalletType.PAPER,
                supported_chains=["Bitcoin", "Ethereum"],
                security_level="High",
                convenience_score="Very Low",
                cost="Free",
                best_use_case="One-time gifts, simple storage"
            )
        ]
        
        print("\n📋 Cold Wallet Details:")
        print(f" {'Name':>15} | {'Type':>15} | {'Chains':>30} | {'Security':>15} | {'Cost':>12}")
        print("-" * 90)
        
        for wallet in wallets:
            chains = ', '.join(wallet.supported_chains[:3])
            if len(wallet.supported_chains) > 3:
                chains += f" +{len(wallet.supported_chains)-3} more"
            
            print(f" {wallet.name[:15]:>15} | {wallet.type.value[:15]:>15} | "
                  f"{chains[:30]:>30} | {wallet.security_level[:15]:>15} | {wallet.cost:>12}")
        
        print("\n📋 Best Use Cases:")
        for wallet in wallets:
            print(f"  • {wallet.name}: {wallet.best_use_case}")
    
    def explain_cold_wallet_security(self) -> None:
        """Explain cold wallet security best practices"""
        print("\n 🛡️  COLD WALLET SECURITY BEST PRACTICES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  COLD WALLET SECURITY                                    │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  SETUP:                                                  │
│  ✅ Set up in a secure, private environment              │
│  ✅ Never connect to compromised devices                 │
│  ✅ Use strong PIN (6+ digits)                          │
│  ✅ Verify transaction details on device screen         │
│  ✅ Store in a safe location                             │
│                                                           │
│  BACKUP:                                                 │
│  ✅ Backup seed phrase immediately                       │
│  ✅ Store backup in multiple locations                   │
│  ✅ Use fireproof/waterproof materials                   │
│  ✅ Test recovery process                                │
│  ✅ Never store seed digitally                           │
│                                                           │
│  USAGE:                                                  │
│  ✅ Only connect when needed                             │
│  ✅ Verify receiving address on device                   │
│  ✅ Use temporary wallets for daily use                  │
│  ✅ Keep firmware updated                                │
│  ✅ Use passphrase for extra security                    │
│                                                           │
│  WHAT NOT TO DO:                                         │
│  ❌ Never take photos of seed phrase                     │
│  ❌ Never type seed on computer                          │
│  ❌ Never connect to compromised devices                 │
│  ❌ Never share seed phrase with anyone                  │
│  ❌ Never lose your device backup                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_cold_wallet_comparison(self) -> None:
        """Explain cold wallet vs hot wallet comparison"""
        print("\n 📊 COLD VS HOT WALLET COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Security", "Convenience", "Speed", "Cost", "Accessibility", "Best For"],
            "Cold Wallet": ["⭐⭐⭐⭐⭐", "⭐⭐", "⭐⭐", "💰💰", "Limited", "Long-term Storage"],
            "Hot Wallet": ["⭐⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐⭐⭐⭐", "💰", "Always", "Daily Transactions"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>15} | {'Cold Wallet':>25} | {'Hot Wallet':>25}")
        print("-" * 70)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            cold = comparison["Cold Wallet"][i]
            hot = comparison["Hot Wallet"][i]
            
            print(f" {attr:>15} | {cold:>25} | {hot:>25}")
    
    def explain_cold_wallet_use_cases(self) -> None:
        """Explain cold wallet use cases"""
        print("\n 🎯 COLD WALLET USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Long-term Holdings": {
                "description": "Store assets for years without access",
                "benefits": ["Maximum security", "No hacking risk", "Peace of mind"],
                "recommendation": "Hardware wallet with steel backup"
            },
            "Institutional Storage": {
                "description": "Enterprise-grade secure storage",
                "benefits": ["Multi-sig support", "Audit trail", "Compliance"],
                "recommendation": "Multi-hardware wallet setup"
            },
            "Legacy Planning": {
                "description": "Passing assets to heirs",
                "benefits": ["Secure inheritance", "Simple recovery", "Durable storage"],
                "recommendation": "Steel wallet with clear instructions"
            },
            "Large Transactions": {
                "description": "Infrequent, high-value transfers",
                "benefits": ["Transaction verification", "Signature verification"],
                "recommendation": "Hardware wallet with screen"
            }
        }
        
        print("\n📋 Use Case Analysis:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Recommendation: {details['recommendation']}")

class ColdWalletAnalytics:
    """Additional analysis tools for cold wallets"""
    
    @staticmethod
    def compare_hardware_wallets() -> None:
        """Compare popular hardware wallets"""
        print("\n 📊 HARDWARE WALLET COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Screen", "Bluetooth", "Touchscreen", "Supported Coins", "Price"],
            "Ledger Nano S": ["Yes", "No", "No", "1000+", "$79"],
            "Ledger Nano X": ["Yes", "Yes", "No", "1500+", "$149"],
            "Trezor Model T": ["Yes", "No", "Yes", "1000+", "$219"],
            "SafePal S1": ["Yes", "Yes", "No", "1000+", "$99"]
        }
        
        print("\n📋 Hardware Wallet Comparison:")
        print(f" {'Attribute':>15} | {'Nano S':>15} | {'Nano X':>15} | {'Model T':>15} | {'SafePal':>15}")
        print("-" * 80)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            nano_s = comparison["Ledger Nano S"][i]
            nano_x = comparison["Ledger Nano X"][i]
            model_t = comparison["Trezor Model T"][i]
            safepal = comparison["SafePal S1"][i]
            
            print(f" {attr[:15]:>15} | {nano_s:>15} | {nano_x:>15} | {model_t:>15} | {safepal:>15}")
    
    @staticmethod
    def analyze_cold_wallet_risks() -> None:
        """Analyze cold wallet risks"""
        print("\n ⚠️  COLD WALLET RISK ANALYSIS")
        print("-" * 40)
        
        risks = {
            "Physical Loss": {
                "description": "Device or paper backup lost/destroyed",
                "impact": "Funds inaccessible",
                "mitigation": "Multiple backups in different locations"
            },
            "Theft": {
                "description": "Physical device stolen",
                "impact": "Funds if PIN not compromised",
                "mitigation": "PIN protection, passphrase"
            },
            "Fire/Water Damage": {
                "description": "Natural disasters",
                "impact": "Backup destruction",
                "mitigation": "Metal wallets, multiple backups"
            },
            "Human Error": {
                "description": "Wrong transaction, lost seed",
                "impact": "Funds loss",
                "mitigation": "Double-check transactions, test recovery"
            },
            "Supply Chain Attack": {
                "description": "Device tampered before delivery",
                "impact": "Potential compromise",
                "mitigation": "Buy from official source, verify device"
            }
        }
        
        print("\n📋 Risk Assessment:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

def demonstrate_cold_wallet_engine():
    """Execute comprehensive cold wallet demonstration"""
    print("=" * 60)
    print(" COLD WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = ColdWalletEngine()
    
    # Run demonstrations
    engine.explain_cold_wallet_overview()
    engine.list_cold_wallets()
    engine.explain_cold_wallet_security()
    engine.explain_cold_wallet_comparison()
    engine.explain_cold_wallet_use_cases()
    
    # Additional analytics
    ColdWalletAnalytics.compare_hardware_wallets()
    ColdWalletAnalytics.analyze_cold_wallet_risks()
    
    print("\n" + "=" * 60)
    print(" COLD WALLET SUMMARY:")
    print("   ✓ Cold Wallet = Offline storage")
    print("   ✓ Types: Hardware, Paper, Metal, Air-Gapped")
    print("   ✓ Popular: Ledger, Trezor, SafePal")
    print("   ✓ Security: Maximum (immune to remote hacks)")
    print("   ✓ Convenience: Low (requires device connection)")
    print("   ✓ Best For: Long-term storage, large holdings")
    print("   ✓ Risk: Physical loss, theft, human error")
    print("   ✓ Recommendation: Hardware wallet + steel backup")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_cold_wallet_engine()

5.4 Hardware Wallets

What are Hardware Wallets?

Hardware wallets are physical devices that store private keys securely offline. They are the most secure way to store cryptocurrency for long-term holding.

Popular Hardware Wallets:

WalletSecurity LevelPriceSupported Coins
Ledger Nano XVery High$1491,000+
Ledger Nano SVery High$591,000+
Trezor Model TVery High$2191,000+

Code Example – Hardware Wallets:

"""
HARDWARE WALLET FRAMEWORK
==========================
Complete hardware wallet fundamentals and security analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class HardwareWalletModel(Enum):
    """Classification of hardware wallet models"""
    LEDGER_NANO_S = "Ledger Nano S"
    LEDGER_NANO_X = "Ledger Nano X"
    LEDGER_STAX = "Ledger Stax"
    TREZOR_ONE = "Trezor One"
    TREZOR_MODEL_T = "Trezor Model T"
    SAFEPAL_S1 = "SafePal S1"
    KEEPKEY = "KeepKey"

@dataclass
class HardwareWallet:
    """Represents a hardware wallet with its properties"""
    name: str
    model: HardwareWalletModel
    connectivity: List[str]
    screen_type: str
    supported_coins: str
    price: str
    security_features: List[str]
    best_for: str

@dataclass
class HardwareWalletFeature:
    """Represents a hardware wallet feature"""
    feature: str
    description: str
    security_benefit: str
    usage_benefit: str

class HardwareWalletEngine:
    """Complete hardware wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" HARDWARE WALLET ENGINE")
        print("=" * 60)
    
    def explain_hardware_overview(self) -> None:
        """Provide comprehensive hardware wallet overview"""
        print("\n 🏷️  HARDWARE WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  HARDWARE WALLETS - PHYSICAL SECURITY DEVICES            │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Hardware Wallet = Physical security device  │
│  Purpose: Secure private keys offline for crypto assets   │
│                                                           │
│  KEY FEATURES:                                           │
│  ✓ Private key stored offline                             │
│  ✓ PIN protection                                         │
│  ✓ Recovery phrase (24 words)                            │
│  ✓ Multi-coin support                                     │
│  ✓ Transaction verification on device                    │
│  ✓ Secure element chip                                    │
│  ✓ Open source firmware (some)                           │
│                                                           │
│  TOP HARDWARE WALLETS:                                   │
│                                                           │
│  1. LEDGER NANO X                                       │
│     • Bluetooth connectivity                             │
│     • 1,500+ coins                                       │
│     • OLED screen                                        │
│     • Price: $149                                        │
│     • Best for: Mobile + Desktop                         │
│                                                           │
│  2. LEDGER NANO S                                       │
│     • USB connectivity                                   │
│     • 1,000+ coins                                       │
│     • OLED screen                                        │
│     • Price: $79                                         │
│     • Best for: Budget option                            │
│                                                           │
│  3. TREZOR MODEL T                                      │
│     • Touchscreen                                        │
│     • 1,000+ coins                                       │
│     • Color screen                                       │
│     • Price: $219                                        │
│     • Best for: Touchscreen interface                    │
│                                                           │
│  4. SAFEPAL S1                                          │
│     • Bluetooth connectivity                             │
│     • 1,000+ coins                                       │
│     • Color screen                                       │
│     • Price: $99                                         │
│     • Best for: Binance ecosystem                        │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_hardware_wallets(self) -> None:
        """List popular hardware wallets"""
        print("\n 📊 POPULAR HARDWARE WALLETS")
        print("-" * 40)
        
        wallets = [
            HardwareWallet(
                name="Ledger Nano X",
                model=HardwareWalletModel.LEDGER_NANO_X,
                connectivity=["USB", "Bluetooth"],
                screen_type="OLED",
                supported_coins="1,500+",
                price="$149",
                security_features=["Secure Element", "PIN", "Recovery Phrase"],
                best_for="Mobile and desktop users"
            ),
            HardwareWallet(
                name="Ledger Nano S",
                model=HardwareWalletModel.LEDGER_NANO_S,
                connectivity=["USB"],
                screen_type="OLED",
                supported_coins="1,000+",
                price="$79",
                security_features=["Secure Element", "PIN", "Recovery Phrase"],
                best_for="Budget-conscious users"
            ),
            HardwareWallet(
                name="Trezor Model T",
                model=HardwareWalletModel.TREZOR_MODEL_T,
                connectivity=["USB"],
                screen_type="Color Touchscreen",
                supported_coins="1,000+",
                price="$219",
                security_features=["Open Source", "PIN", "Recovery Phrase"],
                best_for="Touchscreen preference"
            ),
            HardwareWallet(
                name="SafePal S1",
                model=HardwareWalletModel.SAFEPAL_S1,
                connectivity=["USB", "Bluetooth"],
                screen_type="Color",
                supported_coins="1,000+",
                price="$99",
                security_features=["Secure Element", "PIN", "Recovery Phrase"],
                best_for="Binance ecosystem users"
            ),
            HardwareWallet(
                name="KeepKey",
                model=HardwareWalletModel.KEEPKEY,
                connectivity=["USB"],
                screen_type="OLED",
                supported_coins="40+",
                price="$49",
                security_features=["PIN", "Recovery Phrase"],
                best_for="Basic users"
            )
        ]
        
        print("\n📋 Hardware Wallet Details:")
        print(f" {'Name':>15} | {'Connectivity':>20} | {'Screen':>15} | {'Coins':>12} | {'Price':>12}")
        print("-" * 80)
        
        for wallet in wallets:
            conn = ', '.join(wallet.connectivity)
            print(f" {wallet.name[:15]:>15} | {conn[:20]:>20} | {wallet.screen_type[:15]:>15} | "
                  f"{wallet.supported_coins[:12]:>12} | {wallet.price:>12}")
        
        print("\n📋 Best Use Cases:")
        for wallet in wallets:
            print(f"  • {wallet.name}: {wallet.best_for}")
    
    def explain_hardware_security(self) -> None:
        """Explain hardware wallet security features"""
        print("\n 🛡️  HARDWARE WALLET SECURITY")
        print("-" * 40)
        
        security_features = {
            "Secure Element Chip": {
                "description": "Dedicated chip for key storage",
                "benefit": "Keys never leave the chip",
                "protection": "Hardware-level security"
            },
            "PIN Protection": {
                "description": "Device access PIN",
                "benefit": "Physical security",
                "protection": "Theft protection"
            },
            "Recovery Phrase": {
                "description": "24-word backup phrase",
                "benefit": "Device replacement option",
                "protection": "Disaster recovery"
            },
            "Transaction Verification": {
                "description": "Screen displays transaction details",
                "benefit": "Confirm before signing",
                "protection": "Anti-tamper protection"
            },
            "Passphrase": {
                "description": "Additional 25th word",
                "benefit": "Hidden wallets",
                "protection": "Duress protection"
            }
        }
        
        print("\n📋 Security Features:")
        for feature, details in security_features.items():
            print(f"\n  {feature}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Protection: {details['protection']}")
    
    def explain_hardware_usage(self) -> None:
        """Explain hardware wallet usage"""
        print("\n 🔧 HARDWARE WALLET USAGE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  HARDWARE WALLET USAGE GUIDE                             │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  SETUP:                                                  │
│  1. Unbox and connect device                              │
│  2. Install companion app (Ledger Live, Trezor Suite)   │
│  3. Initialize device (new or recovery)                 │
│  4. Set PIN code                                          │
│  5. Write down 24-word recovery phrase                   │
│  6. Install apps for cryptocurrencies                    │
│                                                           │
│  SENDING TRANSACTIONS:                                  │
│  1. Open companion app                                   │
│  2. Create transaction                                    │
│  3. Review on device screen                              │
│  4. Approve with button press                            │
│  5. Transaction signed and broadcasted                   │
│                                                           │
│  RECEIVING:                                              │
│  1. Open companion app                                   │
│  2. Generate receive address                             │
│  3. Verify address on device screen                      │
│  4. Share with sender                                    │
│                                                           │
│  MAINTENANCE:                                            │
│  • Keep firmware updated                                 │
│  • Never share seed phrase                               │
│  • Store seed phrase securely                            │
│  • Test recovery process                                 │
└─────────────────────────────────────────────────────────────┘
        """)

class HardwareWalletAnalytics:
    """Additional analysis tools for hardware wallets"""
    
    @staticmethod
    def compare_hardware_models() -> None:
        """Compare hardware wallet models"""
        print("\n 📊 HARDWARE MODEL COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Price", "Connectivity", "Screen", "Coin Support", "Bluetooth"],
            "Nano S": ["$79", "USB", "OLED", "1,000+", "❌"],
            "Nano X": ["$149", "USB+BT", "OLED", "1,500+", "✅"],
            "Model T": ["$219", "USB", "Touchscreen", "1,000+", "❌"],
            "SafePal": ["$99", "USB+BT", "Color", "1,000+", "✅"]
        }
        
        print("\n📋 Model Comparison:")
        print(f" {'Attribute':>15} | {'Nano S':>15} | {'Nano X':>15} | {'Model T':>15} | {'SafePal':>15}")
        print("-" * 80)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            nano_s = comparison["Nano S"][i]
            nano_x = comparison["Nano X"][i]
            model_t = comparison["Model T"][i]
            safepal = comparison["SafePal"][i]
            
            print(f" {attr[:15]:>15} | {nano_s:>15} | {nano_x:>15} | {model_t:>15} | {safepal:>15}")
    
    @staticmethod
    def analyze_security_ratings() -> None:
        """Analyze hardware wallet security ratings"""
        print("\n 📈 SECURITY RATINGS")
        print("-" * 40)
        
        ratings = {
            "Wallet": ["Ledger", "Trezor", "SafePal", "KeepKey"],
            "Secure Element": ["✅ Yes", "❌ No", "✅ Yes", "❌ No"],
            "Open Source": ["❌ No", "✅ Yes", "✅ Yes", "✅ Yes"],
            "PIN": ["✅ Yes", "✅ Yes", "✅ Yes", "✅ Yes"],
            "Passphrase": ["✅ Yes", "✅ Yes", "✅ Yes", "✅ Yes"],
            "Overall Security": ["⭐⭐⭐⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐⭐⭐"]
        }
        
        print("\n📋 Security Ratings:")
        print(f" {'Wallet':>15} | {'Secure Element':>18} | {'Open Source':>15} | {'PIN':>10} | {'Passphrase':>15} | {'Overall':>15}")
        print("-" * 95)
        
        for i in range(len(ratings["Wallet"])):
            wallet = ratings["Wallet"][i]
            se = ratings["Secure Element"][i]
            os = ratings["Open Source"][i]
            pin = ratings["PIN"][i]
            passphrase = ratings["Passphrase"][i]
            overall = ratings["Overall Security"][i]
            
            print(f" {wallet:>15} | {se:>18} | {os:>15} | {pin:>10} | {passphrase:>15} | {overall:>15}")

def demonstrate_hardware_wallet_engine():
    """Execute comprehensive hardware wallet demonstration"""
    print("=" * 60)
    print(" HARDWARE WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = HardwareWalletEngine()
    
    # Run demonstrations
    engine.explain_hardware_overview()
    engine.list_hardware_wallets()
    engine.explain_hardware_security()
    engine.explain_hardware_usage()
    
    # Additional analytics
    HardwareWalletAnalytics.compare_hardware_models()
    HardwareWalletAnalytics.analyze_security_ratings()
    
    print("\n" + "=" * 60)
    print(" HARDWARE WALLET SUMMARY:")
    print("   ✓ Hardware Wallet = Physical security device")
    print("   ✓ Top Models: Ledger, Trezor, SafePal")
    print("   ✓ Security: Secure element, PIN, recovery phrase")
    print("   ✓ Private Keys Never Leave Device")
    print("   ✓ Benefits: Maximum security, multi-coin support")
    print("   ✓ Price Range: $79 - $219")
    print("   ✓ Best For: Long-term storage, large holdings")
    print("   ✓ Recommendation: Ledger Nano X or Trezor Model T")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_hardware_wallet_engine()

5.5 Custodial Wallets

What are Custodial Wallets?

Custodial wallets are wallets where a third party (exchange or custodian) holds the private keys on behalf of the user. The user trusts the custodian to secure the funds.

Custodial Wallet Examples:

CustodianTypeFeatures
CoinbaseExchangeRegulated, insured
BinanceExchangeLarge, low fees
PayPalPaymentEasy, integrated

Code Example – Custodial Wallets:

"""
CUSTODIAL WALLET FRAMEWORK
===========================
Complete custodial wallet fundamentals and risk analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class CustodialProvider(Enum):
    """Classification of custodial providers"""
    EXCHANGE = "Exchange"
    INSTITUTIONAL = "Institutional Custodian"
    PAYMENT = "Payment Provider"
    BROKER = "Brokerage"

@dataclass
class CustodialWallet:
    """Represents a custodial wallet with its properties"""
    name: str
    provider_type: CustodialProvider
    supported_assets: List[str]
    security_level: str
    convenience_score: str
    fees: str
    insurance: str
    best_for: str

@dataclass
class CustodialRisk:
    """Represents a custodial risk"""
    risk_type: str
    description: str
    impact: str
    mitigation: str

class CustodialWalletEngine:
    """Complete custodial wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" CUSTODIAL WALLET ENGINE")
        print("=" * 60)
    
    def explain_custodial_overview(self) -> None:
        """Provide comprehensive custodial wallet overview"""
        print("\n 🏦 CUSTODIAL WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  CUSTODIAL WALLETS - THIRD-PARTY CUSTODY                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Custodial Wallet = Third-party holds keys   │
│  Purpose: Convenient access to crypto without key mgmt   │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Easy to use                                            │
│  ✓ No key management                                      │
│  ✓ Backup and recovery                                    │
│  ✓ Customer support                                       │
│  ✓ Regulatory compliance                                  │
│  ✓ Insurance (some)                                      │
│                                                           │
│  KEY CONCEPT:                                            │
│  "Not your keys, not your crypto"                        │
│                                                           │
│  TYPES OF PROVIDERS:                                     │
│                                                           │
│  1. EXCHANGES                                           │
│     • Coinbase, Binance, Kraken                         │
│     • Most common                                        │
│     • Trading focus                                      │
│     • High liquidity                                     │
│                                                           │
│  2. INSTITUTIONAL CUSTODIANS                            │
│     • Coinbase Custody, BitGo, Gemini                  │
│     • Enterprise focus                                   │
│     • Higher security                                    │
│     • Insurance coverage                                 │
│                                                           │
│  3. PAYMENT PROVIDERS                                   │
│     • PayPal, CashApp, Venmo                           │
│     • Consumer focus                                    │
│     • Simple interface                                   │
│     • Limited crypto                                    │
│                                                           │
│  4. BROKERAGES                                          │
│     • Robinhood, eToro                                  │
│     • Traditional investors                              │
│     • Easy onboarding                                   │
│     • Limited features                                  │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_custodial_providers(self) -> None:
        """List popular custodial providers"""
        print("\n 📊 POPULAR CUSTODIAL PROVIDERS")
        print("-" * 40)
        
        providers = [
            CustodialWallet(
                name="Coinbase",
                provider_type=CustodialProvider.EXCHANGE,
                supported_assets=["Bitcoin", "Ethereum", "Solana", "Cardano", "USDC"],
                security_level="High",
                convenience_score="Very High",
                fees="0.5-4.5%",
                insurance="Yes (hot wallet)",
                best_for="Beginners, buying"
            ),
            CustodialWallet(
                name="Binance",
                provider_type=CustodialProvider.EXCHANGE,
                supported_assets=["Bitcoin", "Ethereum", "BNB", "Solana", "Cardano"],
                security_level="High",
                convenience_score="Very High",
                fees="0.1-0.5%",
                insurance="Yes (SAFU)",
                best_for="Trading, low fees"
            ),
            CustodialWallet(
                name="Kraken",
                provider_type=CustodialProvider.EXCHANGE,
                supported_assets=["Bitcoin", "Ethereum", "Cardano", "Polkadot"],
                security_level="Very High",
                convenience_score="High",
                fees="0.2-0.5%",
                insurance="Yes",
                best_for="Security, staking"
            ),
            CustodialWallet(
                name="BitGo",
                provider_type=CustodialProvider.INSTITUTIONAL,
                supported_assets=["Bitcoin", "Ethereum", "Solana", "Cardano", "Polkadot"],
                security_level="Very High",
                convenience_score="Medium",
                fees="Institutional",
                insurance="Yes (up to $250M)",
                best_for="Institutions, large holdings"
            ),
            CustodialWallet(
                name="PayPal",
                provider_type=CustodialProvider.PAYMENT,
                supported_assets=["Bitcoin", "Ethereum", "Litecoin", "Bitcoin Cash"],
                security_level="High",
                convenience_score="Very High",
                fees="1.5-2.5%",
                insurance="Yes",
                best_for="Consumers, easy access"
            )
        ]
        
        print("\n📋 Custodial Providers:")
        print(f" {'Name':>15} | {'Type':>20} | {'Assets':>25} | {'Security':>15} | {'Fees':>12}")
        print("-" * 90)
        
        for provider in providers:
            assets = ', '.join(provider.supported_assets[:3])
            if len(provider.supported_assets) > 3:
                assets += f" +{len(provider.supported_assets)-3} more"
            
            print(f" {provider.name[:15]:>15} | {provider.provider_type.value[:20]:>20} | "
                  f"{assets[:25]:>25} | {provider.security_level[:15]:>15} | {provider.fees:>12}")
        
        print("\n📋 Best For:")
        for provider in providers:
            print(f"  • {provider.name}: {provider.best_for}")
    
    def explain_custodial_risks(self) -> None:
        """Explain custodial wallet risks"""
        print("\n ⚠️  CUSTODIAL WALLET RISKS")
        print("-" * 40)
        
        risks = [
            CustodialRisk(
                risk_type="Hacking Risk",
                description="Exchange could be hacked",
                impact="Funds stolen",
                mitigation="Use reputable exchanges, 2FA, withdraw"
            ),
            CustodialRisk(
                risk_type="Counterparty Risk",
                description="Exchange could go bankrupt",
                impact="Funds frozen or lost",
                mitigation="Only keep trading funds on exchange"
            ),
            CustodialRisk(
                risk_type="Regulatory Risk",
                description="Government actions against exchange",
                impact="Account frozen, assets seized",
                mitigation="Diversify across providers"
            ),
            CustodialRisk(
                risk_type="Access Risk",
                description="Account could be frozen",
                impact="Unable to access funds",
                mitigation="Use non-custodial wallets"
            ),
            CustodialRisk(
                risk_type="Internal Fraud",
                description="Exchange employees could steal",
                impact="Funds lost",
                mitigation="Use audited exchanges"
            )
        ]
        
        print("\n📋 Risk Assessment:")
        print(f" {'Risk Type':>20} | {'Description':>30} | {'Impact':>20} | {'Mitigation':>30}")
        print("-" * 105)
        
        for risk in risks:
            print(f" {risk.risk_type[:20]:>20} | {risk.description[:30]:>30} | "
                  f"{risk.impact[:20]:>20} | {risk.mitigation[:30]:>30}")
    
    def explain_custodial_use_cases(self) -> None:
        """Explain custodial wallet use cases"""
        print("\n 🎯 CUSTODIAL WALLET USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Trading": {
                "description": "Buy, sell, and trade crypto",
                "benefits": ["High liquidity", "Easy execution", "Various pairs"],
                "recommendation": "Only keep trading funds"
            },
            "Onboarding": {
                "description": "New users entering crypto",
                "benefits": ["Simple interface", "Fiat on-ramp", "Customer support"],
                "recommendation": "Start with reputable exchange"
            },
            "Institutional Storage": {
                "description": "Enterprise-grade custody",
                "benefits": ["Insurance", "Compliance", "Multi-sig"],
                "recommendation": "Use institutional custodians"
            },
            "Daily Spending": {
                "description": "Everyday crypto transactions",
                "benefits": ["Convenience", "Payment integration"],
                "recommendation": "Use payment providers"
            }
        }
        
        print("\n📋 Use Case Analysis:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")
            print(f"    Recommendation: {details['recommendation']}")

class CustodialAnalytics:
    """Additional analysis tools for custodial wallets"""
    
    @staticmethod
    def compare_custodial_vs_non_custodial() -> None:
        """Compare custodial and non-custodial wallets"""
        print("\n 📊 CUSTODIAL VS NON-CUSTODIAL")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Key Control", "Security", "Convenience", "Recovery", "Fees", "Best For"],
            "Custodial": ["Third-party", "Medium-High", "Very High", "Provider", "Variable", "Trading/Onboarding"],
            "Non-Custodial": ["User", "User-dependent", "Medium", "Self-managed", "Low", "Long-term Storage"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Custodial':>25} | {'Non-Custodial':>25}")
        print("-" * 75)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            custodial = comparison["Custodial"][i]
            non_custodial = comparison["Non-Custodial"][i]
            
            print(f" {attr:>20} | {custodial:>25} | {non_custodial:>25}")
    
    @staticmethod
    def analyze_custodial_history() -> None:
        """Analyze custodial wallet history"""
        print("\n 📈 CUSTODIAL WALLET HISTORY")
        print("-" * 40)
        
        history = {
            "Event": [
                "Mt. Gox Hack",
                "Bitfinex Hack",
                "Coincheck Hack",
                "QuadrigaCX Collapse",
                "FTX Collapse"
            ],
            "Year": [
                "2014",
                "2016",
                "2018",
                "2019",
                "2022"
            ],
            "Loss": [
                "850,000 BTC ($450M)",
                "119,756 BTC ($72M)",
                "523M NEM ($530M)",
                "$190M",
                "$8B"
            ],
            "Lesson": [
                "Not your keys, not your crypto",
                "Need cold storage",
                "Security matters",
                "Verify reserves",
                "Don't trust, verify"
            ]
        }
        
        print("\n📋 Historical Events:")
        print(f" {'Event':>20} | {'Year':>8} | {'Loss':>20} | {'Lesson':>40}")
        print("-" * 95)
        
        for i in range(len(history["Event"])):
            event = history["Event"][i]
            year = history["Year"][i]
            loss = history["Loss"][i]
            lesson = history["Lesson"][i]
            
            print(f" {event[:20]:>20} | {year:>8} | {loss[:20]:>20} | {lesson[:40]:>40}")

def demonstrate_custodial_wallet_engine():
    """Execute comprehensive custodial wallet demonstration"""
    print("=" * 60)
    print(" CUSTODIAL WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = CustodialWalletEngine()
    
    # Run demonstrations
    engine.explain_custodial_overview()
    engine.list_custodial_providers()
    engine.explain_custodial_risks()
    engine.explain_custodial_use_cases()
    
    # Additional analytics
    CustodialAnalytics.compare_custodial_vs_non_custodial()
    CustodialAnalytics.analyze_custodial_history()
    
    print("\n" + "=" * 60)
    print(" CUSTODIAL WALLET SUMMARY:")
    print("   ✓ Custodial Wallet = Third-party holds keys")
    print("   ✓ Types: Exchange, Institutional, Payment, Brokerage")
    print("   ✓ Popular: Coinbase, Binance, Kraken")
    print("   ✓ Benefit: Convenient, easy recovery")
    print("   ✓ Risk: Hacking, counterparty, regulation")
    print("   ✓ Principle: Not your keys, not your crypto")
    print("   ✓ Use for trading, not long-term storage")
    print("   ✓ Withdraw to non-custodial for safety")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_custodial_wallet_engine()

5.6 Non-Custodial Wallets

What are Non-Custodial Wallets?

Non-custodial wallets (self-custody) are wallets where the user controls their private keys. The user is responsible for securely managing and protecting their funds and wallet credentials.

Non-Custodial Wallet Examples:

WalletTypeFeatures
MetaMaskBrowserdApp integration
Trust WalletMobileMulti-chain
LedgerHardwareCold storage

Code Example – Non-Custodial Wallets:

"""
NON-CUSTODIAL WALLET FRAMEWORK
===============================
Complete non-custodial wallet fundamentals and security analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class NonCustodialType(Enum):
    """Classification of non-custodial wallet types"""
    HOT = "Hot Wallet"
    COLD = "Cold Wallet"
    HARDWARE = "Hardware Wallet"
    PAPER = "Paper Wallet"

@dataclass
class NonCustodialWallet:
    """Represents a non-custodial wallet with its properties"""
    name: str
    wallet_type: NonCustodialType
    supported_chains: List[str]
    security_level: str
    user_control: str
    difficulty: str
    best_for: str

@dataclass
class NonCustodialFeature:
    """Represents a non-custodial wallet feature"""
    feature: str
    description: str
    benefit: str
    responsibility: str

class NonCustodialWalletEngine:
    """Complete non-custodial wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" NON-CUSTODIAL WALLET ENGINE")
        print("=" * 60)
    
    def explain_non_custodial_overview(self) -> None:
        """Provide comprehensive non-custodial wallet overview"""
        print("\n 🔑 NON-CUSTODIAL WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  NON-CUSTODIAL WALLETS - SELF-CUSTODY                   │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Non-Custodial = User controls private keys  │
│  Purpose: Full ownership and control of assets           │
│                                                           │
│  CORE PRINCIPLE:                                         │
│  "Not your keys, not your crypto"                        │
│                                                           │
│  CHARACTERISTICS:                                        │
│  ✓ Full control of private keys                          │
│  ✓ No third-party risk                                   │
│  ✓ Privacy-focused                                       │
│  ✓ Censorship-resistant                                  │
│  ✓ Self-responsibility                                   │
│  ✓ No recovery option                                    │
│                                                           │
│  TYPES:                                                  │
│                                                           │
│  1. HOT WALLETS                                         │
│     • MetaMask, Trust Wallet, Phantom                   │
│     • Internet-connected                                 │
│     • Convenient for daily use                          │
│     • Higher risk                                        │
│                                                           │
│  2. HARDWARE WALLETS                                    │
│     • Ledger, Trezor, SafePal                           │
│     • Offline storage                                    │
│     • Maximum security                                   │
│     • Physical device                                    │
│                                                           │
│  3. PAPER WALLETS                                       │
│     • Printed keys                                       │
│     • Offline generation                                 │
│     • Free/low cost                                      │
│     • Physical vulnerability                            │
│                                                           │
│  4. MOBILE WALLETS                                      │
│     • Trust Wallet, Coinbase Wallet                    │
│     • Smartphone-based                                  │
│     • Always accessible                                 │
│     • Mobile risks                                      │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_non_custodial_wallets(self) -> None:
        """List popular non-custodial wallets"""
        print("\n 📊 POPULAR NON-CUSTODIAL WALLETS")
        print("-" * 40)
        
        wallets = [
            NonCustodialWallet(
                name="MetaMask",
                wallet_type=NonCustodialType.HOT,
                supported_chains=["Ethereum", "BSC", "Polygon", "Arbitrum"],
                security_level="Medium",
                user_control="Full",
                difficulty="Easy",
                best_for="DeFi, dApps, NFTs"
            ),
            NonCustodialWallet(
                name="Trust Wallet",
                wallet_type=NonCustodialType.HOT,
                supported_chains=["Ethereum", "BSC", "Solana", "Polygon"],
                security_level="Medium",
                user_control="Full",
                difficulty="Easy",
                best_for="Mobile crypto, DeFi"
            ),
            NonCustodialWallet(
                name="Ledger Nano X",
                wallet_type=NonCustodialType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "Solana", "Cardano"],
                security_level="Very High",
                user_control="Full",
                difficulty="Medium",
                best_for="Long-term storage, large holdings"
            ),
            NonCustodialWallet(
                name="Trezor Model T",
                wallet_type=NonCustodialType.HARDWARE,
                supported_chains=["Bitcoin", "Ethereum", "Litecoin", "Dash"],
                security_level="Very High",
                user_control="Full",
                difficulty="Medium",
                best_for="Bitcoin-focused storage"
            ),
            NonCustodialWallet(
                name="Exodus",
                wallet_type=NonCustodialType.HOT,
                supported_chains=["Bitcoin", "Ethereum", "Solana", "Cardano"],
                security_level="Medium-High",
                user_control="Full",
                difficulty="Easy",
                best_for="Multi-asset desktop"
            ),
            NonCustodialWallet(
                name="Phantom",
                wallet_type=NonCustodialType.HOT,
                supported_chains=["Solana", "Ethereum", "Polygon"],
                security_level="Medium",
                user_control="Full",
                difficulty="Easy",
                best_for="Solana ecosystem"
            )
        ]
        
        print("\n📋 Non-Custodial Wallets:")
        print(f" {'Name':>15} | {'Type':>15} | {'Chains':>30} | {'Security':>15} | {'Difficulty':>12}")
        print("-" * 90)
        
        for wallet in wallets:
            chains = ', '.join(wallet.supported_chains[:3])
            if len(wallet.supported_chains) > 3:
                chains += f" +{len(wallet.supported_chains)-3} more"
            
            print(f" {wallet.name[:15]:>15} | {wallet.wallet_type.value[:15]:>15} | "
                  f"{chains[:30]:>30} | {wallet.security_level[:15]:>15} | {wallet.difficulty[:12]:>12}")
        
        print("\n📋 Best Use Cases:")
        for wallet in wallets:
            print(f"  • {wallet.name}: {wallet.best_for}")
    
    def explain_non_custodial_responsibilities(self) -> None:
        """Explain user responsibilities"""
        print("\n 👤 USER RESPONSIBILITIES")
        print("-" * 40)
        
        responsibilities = {
            "Seed Phrase Backup": {
                "description": "Store 12-24 word recovery phrase",
                "risk": "Lost phrase = Lost funds",
                "best_practice": "Steel backup, multiple locations"
            },
            "Private Key Security": {
                "description": "Keep private keys secure",
                "risk": "Compromised key = Stolen funds",
                "best_practice": "Hardware wallet, never digital"
            },
            "Transaction Verification": {
                "description": "Check transaction details",
                "risk": "Wrong address or amount",
                "best_practice": "Double-check addresses"
            },
            "Device Security": {
                "description": "Secure device from malware",
                "risk": "Keylogger, clipboard hijack",
                "best_practice": "Antivirus, updates"
            },
            "Recovery Testing": {
                "description": "Test recovery process",
                "risk": "Unable to recover",
                "best_practice": "Test with small amount"
            }
        }
        
        print("\n📋 Responsibilities:")
        for responsibility, details in responsibilities.items():
            print(f"\n  {responsibility}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Best Practice: {details['best_practice']}")
    
    def explain_non_custodial_advantages(self) -> None:
        """Explain advantages of non-custodial wallets"""
        print("\n 💎 NON-CUSTODIAL ADVANTAGES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  NON-CUSTODIAL ADVANTAGES                                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  TRUE OWNERSHIP:                                        │
│  • You control your private keys                         │
│  • No third-party risk                                   │
│  • Censorship-resistant                                  │
│  • Sovereignty over assets                               │
│                                                           │
│  PRIVACY:                                                │
│  • No KYC required (usually)                            │
│  • Pseudonymous                                          │
│  • No central database                                   │
│  • Self-sovereign identity                               │
│                                                           │
│  SECURITY:                                              │
│  • No exchange hack risk                                 │
│  • No withdrawal limits                                  │
│  • No frozen accounts                                    │
│  • Self-custody                                          │
│                                                           │
│  DECENTRALIZATION:                                       │
│  • Part of the network                                   │
│  • Trustless                                             │
│  • Permissionless                                        │
│  • Autonomous                                            │
└─────────────────────────────────────────────────────────────┘
        """)

class NonCustodialAnalytics:
    """Additional analysis tools for non-custodial wallets"""
    
    @staticmethod
    def compare_custodial_vs_non_custodial() -> None:
        """Compare custodial and non-custodial wallets"""
        print("\n 📊 CUSTODIAL VS NON-CUSTODIAL")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Key Control", "Security", "Convenience", "Recovery", "Privacy", "Best For"],
            "Custodial": ["Exchange/Provider", "Provider", "Very High", "Easy", "Low", "Trading, Beginners"],
            "Non-Custodial": ["User", "User", "Medium", "Self", "High", "Storage, DeFi"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'Custodial':>25} | {'Non-Custodial':>25}")
        print("-" * 75)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            custodial = comparison["Custodial"][i]
            non_custodial = comparison["Non-Custodial"][i]
            
            print(f" {attr:>20} | {custodial:>25} | {non_custodial:>25}")
    
    @staticmethod
    def analyze_security_continuum() -> None:
        """Analyze security continuum of non-custodial wallets"""
        print("\n 📈 NON-CUSTODIAL SECURITY CONTINUUM")
        print("-" * 40)
        
        continuum = {
            "Wallet Type": ["Paper", "Hardware", "Mobile", "Desktop", "Browser"],
            "Security": ["⭐⭐⭐⭐⭐", "⭐⭐⭐⭐⭐", "⭐⭐⭐", "⭐⭐⭐", "⭐⭐"],
            "Convenience": ["⭐", "⭐⭐", "⭐⭐⭐⭐", "⭐⭐⭐", "⭐⭐⭐⭐⭐"],
            "Best For": ["Long-term", "Storage", "Daily", "Desktop", "dApps"]
        }
        
        print("\n📋 Security Continuum:")
        print(f" {'Wallet Type':>15} | {'Security':>15} | {'Convenience':>15} | {'Best For':>20}")
        print("-" * 70)
        
        for i in range(len(continuum["Wallet Type"])):
            wallet_type = continuum["Wallet Type"][i]
            security = continuum["Security"][i]
            convenience = continuum["Convenience"][i]
            best_for = continuum["Best For"][i]
            
            print(f" {wallet_type[:15]:>15} | {security:>15} | {convenience:>15} | {best_for[:20]:>20}")

def demonstrate_non_custodial_wallet_engine():
    """Execute comprehensive non-custodial wallet demonstration"""
    print("=" * 60)
    print(" NON-CUSTODIAL WALLET FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = NonCustodialWalletEngine()
    
    # Run demonstrations
    engine.explain_non_custodial_overview()
    engine.list_non_custodial_wallets()
    engine.explain_non_custodial_responsibilities()
    engine.explain_non_custodial_advantages()
    
    # Additional analytics
    NonCustodialAnalytics.compare_custodial_vs_non_custodial()
    NonCustodialAnalytics.analyze_security_continuum()
    
    print("\n" + "=" * 60)
    print(" NON-CUSTODIAL WALLET SUMMARY:")
    print("   ✓ Non-Custodial = User controls private keys")
    print("   ✓ Types: Hot, Hardware, Paper")
    print("   ✓ Popular: MetaMask, Trust Wallet, Ledger")
    print("   ✓ Benefits: Full control, privacy, self-sovereignty")
    print("   ✓ Risk: Self-responsibility, no recovery")
    print("   ✓ Principle: Not your keys, not your crypto")
    print("   ✓ Use for: Long-term storage, DeFi")
    print("   ✓ Recommendation: Hardware wallet for large holdings")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_non_custodial_wallet_engine()

5.7 Seed Phrase

What is a Seed Phrase?

A seed phrase (recovery phrase, mnemonic phrase) is a set of words that can generate all private keys in a wallet. It acts as the master key that provides access to your cryptocurrency funds.

Seed Phrase Format:

FormatWordsBits
BIP-3912128
BIP-3924256

Security Guidelines:

RuleWhy
Never ShareAnyone with phrase controls funds
Write DownDon’t store digitally
Backup MultiplePrevent single point of failure
Store SecurePhysical security

Code Example – Seed Phrase:

"""
SEED PHRASE FUNDAMENTALS FRAMEWORK
===================================
Complete seed phrase analysis, security, and best practices
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class SeedLength(Enum):
    """Classification of seed phrase lengths"""
    WORDS_12 = "12 words (128-bit)"
    WORDS_15 = "15 words (160-bit)"
    WORDS_18 = "18 words (192-bit)"
    WORDS_21 = "21 words (224-bit)"
    WORDS_24 = "24 words (256-bit)"

@dataclass
class SeedPhraseInfo:
    """Represents seed phrase information"""
    word_count: int
    entropy_bits: int
    security_level: str
    compatibility: str
    recovery_time: str

@dataclass
class SeedStorageMethod:
    """Represents a seed storage method"""
    method: str
    durability: str
    security: str
    cost: str
    recommended: bool

class SeedPhraseEngine:
    """Complete seed phrase demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" SEED PHRASE ENGINE")
        print("=" * 60)
    
    def explain_seed_phrase_overview(self) -> None:
        """Provide comprehensive seed phrase overview"""
        print("\n 🌱 SEED PHRASE OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SEED PHRASE - MASTER KEY                                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Seed Phrase = Master key that generates keys │
│  Purpose: Backup, recovery, and wallet restoration        │
│                                                           │
│  KEY CONCEPT:                                            │
│  Seed Phrase → Master Key → All Private Keys             │
│                                                           │
│  FORMATS:                                                │
│                                                           │
│  12 WORDS (128-bit)                                     │
│  • Most common                                           │
│  • Good security                                         │
│  • Easy to write down                                    │
│  • Standard BIP-39                                       │
│                                                           │
│  24 WORDS (256-bit)                                     │
│  • Maximum security                                      │
│  • More words to write                                   │
│  • Highest entropy                                      │
│  • Recommended for large holdings                        │
│                                                           │
│  BIP-39 STANDARD:                                        │
│  • Word list: 2048 words                                 │
│  • Checksum: Validates phrase                            │
│  • Deterministic: Same seed = Same keys                 │
│  • Universal: Works across wallets                       │
│                                                           │
│  CRITICAL:                                               │
│  ⚠️  Seed Phrase = Complete control                      │
│  ⚠️  Anyone with phrase = Access to funds               │
│  ⚠️  Lost phrase = Lost funds forever                   │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_seed_formats(self) -> None:
        """List different seed phrase formats"""
        print("\n 📋 SEED PHRASE FORMATS")
        print("-" * 40)
        
        formats = [
            SeedPhraseInfo(
                word_count=12,
                entropy_bits=128,
                security_level="Very High",
                compatibility="Universal",
                recovery_time="Fast"
            ),
            SeedPhraseInfo(
                word_count=15,
                entropy_bits=160,
                security_level="Very High",
                compatibility="Some wallets",
                recovery_time="Medium"
            ),
            SeedPhraseInfo(
                word_count=18,
                entropy_bits=192,
                security_level="Extremely High",
                compatibility="Limited",
                recovery_time="Medium"
            ),
            SeedPhraseInfo(
                word_count=21,
                entropy_bits=224,
                security_level="Extremely High",
                compatibility="Limited",
                recovery_time="Slow"
            ),
            SeedPhraseInfo(
                word_count=24,
                entropy_bits=256,
                security_level="Maximum",
                compatibility="Universal",
                recovery_time="Slow"
            )
        ]
        
        print("\n📋 Format Details:")
        print(f" {'Words':>8} | {'Entropy':>12} | {'Security':>20} | {'Compatibility':>15} | {'Recovery':>12}")
        print("-" * 75)
        
        for format_info in formats:
            print(f" {format_info.word_count:>8} | {format_info.entropy_bits:>12} | "
                  f"{format_info.security_level[:20]:>20} | {format_info.compatibility[:15]:>15} | "
                  f"{format_info.recovery_time[:12]:>12}")
    
    def explain_seed_storage(self) -> None:
        """Explain seed storage methods"""
        print("\n 📦 SEED STORAGE METHODS")
        print("-" * 40)
        
        methods = [
            SeedStorageMethod(
                method="Paper Backup",
                durability="Low (fire/water risk)",
                security="Medium",
                cost="Free",
                recommended=False
            ),
            SeedStorageMethod(
                method="Metal/Steel",
                durability="Very High (fireproof/waterproof)",
                security="Very High",
                cost="$20-100",
                recommended=True
            ),
            SeedStorageMethod(
                method="Fireproof Safe",
                durability="High",
                security="Very High",
                cost="$100-500",
                recommended=True
            ),
            SeedStorageMethod(
                method="Bank Safe Deposit",
                durability="Very High",
                security="Very High",
                cost="Annual fee",
                recommended=True
            ),
            SeedStorageMethod(
                method="Digital Storage",
                durability="Medium",
                security="Low (hackable)",
                cost="Free",
                recommended=False
            )
        ]
        
        print("\n📋 Storage Methods:")
        print(f" {'Method':>18} | {'Durability':>20} | {'Security':>15} | {'Cost':>15} | {'Recommended':>12}")
        print("-" * 85)
        
        for method in methods:
            rec = "✅ Yes" if method.recommended else "❌ No"
            print(f" {method.method[:18]:>18} | {method.durability[:20]:>20} | "
                  f"{method.security[:15]:>15} | {method.cost[:15]:>15} | {rec:>12}")
    
    def explain_seed_security(self) -> None:
        """Explain seed phrase security"""
        print("\n 🛡️  SEED PHRASE SECURITY")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SEED PHRASE SECURITY BEST PRACTICES                    │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DO:                                                    │
│  ✅ Store on multiple physical media (paper, metal)     │
│  ✅ Use fireproof and waterproof materials               │
│  ✅ Store in different locations                         │
│  ✅ Test recovery process                                │
│  ✅ Use passphrase for extra security                    │
│  ✅ Keep backups separate from wallet                    │
│  ✅ Use steel plates for long-term storage               │
│                                                           │
│  DON'T:                                                 │
│  ❌ Never store digitally (phone, computer, cloud)      │
│  ❌ Never take photos or screenshots                     │
│  ❌ Never type into any device                           │
│  ❌ Never share with anyone                              │
│  ❌ Never lose or misplace                               │
│  ❌ Never store in a single location                     │
│  ❌ Never rely on memory                                 │
│                                                           │
│  ATTACK VECTORS:                                        │
│  • Physical theft                                        │
│  • Digital malware                                       │
│  • Social engineering                                    │
│  • Phishing attacks                                      │
│  • Keyloggers                                           │
│  • Clipboard hijacking                                   │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_seed_recovery(self) -> None:
        """Explain seed phrase recovery process"""
        print("\n 🔄 SEED PHRASE RECOVERY")
        print("-" * 40)
        
        recovery_steps = {
            "Step": [
                "1. Install Wallet",
                "2. Select Recovery",
                "3. Enter Words",
                "4. Verify Order",
                "5. Set New PIN",
                "6. Wait for Sync"
            ],
            "Action": [
                "Download compatible wallet",
                "Choose 'Import/Restore'",
                "Type 12-24 words correctly",
                "Check spelling and order",
                "Create new wallet PIN",
                "Blockchain synchronizes"
            ],
            "Time": [
                "5-10 min",
                "1 min",
                "5-15 min",
                "2-5 min",
                "1 min",
                "10-60 min"
            ]
        }
        
        print("\n📋 Recovery Process:")
        print(f" {'Step':>12} | {'Action':>30} | {'Time':>15}")
        print("-" * 65)
        
        for i in range(len(recovery_steps["Step"])):
            step = recovery_steps["Step"][i]
            action = recovery_steps["Action"][i]
            time_taken = recovery_steps["Time"][i]
            
            print(f" {step[:12]:>12} | {action[:30]:>30} | {time_taken:>15}")

class SeedAnalytics:
    """Additional analysis tools for seed phrases"""
    
    @staticmethod
    def analyze_entropy_strength() -> None:
        """Analyze seed phrase entropy strength"""
        print("\n 📊 ENTROPY STRENGTH ANALYSIS")
        print("-" * 40)
        
        entropy_data = {
            "Word Count": ["12", "15", "18", "21", "24"],
            "Entropy Bits": ["128", "160", "192", "224", "256"],
            "Security Level": ["Standard", "Enhanced", "High", "Very High", "Maximum"],
            "Brute Force Time": [
                "~10^24 years",
                "~10^30 years",
                "~10^36 years",
                "~10^42 years",
                "~10^48 years"
            ],
            "Recommendation": [
                "Beginner",
                "Intermediate",
                "Advanced",
                "Expert",
                "Institutional"
            ]
        }
        
        print("\n📋 Entropy Analysis:")
        print(f" {'Words':>12} | {'Entropy':>12} | {'Security':>20} | {'Brute Force Time':>25} | {'Recommendation':>15}")
        print("-" * 90)
        
        for i in range(len(entropy_data["Word Count"])):
            words = entropy_data["Word Count"][i]
            entropy = entropy_data["Entropy Bits"][i]
            security = entropy_data["Security Level"][i]
            time_brute = entropy_data["Brute Force Time"][i]
            rec = entropy_data["Recommendation"][i]
            
            print(f" {words:>12} | {entropy:>12} | {security[:20]:>20} | {time_brute[:25]:>25} | {rec[:15]:>15}")
    
    @staticmethod
    def analyze_common_mistakes() -> None:
        """Analyze common seed phrase mistakes"""
        print("\n ⚠️  COMMON SEED PHRASE MISTAKES")
        print("-" * 40)
        
        mistakes = {
            "Digital Storage": {
                "description": "Storing seed phrase digitally",
                "risk": "Exposed to malware/hackers",
                "consequence": "Funds stolen",
                "solution": "Use physical storage only"
            },
            "Single Backup": {
                "description": "Only one copy of seed phrase",
                "risk": "Lost if backup destroyed",
                "consequence": "Lost funds forever",
                "solution": "Multiple backups, different locations"
            },
            "Sharing with Others": {
                "description": "Sharing seed phrase",
                "risk": "Anyone can access funds",
                "consequence": "Funds stolen",
                "solution": "Never share with anyone"
            },
            "No Recovery Test": {
                "description": "Never tested recovery",
                "risk": "Unable to recover",
                "consequence": "Lost funds",
                "solution": "Test recovery with small amount"
            },
            "Memory Reliance": {
                "description": "Relying on memory only",
                "risk": "Forget phrase",
                "consequence": "Lost funds",
                "solution": "Always write down, test memory"
            }
        }
        
        print("\n📋 Common Mistakes:")
        for mistake, details in mistakes.items():
            print(f"\n  {mistake}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Consequence: {details['consequence']}")
            print(f"    Solution: {details['solution']}")

def demonstrate_seed_phrase_engine():
    """Execute comprehensive seed phrase demonstration"""
    print("=" * 60)
    print(" SEED PHRASE FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = SeedPhraseEngine()
    
    # Run demonstrations
    engine.explain_seed_phrase_overview()
    engine.list_seed_formats()
    engine.explain_seed_storage()
    engine.explain_seed_security()
    engine.explain_seed_recovery()
    
    # Additional analytics
    SeedAnalytics.analyze_entropy_strength()
    SeedAnalytics.analyze_common_mistakes()
    
    print("\n" + "=" * 60)
    print(" SEED PHRASE SUMMARY:")
    print("   ✓ Seed Phrase = Master key to all funds")
    print("   ✓ Formats: 12-24 words (BIP-39)")
    print("   ✓ Security: 128-256 bit entropy")
    print("   ✓ Storage: Physical only (paper, metal)")
    print("   ✓ Backup: Multiple copies, different locations")
    print("   ✓ Never: Share, store digitally, photograph")
    print("   ✓ Warning: Lost phrase = Lost funds forever")
    print("   ✓ Principle: Self-custody responsibility")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_seed_phrase_engine()

5.8 Transaction Signing

What is Transaction Signing?

Transaction signing is the process of authorizing a transaction using a private key. It proves that the transaction is authorized by the owner and prevents unauthorized transactions.

Signing Process:

  1. Create Transaction: Specify recipient, amount, gas, etc.
  2. Hash Transaction: Calculate transaction hash
  3. Sign with Private Key: Encrypt hash with private key
  4. Attach Signature: Add signature to transaction

Code Example – Transaction Signing:

"""
TRANSACTION SIGNING FRAMEWORK
==============================
Complete transaction signing demonstration and analysis
"""

import hashlib
import time
from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class SigningAlgorithm(Enum):
    """Classification of signing algorithms"""
    ECDSA = "ECDSA (secp256k1)"
    EdDSA = "EdDSA (ed25519)"
    RSA = "RSA"
    Schnorr = "Schnorr"

@dataclass
class Transaction:
    """Represents a blockchain transaction"""
    sender: str
    recipient: str
    amount: float
    gas_limit: int
    gas_price: int
    nonce: int
    data: str
    chain_id: int

@dataclass
class SignedTransaction:
    """Represents a signed transaction"""
    transaction: Transaction
    transaction_hash: str
    signature: str
    signing_algorithm: SigningAlgorithm
    signed_time: float
    is_valid: bool

class TransactionSigningEngine:
    """Complete transaction signing demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" TRANSACTION SIGNING ENGINE")
        print("=" * 60)
    
    def explain_signing_process(self) -> None:
        """Explain the transaction signing process"""
        print("\n ✍️  TRANSACTION SIGNING PROCESS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  TRANSACTION SIGNING FLOW                                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1. CREATE TRANSACTION                                   │
│     • Sender address                                      │
│     • Recipient address                                   │
│     • Amount                                              │
│     • Gas parameters                                      │
│     • Nonce                                               │
│     • Data (optional)                                     │
│                                                           │
│  2. HASH TRANSACTION                                     │
│     • Serialize transaction data                         │
│     • Apply hashing (SHA-256/Keccak)                    │
│     • Create unique transaction ID                       │
│     • Deterministic                                       │
│                                                           │
│  3. SIGN WITH PRIVATE KEY                                │
│     • Use private key                                     │
│     • Apply ECDSA/EdDSA                                  │
│     • Generate signature                                  │
│     • (r, s) components                                   │
│                                                           │
│  4. ATTACH SIGNATURE                                     │
│     • Add to transaction                                  │
│     • Ready for broadcast                                 │
│     • Network validation                                  │
│                                                           │
│  SECURITY PRINCIPLES:                                    │
│  ✓ Only key holder can sign                              │
│  ✓ Prevents unauthorized transactions                   │
│  ✓ Proves ownership                                      │
│  ✓ Non-repudiation                                       │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def create_and_sign_transaction(self) -> None:
        """Create and sign a sample transaction"""
        print("\n 📝 CREATING AND SIGNING TRANSACTION")
        print("-" * 40)
        
        # Create transaction
        transaction = Transaction(
            sender="0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
            recipient="0x9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWVH",
            amount=10.5,
            gas_limit=21000,
            gas_price=50,
            nonce=5,
            data="",
            chain_id=1
        )
        
        print("📋 Transaction Details:")
        print(f"  From: {transaction.sender[:16]}...")
        print(f"  To: {transaction.recipient[:16]}...")
        print(f"  Amount: {transaction.amount} ETH")
        print(f"  Gas Limit: {transaction.gas_limit}")
        print(f"  Gas Price: {transaction.gas_price} Gwei")
        print(f"  Nonce: {transaction.nonce}")
        
        # Hash transaction
        tx_string = f"{transaction.sender}{transaction.recipient}{transaction.amount}{transaction.nonce}{transaction.gas_limit}{transaction.gas_price}{transaction.chain_id}"
        tx_hash = hashlib.sha256(tx_string.encode()).hexdigest()
        
        print(f"\n🔐 Transaction Hash:")
        print(f"  {tx_hash}")
        
        # Sign transaction (simplified ECDSA)
        private_key = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
        signature_data = f"{tx_hash}{private_key}"
        signature = hashlib.sha256(signature_data.encode()).hexdigest()
        
        print(f"\n✍️  Signature:")
        print(f"  {signature}")
        print(f"  Length: {len(signature)} characters")
        
        signed_tx = SignedTransaction(
            transaction=transaction,
            transaction_hash=tx_hash,
            signature=signature,
            signing_algorithm=SigningAlgorithm.ECDSA,
            signed_time=time.time(),
            is_valid=True
        )
        
        print(f"\n✅ Transaction Signed Successfully")
        print(f"  Algorithm: {signed_tx.signing_algorithm.value}")
        print(f"  Valid: {signed_tx.is_valid}")
    
    def explain_signing_algorithms(self) -> None:
        """Explain different signing algorithms"""
        print("\n 📊 SIGNING ALGORITHMS")
        print("-" * 40)
        
        algorithms = {
            "ECDSA (secp256k1)": {
                "description": "Elliptic Curve Digital Signature Algorithm",
                "key_size": "256-bit",
                "signature_size": "64 bytes",
                "speed": "Fast",
                "usage": "Bitcoin, Ethereum"
            },
            "EdDSA (ed25519)": {
                "description": "Edwards-curve Digital Signature Algorithm",
                "key_size": "256-bit",
                "signature_size": "64 bytes",
                "speed": "Very Fast",
                "usage": "Solana, Cardano"
            },
            "Schnorr": {
                "description": "Schnorr signature algorithm",
                "key_size": "256-bit",
                "signature_size": "64 bytes",
                "speed": "Fast",
                "usage": "Bitcoin (Taproot)"
            }
        }
        
        print("\n📋 Algorithm Comparison:")
        print(f" {'Algorithm':>20} | {'Key Size':>12} | {'Signature Size':>15} | {'Speed':>10} | {'Usage':>15}")
        print("-" * 80)
        
        for alg_name, details in algorithms.items():
            print(f" {alg_name[:20]:>20} | {details['key_size']:>12} | {details['signature_size']:>15} | "
                  f"{details['speed']:>10} | {details['usage'][:15]:>15}")
    
    def explain_security_considerations(self) -> None:
        """Explain security considerations"""
        print("\n 🛡️  SIGNING SECURITY")
        print("-" * 40)
        
        security_considerations = {
            "Private Key Security": {
                "description": "Private key must be kept secure",
                "risk": "Compromised key = Stolen funds",
                "best_practice": "Use hardware wallet, never share"
            },
            "Nonce Reuse": {
                "description": "Never reuse nonce in ECDSA",
                "risk": "Private key can be recovered",
                "best_practice": "Use deterministic ECDSA (RFC 6979)"
            },
            "Transaction Verification": {
                "description": "Verify transaction details before signing",
                "risk": "Signing malicious transaction",
                "best_practice": "Review on hardware wallet screen"
            },
            "Replay Attacks": {
                "description": "Transaction replayed on different chain",
                "risk": "Unintended execution",
                "best_practice": "Use chain ID in transaction"
            },
            "Phishing": {
                "description": "Fake websites requesting signatures",
                "risk": "Signing malicious transactions",
                "best_practice": "Always verify URL and dApp"
            }
        }
        
        print("\n📋 Security Considerations:")
        for consideration, details in security_considerations.items():
            print(f"\n  {consideration}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Best Practice: {details['best_practice']}")

class SigningAnalytics:
    """Additional analysis tools for transaction signing"""
    
    @staticmethod
    def compare_signing_speed() -> None:
        """Compare signing speed across algorithms"""
        print("\n 📈 SIGNING SPEED COMPARISON")
        print("-" * 40)
        
        speed_data = {
            "Algorithm": ["ECDSA (secp256k1)", "EdDSA (ed25519)", "Schnorr"],
            "Signing (ms)": ["1.5ms", "1.0ms", "1.2ms"],
            "Verification (ms)": ["2.5ms", "1.8ms", "2.0ms"],
            "Relative Speed": ["Reference", "30% Faster", "20% Faster"]
        }
        
        print("\n📋 Speed Comparison:")
        print(f" {'Algorithm':>20} | {'Signing (ms)':>15} | {'Verification (ms)':>20} | {'Relative':>15}")
        print("-" * 75)
        
        for i in range(len(speed_data["Algorithm"])):
            alg = speed_data["Algorithm"][i]
            signing = speed_data["Signing (ms)"][i]
            verification = speed_data["Verification (ms)"][i]
            relative = speed_data["Relative Speed"][i]
            
            print(f" {alg[:20]:>20} | {signing:>15} | {verification:>20} | {relative:>15}")
    
    @staticmethod
    def analyze_signing_workflow() -> None:
        """Analyze the signing workflow in detail"""
        print("\n 🔄 SIGNING WORKFLOW ANALYSIS")
        print("-" * 40)
        
        workflow = {
            "Step": [
                "1. Transaction Creation",
                "2. Serialization",
                "3. Hashing",
                "4. Signing",
                "5. Signature Verification",
                "6. Broadcast"
            ],
            "Process": [
                "Build transaction object",
                "RLP/Protobuf encoding",
                "SHA-256/Keccak-256",
                "ECDSA/EdDSA",
                "Public key verification",
                "Network propagation"
            ],
            "Time": [
                "< 1ms",
                "< 1ms",
                "< 1ms",
                "1-2ms",
                "2-3ms",
                "100-500ms"
            ]
        }
        
        print("\n📋 Workflow Steps:")
        print(f" {'Step':>25} | {'Process':>30} | {'Time':>15}")
        print("-" * 75)
        
        for i in range(len(workflow["Step"])):
            step = workflow["Step"][i]
            process = workflow["Process"][i]
            time_taken = workflow["Time"][i]
            
            print(f" {step[:25]:>25} | {process[:30]:>30} | {time_taken:>15}")

def demonstrate_transaction_signing_engine():
    """Execute comprehensive transaction signing demonstration"""
    print("=" * 60)
    print(" TRANSACTION SIGNING ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = TransactionSigningEngine()
    
    # Run demonstrations
    engine.explain_signing_process()
    engine.create_and_sign_transaction()
    engine.explain_signing_algorithms()
    engine.explain_security_considerations()
    
    # Additional analytics
    SigningAnalytics.compare_signing_speed()
    SigningAnalytics.analyze_signing_workflow()
    
    print("\n" + "=" * 60)
    print(" TRANSACTION SIGNING SUMMARY:")
    print("   ✓ Signing = Authorization with private key")
    print("   ✓ Process: Create → Hash → Sign → Attach")
    print("   ✓ Algorithms: ECDSA, EdDSA, Schnorr")
    print("   ✓ Security: Only key holder can sign")
    print("   ✓ Every transaction must be signed")
    print("   ✓ Signing proves ownership and authorization")
    print("   ✓ Prevents unauthorized transactions")
    print("   ✓ Hardware wallets for secure signing")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_transaction_signing_engine()

5.9 Gas

What is Gas?

Gas is a unit of computational work on the Ethereum network. It measures the amount of work required to execute a transaction or smart contract. Users pay gas fees to compensate validators for processing transactions.

Gas Concepts:

TermDescription
GasUnit of computational work
Gas LimitMaximum gas allowed
Gas PricePrice per gas unit
Gwei1 Gwei = 10^-9 ETH

Code Example – Gas:

"""
GAS FUNDAMENTALS FRAMEWORK
===========================
Complete gas analysis for blockchain transactions
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class GasLevel(Enum):
    """Classification of gas price levels"""
    LOW = "Low Priority"
    MEDIUM = "Standard Priority"
    HIGH = "High Priority"
    VERY_HIGH = "Maximum Priority"

@dataclass
class GasTransaction:
    """Represents a transaction with gas parameters"""
    gas_limit: int
    gas_price_gwei: float
    total_gwei: float
    total_eth: float
    total_usd: float
    confirmation_time: str

@dataclass
class GasMetric:
    """Represents a gas metric"""
    metric: str
    value: str
    description: str
    significance: str

class GasEngine:
    """Complete gas fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" GAS FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_gas_overview(self) -> None:
        """Provide comprehensive gas overview"""
        print("\n ⛽ GAS OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  GAS - COMPUTATIONAL WORK UNIT                           │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Gas = Unit of computational work            │
│  Purpose: Measure and pay for transaction processing      │
│                                                           │
│  WHY GAS EXISTS:                                         │
│  ✓ Prevents spam and DoS attacks                         │
│  ✓ Compensates validators                                │
│  ✓ Measures computational complexity                     │
│  ✓ Allocates resources efficiently                        │
│  ✓ Gas limit prevents infinite loops                     │
│                                                           │
│  GAS COMPONENTS:                                         │
│                                                           │
│  1. GAS LIMIT                                           │
│     • Maximum gas allowed                                 │
│     • Simple transfer: 21,000                            │
│     • Complex contract: 100,000-1,000,000               │
│     • Protects against bugs                              │
│                                                           │
│  2. GAS PRICE                                           │
│     • Price per unit of gas                              │
│     • Measured in Gwei                                   │
│     • Low: 10-20 Gwei                                    │
│     • Medium: 30-50 Gwei                                 │
│     • High: 100+ Gwei                                    │
│                                                           │
│  3. GWEI                                                │
│     • Unit of ETH                                        │
│     • 1 Gwei = 10^-9 ETH                                 │
│     • 1 ETH = 1,000,000,000 Gwei                        │
│     • Used for gas pricing                               │
│                                                           │
│  FORMULA:                                                │
│  Total Fee = Gas Used × Gas Price                       │
│  in Gwei = Gas Used × Gas Price (Gwei)                 │
│  in ETH = (Gas Used × Gas Price) / 10^9                │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_gas_calculation(self) -> None:
        """Demonstrate gas calculations"""
        print("\n 📊 GAS CALCULATION EXAMPLES")
        print("-" * 40)
        
        transactions = [
            GasTransaction(
                gas_limit=21000,
                gas_price_gwei=30.0,
                total_gwei=630000,
                total_eth=0.00063,
                total_usd=1.89,
                confirmation_time="~2-3 minutes"
            ),
            GasTransaction(
                gas_limit=21000,
                gas_price_gwei=50.0,
                total_gwei=1050000,
                total_eth=0.00105,
                total_usd=3.15,
                confirmation_time="~1-2 minutes"
            ),
            GasTransaction(
                gas_limit=21000,
                gas_price_gwei=100.0,
                total_gwei=2100000,
                total_eth=0.0021,
                total_usd=6.30,
                confirmation_time="~30-60 seconds"
            ),
            GasTransaction(
                gas_limit=100000,
                gas_price_gwei=50.0,
                total_gwei=5000000,
                total_eth=0.005,
                total_usd=15.00,
                confirmation_time="~1-2 minutes"
            ),
            GasTransaction(
                gas_limit=200000,
                gas_price_gwei=30.0,
                total_gwei=6000000,
                total_eth=0.006,
                total_usd=18.00,
                confirmation_time="~2-3 minutes"
            )
        ]
        
        print("📋 Gas Calculation Examples (ETH Price: $3,000):")
        print(f" {'Gas Limit':>12} | {'Gas Price':>15} | {'Total Gwei':>15} | {'Total ETH':>12} | {'Total USD':>12} | {'Time':>15}")
        print("-" * 85)
        
        for tx in transactions:
            print(f" {tx.gas_limit:>12} | {tx.gas_price_gwei:>14.1f} Gwei | {tx.total_gwei:>15,} | "
                  f"{tx.total_eth:>12.6f} | ${tx.total_usd:>11.2f} | {tx.confirmation_time:>15}")
    
    def explain_gas_pricing(self) -> None:
        """Explain gas pricing dynamics"""
        print("\n 📈 GAS PRICING DYNAMICS")
        print("-" * 40)
        
        gas_levels = {
            GasLevel.LOW: {
                "gwei": 10-20,
                "description": "Low priority, slow confirmation",
                "wait_time": "~10-30 minutes",
                "use_case": "Non-urgent transfers"
            },
            GasLevel.MEDIUM: {
                "gwei": 30-50,
                "description": "Standard priority, typical confirmation",
                "wait_time": "~2-5 minutes",
                "use_case": "Most transactions"
            },
            GasLevel.HIGH: {
                "gwei": 70-100,
                "description": "High priority, fast confirmation",
                "wait_time": "~30-60 seconds",
                "use_case": "Time-sensitive transactions"
            },
            GasLevel.VERY_HIGH: {
                "gwei": 150-200,
                "description": "Maximum priority, instant confirmation",
                "wait_time": "~10-20 seconds",
                "use_case": "High-value transactions"
            }
        }
        
        print("\n📋 Gas Price Levels:")
        print(f" {'Level':>15} | {'Gwei Range':>15} | {'Description':>30} | {'Wait Time':>15}")
        print("-" * 80)
        
        for level, details in gas_levels.items():
            gwei_range = f"{details['gwei'][0]}-{details['gwei'][1]}"
            print(f" {level.value[:15]:>15} | {gwei_range:>15} | {details['description'][:30]:>30} | "
                  f"{details['wait_time'][:15]:>15}")
    
    def explain_gas_metrics(self) -> None:
        """Explain key gas metrics"""
        print("\n 📊 GAS METRICS")
        print("-" * 40)
        
        metrics = [
            GasMetric(
                metric="Base Fee",
                value="Variable",
                description="Minimum fee per gas, burned",
                significance="Shows network demand"
            ),
            GasMetric(
                metric="Priority Fee",
                value="Tip to validators",
                description="Extra to incentivize inclusion",
                significance="Shows urgency"
            ),
            GasMetric(
                metric="Gas Used",
                value="Actual gas consumed",
                description="Computational resources used",
                significance="Shows complexity"
            ),
            GasMetric(
                metric="Block Gas Limit",
                value="30M (Ethereum)",
                description="Max gas per block",
                significance="Shows network capacity"
            ),
            GasMetric(
                metric="Average Gas Price",
                value="~30-50 Gwei",
                description="Current network average",
                significance="Indicates congestion"
            )
        ]
        
        print("\n📋 Gas Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric[:25]:>25} | {metric.value[:20]:>20} | "
                  f"{metric.description[:30]:>30} | {metric.significance[:30]:>30}")

class GasAnalytics:
    """Additional analysis tools for gas"""
    
    @staticmethod
    def analyze_gas_history() -> None:
        """Analyze historical gas trends"""
        print("\n 📈 GAS PRICE HISTORY")
        print("-" * 40)
        
        history = {
            "Year": ["2020", "2021", "2022", "2023", "2024"],
            "Average Gas (Gwei)": ["40", "100", "30", "20", "35"],
            "Peak Gas (Gwei)": ["200", "500", "100", "80", "120"],
            "Normal Time": ["~5 min", "~10 min", "~3 min", "~2 min", "~3 min"],
            "Network": ["Low", "High", "Medium", "Low", "Medium"]
        }
        
        print("\n📋 Historical Gas Prices:")
        print(f" {'Year':>10} | {'Average (Gwei)':>15} | {'Peak (Gwei)':>15} | {'Normal Time':>15} | {'Network':>15}")
        print("-" * 75)
        
        for i in range(len(history["Year"])):
            year = history["Year"][i]
            avg = history["Average Gas (Gwei)"][i]
            peak = history["Peak Gas (Gwei)"][i]
            time_norm = history["Normal Time"][i]
            network = history["Network"][i]
            
            print(f" {year:>10} | {avg:>15} | {peak:>15} | {time_norm:>15} | {network:>15}")
    
    @staticmethod
    def analyze_gas_optimization() -> None:
        """Analyze gas optimization strategies"""
        print("\n ⚡ GAS OPTIMIZATION STRATEGIES")
        print("-" * 40)
        
        strategies = {
            "Low Activity Times": {
                "benefit": "Lower gas prices",
                "best_time": "Weekends, night hours (UTC)",
                "saving": "Up to 50%"
            },
            "Use Layer 2": {
                "benefit": "Dramatically lower fees",
                "best_time": "Any time",
                "saving": "90-99%"
            },
            "Batch Transactions": {
                "benefit": "Single fee for multiple operations",
                "best_time": "When sending to multiple recipients",
                "saving": "30-50%"
            },
            "Optimize Contract Code": {
                "benefit": "Lower gas consumption",
                "best_time": "Contract deployment",
                "saving": "20-40%"
            }
        }
        
        print("\n📋 Optimization Strategies:")
        for strategy, details in strategies.items():
            print(f"\n  {strategy}:")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Best Time: {details['best_time']}")
            print(f"    Saving: {details['saving']}")

def demonstrate_gas_engine():
    """Execute comprehensive gas demonstration"""
    print("=" * 60)
    print(" GAS FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GasEngine()
    
    # Run demonstrations
    engine.explain_gas_overview()
    engine.demonstrate_gas_calculation()
    engine.explain_gas_pricing()
    engine.explain_gas_metrics()
    
    # Additional analytics
    GasAnalytics.analyze_gas_history()
    GasAnalytics.analyze_gas_optimization()
    
    print("\n" + "=" * 60)
    print(" GAS SUMMARY:")
    print("   ✓ Gas = Unit of computational work")
    print("   ✓ Components: Gas Limit, Gas Price, Gwei")
    print("   ✓ Total Fee = Gas Used × Gas Price")
    print("   ✓ Simple transfer: 21,000 gas")
    print("   ✓ Gas Price: 10-100+ Gwei")
    print("   ✓ 1 Gwei = 10^-9 ETH")
    print("   ✓ High demand = Higher gas prices")
    print("   ✓ Use Layer 2 for lower fees")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_gas_engine()

5.10 Gas Limit

What is Gas Limit?

The gas limit is the maximum amount of gas the sender is willing to pay for a transaction. It acts as a cap on the transaction fee.

Gas Limit by Transaction Type:

Transaction TypeTypical Gas Limit
ETH Transfer21,000
ERC-20 Transfer65,000
Uniswap Swap100,000+
Contract Deployment1,000,000+

Code Example – Gas Limit:

"""
GAS LIMIT FUNDAMENTALS FRAMEWORK
=================================
Complete gas limit analysis and optimization
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class TransactionType(Enum):
    """Classification of transaction types by gas usage"""
    SIMPLE_TRANSFER = "Simple ETH Transfer"
    ERC20_TRANSFER = "ERC-20 Token Transfer"
    SIMPLE_CONTRACT = "Simple Contract Call"
    COMPLEX_CONTRACT = "Complex Contract Call"
    CONTRACT_DEPLOYMENT = "Smart Contract Deployment"

@dataclass
class GasLimitInfo:
    """Represents gas limit information for a transaction type"""
    transaction_type: TransactionType
    gas_limit: int
    description: str
    typical_cost_usd: str
    risk_level: str

@dataclass
class GasLimitMetric:
    """Represents a gas limit metric"""
    metric: str
    value: str
    description: str
    significance: str

class GasLimitEngine:
    """Complete gas limit demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" GAS LIMIT ENGINE")
        print("=" * 60)
    
    def explain_gas_limit_overview(self) -> None:
        """Provide comprehensive gas limit overview"""
        print("\n ⛽ GAS LIMIT OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  GAS LIMIT - MAXIMUM GAS ALLOWED                        │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Gas Limit = Maximum gas allowed for tx      │
│  Purpose: Cap computational cost and prevent runaway      │
│                                                           │
│  WHY GAS LIMIT MATTERS:                                  │
│  ✓ Protects users from infinite loops                    │
│  ✓ Prevents excessive spending                           │
│  ✓ Transaction success/failure determinant              │
│  ✓ Block space allocation                                │
│                                                           │
│  KEY CONCEPTS:                                           │
│                                                           │
│  SETTING GAS LIMIT:                                      │
│  • If too low: Transaction fails ("Out of Gas")          │
│  • If too high: Unused gas is refunded                   │
│  • Wallets auto-calculate                                 │
│                                                           │
│  UNUSED GAS REFUND:                                      │
│  • Gas used < Gas Limit                                  │
│  • Difference is refunded to sender                     │
│  • Still pay for used gas                                │
│                                                           │
│  TYPICAL GAS LIMITS:                                     │
│  • ETH Transfer: 21,000                                  │
│  • ERC-20 Transfer: 65,000                              │
│  • Simple Contract: 100,000                             │
│  • Complex Contract: 300,000+                           │
│  • Contract Deployment: 1,000,000+                     │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_gas_limits(self) -> None:
        """List gas limits for different transaction types"""
        print("\n 📋 GAS LIMITS BY TRANSACTION TYPE")
        print("-" * 40)
        
        gas_infos = [
            GasLimitInfo(
                transaction_type=TransactionType.SIMPLE_TRANSFER,
                gas_limit=21000,
                description="Basic ETH transfer between wallets",
                typical_cost_usd="~$0.60 (30 Gwei, $3,000 ETH)",
                risk_level="Low"
            ),
            GasLimitInfo(
                transaction_type=TransactionType.ERC20_TRANSFER,
                gas_limit=65000,
                description="Transfer of ERC-20 tokens",
                typical_cost_usd="~$1.95 (30 Gwei, $3,000 ETH)",
                risk_level="Low"
            ),
            GasLimitInfo(
                transaction_type=TransactionType.SIMPLE_CONTRACT,
                gas_limit=100000,
                description="Simple smart contract interaction",
                typical_cost_usd="~$3.00 (30 Gwei, $3,000 ETH)",
                risk_level="Medium"
            ),
            GasLimitInfo(
                transaction_type=TransactionType.COMPLEX_CONTRACT,
                gas_limit=300000,
                description="Complex contract execution",
                typical_cost_usd="~$9.00 (30 Gwei, $3,000 ETH)",
                risk_level="High"
            ),
            GasLimitInfo(
                transaction_type=TransactionType.CONTRACT_DEPLOYMENT,
                gas_limit=1000000,
                description="Deploying new smart contract",
                typical_cost_usd="~$30.00 (30 Gwei, $3,000 ETH)",
                risk_level="High"
            )
        ]
        
        print("\n📋 Gas Limit Details:")
        print(f" {'Transaction Type':>25} | {'Gas Limit':>12} | {'Description':>35} | {'Risk':>12}")
        print("-" * 90)
        
        for info in gas_infos:
            print(f" {info.transaction_type.value[:25]:>25} | {info.gas_limit:>12,} | "
                  f"{info.description[:35]:>35} | {info.risk_level[:12]:>12}")
    
    def explain_gas_limit_consequences(self) -> None:
        """Explain consequences of incorrect gas limit"""
        print("\n ⚠️  GAS LIMIT CONSEQUENCES")
        print("-" * 40)
        
        consequences = {
            "Gas Limit Too Low": {
                "result": "Transaction fails",
                "message": "Out of gas",
                "impact": "Gas still consumed, no refund",
                "solution": "Increase gas limit"
            },
            "Gas Limit Too High": {
                "result": "Transaction succeeds",
                "message": "Successful execution",
                "impact": "Unused gas refunded",
                "solution": "Use auto-calculated limit"
            },
            "Gas Limit Correct": {
                "result": "Transaction succeeds",
                "message": "Optimal gas usage",
                "impact": "Pay only for gas used",
                "solution": "Trust wallet estimates"
            }
        }
        
        print("\n📋 Consequences:")
        print(f" {'Scenario':>25} | {'Result':>20} | {'Impact':>35} | {'Solution':>30}")
        print("-" * 115)
        
        for scenario, details in consequences.items():
            print(f" {scenario[:25]:>25} | {details['result'][:20]:>20} | "
                  f"{details['impact'][:35]:>35} | {details['solution'][:30]:>30}")
    
    def explain_gas_limit_optimization(self) -> None:
        """Explain gas limit optimization strategies"""
        print("\n 🎯 GAS LIMIT OPTIMIZATION")
        print("-" * 40)
        
        strategies = {
            "Use Auto-Estimation": {
                "description": "Wallets estimate gas automatically",
                "benefit": "Reduces risk of failure",
                "best_practice": "Trust wallet estimates for standard txs"
            },
            "Manual Increase": {
                "description": "Manually set higher gas limit",
                "benefit": "Ensures success for complex txs",
                "best_practice": "Add 20-30% buffer for contracts"
            },
            "Test with Small Amount": {
                "description": "Test transaction first",
                "benefit": "Validates gas requirements",
                "best_practice": "Use testnet or small amounts"
            },
            "Contract Optimization": {
                "description": "Optimize contract gas usage",
                "benefit": "Lower gas costs",
                "best_practice": "Use gas-efficient patterns"
            }
        }
        
        print("\n📋 Optimization Strategies:")
        for strategy, details in strategies.items():
            print(f"\n  {strategy}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Best Practice: {details['best_practice']}")

class GasLimitAnalytics:
    """Additional analysis tools for gas limit"""
    
    @staticmethod
    def analyze_gas_usage_patterns() -> None:
        """Analyze gas usage patterns"""
        print("\n 📊 GAS USAGE PATTERNS")
        print("-" * 40)
        
        patterns = {
            "Transaction Type": [
                "ETH Transfer",
                "ERC-20 Transfer",
                "NFT Transfer",
                "DEX Swap",
                "Lending",
                "Bridge"
            ],
            "Average Gas": [
                "21,000",
                "65,000",
                "100,000",
                "150,000",
                "200,000",
                "250,000"
            ],
            "Complexity": [
                "Simple",
                "Medium",
                "Medium",
                "Complex",
                "Very Complex",
                "Very Complex"
            ],
            "Typical Cost": [
                "$0.60",
                "$1.95",
                "$3.00",
                "$4.50",
                "$6.00",
                "$7.50"
            ]
        }
        
        print("\n📋 Usage Patterns:")
        print(f" {'Transaction Type':>20} | {'Avg Gas':>12} | {'Complexity':>15} | {'Cost':>12}")
        print("-" * 65)
        
        for i in range(len(patterns["Transaction Type"])):
            tx_type = patterns["Transaction Type"][i]
            avg_gas = patterns["Average Gas"][i]
            complexity = patterns["Complexity"][i]
            cost = patterns["Typical Cost"][i]
            
            print(f" {tx_type[:20]:>20} | {avg_gas:>12} | {complexity[:15]:>15} | {cost:>12}")
    
    @staticmethod
    def analyze_gas_limit_history() -> None:
        """Analyze gas limit history"""
        print("\n 📈 GAS LIMIT HISTORY")
        print("-" * 40)
        
        history = {
            "Network": ["Ethereum", "Ethereum", "Ethereum", "Ethereum", "Solana", "BSC"],
            "Block Gas Limit": [
                "1M",
                "10M",
                "15M",
                "30M",
                "~48M",
                "~30M"
            ],
            "Year": [
                "2015",
                "2018",
                "2020",
                "2022",
                "2023",
                "2023"
            ],
            "Impact": [
                "Initial limit",
                "First upgrade",
                "EIP-1559",
                "Merge",
                "High throughput",
                "EVM compatible"
            ]
        }
        
        print("\n📋 Gas Limit History:")
        print(f" {'Network':>15} | {'Block Gas Limit':>18} | {'Year':>10} | {'Impact':>30}")
        print("-" * 80)
        
        for i in range(len(history["Network"])):
            network = history["Network"][i]
            limit = history["Block Gas Limit"][i]
            year = history["Year"][i]
            impact = history["Impact"][i]
            
            print(f" {network[:15]:>15} | {limit:>18} | {year:>10} | {impact[:30]:>30}")

def demonstrate_gas_limit_engine():
    """Execute comprehensive gas limit demonstration"""
    print("=" * 60)
    print(" GAS LIMIT FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GasLimitEngine()
    
    # Run demonstrations
    engine.explain_gas_limit_overview()
    engine.list_gas_limits()
    engine.explain_gas_limit_consequences()
    engine.explain_gas_limit_optimization()
    
    # Additional analytics
    GasLimitAnalytics.analyze_gas_usage_patterns()
    GasLimitAnalytics.analyze_gas_limit_history()
    
    print("\n" + "=" * 60)
    print(" GAS LIMIT SUMMARY:")
    print("   ✓ Gas Limit = Max gas allowed for transaction")
    print("   ✓ Too low = Transaction fails (Out of Gas)")
    print("   ✓ Too high = Unused gas refunded")
    print("   ✓ ETH Transfer: 21,000 gas")
    print("   ✓ ERC-20 Transfer: 65,000 gas")
    print("   ✓ Complex Contract: 300,000+ gas")
    print("   ✓ Auto-calculation by wallets is recommended")
    print("   ✓ Add buffer for complex transactions")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_gas_limit_engine()

5.11 Gas Price

What is Gas Price?

The gas price is the amount of cryptocurrency (ETH) paid per unit of gas. Higher gas prices incentivize validators to process transactions faster.

Gas Price Factors:

FactorEffect
Network CongestionHigher = More Expensive
Transaction PriorityHigher = Faster Processing
Time of DayVaries
Current Gas PriceMarket-determined

Code Example – Gas Price:

"""
GAS PRICE FUNDAMENTALS FRAMEWORK
=================================
Complete gas price analysis and optimization
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class PriceLevel(Enum):
    """Classification of gas price levels"""
    LOW = "Low Priority"
    STANDARD = "Standard Priority"
    HIGH = "High Priority"
    PREMIUM = "Premium Priority"

@dataclass
class GasPriceInfo:
    """Represents gas price information"""
    level: PriceLevel
    gwei_range: str
    description: str
    wait_time: str
    use_case: str

@dataclass
class GasPriceMetric:
    """Represents a gas price metric"""
    metric: str
    value: str
    description: str
    significance: str

class GasPriceEngine:
    """Complete gas price demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" GAS PRICE ENGINE")
        print("=" * 60)
    
    def explain_gas_price_overview(self) -> None:
        """Provide comprehensive gas price overview"""
        print("\n 💲 GAS PRICE OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  GAS PRICE - PRICE PER GAS UNIT                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Gas Price = Price per unit of gas           │
│  Unit: Gwei (1 Gwei = 10^-9 ETH)                        │
│                                                           │
│  HOW GAS PRICE WORKS:                                    │
│  • Users bid for gas price                               │
│  • Validators prioritize higher bids                     │
│  • Market determines price                               │
│  • Supply and demand driven                              │
│                                                           │
│  GAS PRICE LEVELS:                                       │
│                                                           │
│  LOW PRIORITY (10-20 Gwei)                              │
│  • Slowest processing                                     │
│  • Lower cost                                             │
│  • Wait: 10-30 minutes                                   │
│  • Use: Non-urgent transfers                             │
│                                                           │
│  STANDARD PRIORITY (30-50 Gwei)                         │
│  • Normal processing                                      │
│  • Average cost                                           │
│  • Wait: 2-5 minutes                                     │
│  • Use: Most transactions                                │
│                                                           │
│  HIGH PRIORITY (70-100 Gwei)                            │
│  • Fast processing                                        │
│  • Higher cost                                            │
│  • Wait: 30-60 seconds                                   │
│  • Use: Time-sensitive txs                               │
│                                                           │
│  PREMIUM PRIORITY (150+ Gwei)                           │
│  • Fastest processing                                     │
│  • Highest cost                                           │
│  • Wait: 10-20 seconds                                   │
│  • Use: High-value transactions                          │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_gas_prices(self) -> None:
        """List gas price levels"""
        print("\n 📊 GAS PRICE LEVELS")
        print("-" * 40)
        
        price_infos = [
            GasPriceInfo(
                level=PriceLevel.LOW,
                gwei_range="10-20",
                description="Low priority, slowest confirmation",
                wait_time="10-30 minutes",
                use_case="Non-urgent transfers"
            ),
            GasPriceInfo(
                level=PriceLevel.STANDARD,
                gwei_range="30-50",
                description="Standard priority, normal speed",
                wait_time="2-5 minutes",
                use_case="Most transactions"
            ),
            GasPriceInfo(
                level=PriceLevel.HIGH,
                gwei_range="70-100",
                description="High priority, fast confirmation",
                wait_time="30-60 seconds",
                use_case="Time-sensitive transactions"
            ),
            GasPriceInfo(
                level=PriceLevel.PREMIUM,
                gwei_range="150+",
                description="Premium priority, fastest confirmation",
                wait_time="10-20 seconds",
                use_case="High-value or urgent transactions"
            )
        ]
        
        print("\n📋 Gas Price Levels:")
        print(f" {'Level':>15} | {'Gwei Range':>15} | {'Description':>35} | {'Wait Time':>15} | {'Use Case':>20}")
        print("-" * 105)
        
        for info in price_infos:
            print(f" {info.level.value[:15]:>15} | {info.gwei_range:>15} | "
                  f"{info.description[:35]:>35} | {info.wait_time[:15]:>15} | {info.use_case[:20]:>20}")
    
    def explain_gas_price_factors(self) -> None:
        """Explain factors affecting gas price"""
        print("\n 📈 FACTORS AFFECTING GAS PRICE")
        print("-" * 40)
        
        factors = {
            "Network Congestion": {
                "description": "Number of pending transactions",
                "impact": "High congestion = High gas price",
                "example": "NFT mint events, DeFi activity",
                "strategy": "Wait for off-peak hours"
            },
            "Transaction Complexity": {
                "description": "Gas required for execution",
                "impact": "Complex txs need higher gas",
                "example": "Smart contracts vs transfers",
                "strategy": "Optimize contract code"
            },
            "Block Space Demand": {
                "description": "Demand for block capacity",
                "impact": "High demand = Higher gas",
                "example": "Popular dApps, airdrops",
                "strategy": "Use Layer 2 solutions"
            },
            "Validator Preference": {
                "description": "Validators choose high fees",
                "impact": "Higher tips = Faster inclusion",
                "example": "Priority transactions",
                "strategy": "Tip appropriately"
            }
        }
        
        print("\n📋 Factors:")
        for factor, details in factors.items():
            print(f"\n  {factor}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Example: {details['example']}")
            print(f"    Strategy: {details['strategy']}")
    
    def explain_gas_price_metrics(self) -> None:
        """Explain key gas price metrics"""
        print("\n 📊 GAS PRICE METRICS")
        print("-" * 40)
        
        metrics = [
            GasPriceMetric(
                metric="Current Gas Price",
                value="Variable",
                description="Current network gas price",
                significance="Shows current congestion"
            ),
            GasPriceMetric(
                metric="Base Fee",
                value="EIP-1559",
                description="Minimum fee burned",
                significance="Network demand indicator"
            ),
            GasPriceMetric(
                metric="Priority Fee",
                value="Tip to validators",
                description="Extra for faster inclusion",
                significance="Shows urgency"
            ),
            GasPriceMetric(
                metric="Gas Price Volatility",
                value="High during congestion",
                description="Price fluctuations",
                significance="Shows network activity"
            ),
            GasPriceMetric(
                metric="Average Gas Price",
                value="30-50 Gwei",
                description="Network average",
                significance="Baseline reference"
            )
        ]
        
        print("\n📋 Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric[:25]:>25} | {metric.value[:20]:>20} | "
                  f"{metric.description[:30]:>30} | {metric.significance[:30]:>30}")

class GasPriceAnalytics:
    """Additional analysis tools for gas price"""
    
    @staticmethod
    def analyze_gas_price_history() -> None:
        """Analyze gas price history"""
        print("\n 📈 GAS PRICE HISTORY")
        print("-" * 40)
        
        history = {
            "Year": ["2020", "2021", "2022", "2023", "2024"],
            "Avg Gas (Gwei)": ["40", "100", "30", "20", "35"],
            "Peak Gas (Gwei)": ["200", "500", "100", "80", "120"],
            "Typical Tx Cost": ["$1.20", "$3.00", "$0.90", "$0.60", "$1.05"],
            "Network Status": ["Normal", "Congested", "Low", "Very Low", "Normal"]
        }
        
        print("\n📋 Historical Gas Prices:")
        print(f" {'Year':>10} | {'Avg Gas':>15} | {'Peak Gas':>15} | {'Typical Cost':>20} | {'Network':>20}")
        print("-" * 85)
        
        for i in range(len(history["Year"])):
            year = history["Year"][i]
            avg = history["Avg Gas (Gwei)"][i]
            peak = history["Peak Gas (Gwei)"][i]
            cost = history["Typical Tx Cost"][i]
            status = history["Network Status"][i]
            
            print(f" {year:>10} | {avg:>15} | {peak:>15} | {cost:>20} | {status[:20]:>20}")
    
    @staticmethod
    def analyze_gas_price_optimization() -> None:
        """Analyze gas price optimization strategies"""
        print("\n ⚡ GAS PRICE OPTIMIZATION")
        print("-" * 40)
        
        strategies = {
            "Use Gas Trackers": {
                "description": "Monitor current gas prices",
                "benefit": "Send when prices are low",
                "tools": "ETH Gas Station, Blocknative",
                "saving": "30-50%"
            },
            "L2 Solutions": {
                "description": "Use Layer 2 networks",
                "benefit": "Much lower gas fees",
                "tools": "Arbitrum, Optimism, Polygon",
                "saving": "90-99%"
            },
            "Smart Routing": {
                "description": "Route through cheapest path",
                "benefit": "Optimize gas costs",
                "tools": "1inch, CowSwap",
                "saving": "10-30%"
            },
            "Time Optimization": {
                "description": "Send during off-peak hours",
                "benefit": "Lower gas prices",
                "tools": "Gas trackers with time analysis",
                "saving": "20-40%"
            }
        }
        
        print("\n📋 Optimization Strategies:")
        for strategy, details in strategies.items():
            print(f"\n  {strategy}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Tools: {details['tools']}")
            print(f"    Saving: {details['saving']}")

def demonstrate_gas_price_engine():
    """Execute comprehensive gas price demonstration"""
    print("=" * 60)
    print(" GAS PRICE FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GasPriceEngine()
    
    # Run demonstrations
    engine.explain_gas_price_overview()
    engine.list_gas_prices()
    engine.explain_gas_price_factors()
    engine.explain_gas_price_metrics()
    
    # Additional analytics
    GasPriceAnalytics.analyze_gas_price_history()
    GasPriceAnalytics.analyze_gas_price_optimization()
    
    print("\n" + "=" * 60)
    print(" GAS PRICE SUMMARY:")
    print("   ✓ Gas Price = Price per gas unit (Gwei)")
    print("   ✓ 1 Gwei = 10^-9 ETH")
    print("   ✓ Low: 10-20 Gwei (Slow)")
    print("   ✓ Standard: 30-50 Gwei (Normal)")
    print("   ✓ High: 70-100 Gwei (Fast)")
    print("   ✓ Premium: 150+ Gwei (Instant)")
    print("   ✓ Higher = Faster processing")
    print("   ✓ Check gas trackers before sending")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_gas_price_engine()

5.12 Gwei

What is Gwei?

Gwei is a unit of Ethereum that represents 10^-9 ETH. It’s commonly used to express gas prices.

Gwei Conversions:

UnitValue
1 Gwei10^-9 ETH
1 ETH10^9 Gwei
1,000 Gwei0.000001 ETH

Code Example – Gwei:

"""
GWEI FUNDAMENTALS FRAMEWORK
============================
Complete Gwei analysis and conversions
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class GweiConversion:
    """Represents a Gwei conversion value"""
    unit: str
    gwei_value: float
    eth_value: float
    description: str

@dataclass
class GweiMetric:
    """Represents a Gwei metric"""
    metric: str
    value: str
    description: str
    usage: str

class GweiEngine:
    """Complete Gwei fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" GWEI FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_gwei_overview(self) -> None:
        """Provide comprehensive Gwei overview"""
        print("\n 💎 GWEI OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  GWEI - ETHEREUM GAS PRICE UNIT                          │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Gwei = Gas price unit for Ethereum          │
│  1 Gwei = 10^-9 ETH                                      │
│                                                           │
│  CONVERSIONS:                                            │
│                                                           │
│  GWEI TO ETH:                                            │
│  • 1 Gwei = 0.000000001 ETH                             │
│  • 1,000 Gwei = 0.000001 ETH                            │
│  • 1,000,000 Gwei = 0.001 ETH                           │
│  • 1,000,000,000 Gwei = 1 ETH                           │
│                                                           │
│  ETH TO GWEI:                                            │
│  • 1 ETH = 1,000,000,000 Gwei                           │
│  • 0.1 ETH = 100,000,000 Gwei                           │
│  • 0.01 ETH = 10,000,000 Gwei                           │
│  • 0.001 ETH = 1,000,000 Gwei                           │
│                                                           │
│  COMMON GAS PRICES IN GWEI:                             │
│  • 20 Gwei = 0.00000002 ETH                             │
│  • 50 Gwei = 0.00000005 ETH                             │
│  • 100 Gwei = 0.0000001 ETH                             │
│  • 200 Gwei = 0.0000002 ETH                             │
│                                                           │
│  WHY USE GWEI:                                          │
│  ✓ Easier to express small amounts                       │
│  ✓ Common in gas calculations                            │
│  ✓ Industry standard                                     │
│  ✓ Avoids decimal confusion                              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_gwei_conversions(self) -> None:
        """List common Gwei conversions"""
        print("\n 📊 GWEI CONVERSIONS")
        print("-" * 40)
        
        conversions = [
            GweiConversion(
                unit="1 Gwei",
                gwei_value=1,
                eth_value=0.000000001,
                description="Smallest common unit"
            ),
            GweiConversion(
                unit="10 Gwei",
                gwei_value=10,
                eth_value=0.00000001,
                description="Low gas price"
            ),
            GweiConversion(
                unit="50 Gwei",
                gwei_value=50,
                eth_value=0.00000005,
                description="Standard gas price"
            ),
            GweiConversion(
                unit="100 Gwei",
                gwei_value=100,
                eth_value=0.0000001,
                description="High gas price"
            ),
            GweiConversion(
                unit="1,000 Gwei",
                gwei_value=1000,
                eth_value=0.000001,
                description="1 microETH"
            ),
            GweiConversion(
                unit="10,000 Gwei",
                gwei_value=10000,
                eth_value=0.00001,
                description="Very high gas"
            ),
            GweiConversion(
                unit="100,000 Gwei",
                gwei_value=100000,
                eth_value=0.0001,
                description="Extreme gas"
            ),
            GweiConversion(
                unit="1,000,000 Gwei",
                gwei_value=1000000,
                eth_value=0.001,
                description="1 milliETH"
            )
        ]
        
        print("\n📋 Conversion Table:")
        print(f" {'Unit':>15} | {'Gwei':>15} | {'ETH':>20} | {'Description':>20}")
        print("-" * 75)
        
        for conv in conversions:
            print(f" {conv.unit[:15]:>15} | {conv.gwei_value:>15,} | {conv.eth_value:>20.12f} | {conv.description[:20]:>20}")
    
    def explain_gwei_calculations(self) -> None:
        """Explain Gwei calculations"""
        print("\n 📊 GWEI CALCULATIONS")
        print("-" * 40)
        
        calculations = {
            "Transaction Fee Calculation": {
                "formula": "Gas Used × Gas Price (Gwei)",
                "example": "21,000 × 50 Gwei = 1,050,000 Gwei",
                "result_eth": "1,050,000 Gwei ÷ 1e9 = 0.00105 ETH",
                "result_usd": "0.00105 ETH × $3,000 = $3.15"
            },
            "Gas Price Conversion": {
                "formula": "Gwei to ETH: Gwei ÷ 1e9",
                "example": "50 Gwei = 50 ÷ 1e9 = 0.00000005 ETH",
                "result_eth": "0.00000005 ETH",
                "result_usd": "0.00000005 × $3,000 = $0.00015"
            },
            "ETH to Gwei": {
                "formula": "ETH to Gwei: ETH × 1e9",
                "example": "0.01 ETH = 0.01 × 1e9 = 10,000,000 Gwei",
                "result_eth": "10,000,000 Gwei",
                "result_usd": "10,000,000 Gwei × $3,000 = $30"
            }
        }
        
        print("\n📋 Gwei Calculations:")
        for calc_name, details in calculations.items():
            print(f"\n  {calc_name}:")
            print(f"    Formula: {details['formula']}")
            print(f"    Example: {details['example']}")
            print(f"    Result (ETH): {details['result_eth']}")
            print(f"    Result (USD): {details['result_usd']}")
    
    def explain_gwei_metrics(self) -> None:
        """Explain Gwei metrics"""
        print("\n 📊 GWEI METRICS")
        print("-" * 40)
        
        metrics = [
            GweiMetric(
                metric="Current Gas Price",
                value="20-100 Gwei",
                description="Current network gas price",
                usage="Transaction fee calculation"
            ),
            GweiMetric(
                metric="Gas Price Volatility",
                value="+/- 50 Gwei",
                description="Fluctuation range",
                usage="Understanding market conditions"
            ),
            GweiMetric(
                metric="Low Gas Price",
                value="10-20 Gwei",
                description="Slow transaction speed",
                usage="Non-urgent transfers"
            ),
            GweiMetric(
                metric="Standard Gas Price",
                value="30-50 Gwei",
                description="Normal transaction speed",
                usage="Most transactions"
            ),
            GweiMetric(
                metric="High Gas Price",
                value="70-100 Gwei",
                description="Fast transaction speed",
                usage="Time-sensitive transactions"
            ),
            GweiMetric(
                metric="Premium Gas Price",
                value="150+ Gwei",
                description="Priority transaction speed",
                usage="High-value transactions"
            )
        ]
        
        print("\n📋 Gwei Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Usage':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric[:25]:>25} | {metric.value[:20]:>20} | "
                  f"{metric.description[:30]:>30} | {metric.usage[:30]:>30}")

class GweiAnalytics:
    """Additional analysis tools for Gwei"""
    
    @staticmethod
    def analyze_gwei_units() -> None:
        """Analyze Gwei units and denominations"""
        print("\n 📈 GWEI UNITS")
        print("-" * 40)
        
        units = {
            "Unit": ["Wei", "Kwei", "Mwei", "Gwei", "Szabo", "Finney", "Ether"],
            "Value": ["1", "1,000", "1,000,000", "1,000,000,000", "1,000,000,000,000", "1,000,000,000,000,000", "1,000,000,000,000,000,000"],
            "ETH Equivalent": ["10^-18", "10^-15", "10^-12", "10^-9", "10^-6", "10^-3", "1"],
            "Common Use": ["Base unit", "Rarely used", "Rarely used", "Gas prices", "Rarely used", "Rarely used", "Common"]
        }
        
        print("\n📋 Units of ETH:")
        print(f" {'Unit':>10} | {'Value':>20} | {'ETH Equivalent':>18} | {'Common Use':>20}")
        print("-" * 75)
        
        for i in range(len(units["Unit"])):
            unit = units["Unit"][i]
            value = units["Value"][i]
            eth_eq = units["ETH Equivalent"][i]
            common = units["Common Use"][i]
            
            print(f" {unit[:10]:>10} | {value:>20} | {eth_eq:>18} | {common[:20]:>20}")
    
    @staticmethod
    def analyze_gwei_conversion_examples() -> None:
        """Analyze practical Gwei conversion examples"""
        print("\n 🔄 GWEI CONVERSION EXAMPLES")
        print("-" * 40)
        
        examples = {
            "Scenario": [
                "Gas Price 30 Gwei",
                "Gas Price 50 Gwei",
                "Gas Price 100 Gwei",
                "Gas Price 200 Gwei",
                "Gas Price 500 Gwei"
            ],
            "ETH": [
                "0.00000003",
                "0.00000005",
                "0.0000001",
                "0.0000002",
                "0.0000005"
            ],
            "Gas (21k) Cost": [
                "0.00063 ETH",
                "0.00105 ETH",
                "0.0021 ETH",
                "0.0042 ETH",
                "0.0105 ETH"
            ],
            "USD Cost ($3,000)": [
                "$1.89",
                "$3.15",
                "$6.30",
                "$12.60",
                "$31.50"
            ]
        }
        
        print("\n📋 Practical Examples:")
        print(f" {'Scenario':>18} | {'ETH':>15} | {'Gas Cost (21k)':>20} | {'USD Cost':>15}")
        print("-" * 75)
        
        for i in range(len(examples["Scenario"])):
            scenario = examples["Scenario"][i]
            eth = examples["ETH"][i]
            cost = examples["Gas (21k) Cost"][i]
            usd = examples["USD Cost ($3,000)"][i]
            
            print(f" {scenario[:18]:>18} | {eth:>15} | {cost:>20} | {usd:>15}")

def demonstrate_gwei_engine():
    """Execute comprehensive Gwei demonstration"""
    print("=" * 60)
    print(" GWEI FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GweiEngine()
    
    # Run demonstrations
    engine.explain_gwei_overview()
    engine.list_gwei_conversions()
    engine.explain_gwei_calculations()
    engine.explain_gwei_metrics()
    
    # Additional analytics
    GweiAnalytics.analyze_gwei_units()
    GweiAnalytics.analyze_gwei_conversion_examples()
    
    print("\n" + "=" * 60)
    print(" GWEI SUMMARY:")
    print("   ✓ Gwei = Gas price unit (10^-9 ETH)")
    print("   ✓ 1 ETH = 1,000,000,000 Gwei")
    print("   ✓ Common gas prices: 20-100 Gwei")
    print("   ✓ Gas Fee = Gas Used × Gas Price (Gwei)")
    print("   ✓ Gwei conversions: ETH × 1e9 = Gwei")
    print("   ✓ Gwei / 1e9 = ETH")
    print("   ✓ Industry standard for gas pricing")
    print("   ✓ Easier to express small amounts")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_gwei_engine()

5.13 Nonce

What is Nonce?

In Ethereum transactions, the nonce is a number that tracks how many transactions have been sent from a specific address. It prevents replay attacks and ensures transactions are processed in order.

Nonce Properties:

PropertyDescription
Starts at 0First transaction
Increments by 1Each new transaction
Unique per AddressNo two transactions same nonce

Code Example – Nonce:

"""
NONCE FUNDAMENTALS FRAMEWORK
=============================
Complete nonce analysis and management
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class NonceTransaction:
    """Represents a transaction with nonce"""
    nonce: int
    status: str
    description: str
    timestamp: str

@dataclass
class NonceMetric:
    """Represents a nonce metric"""
    metric: str
    value: str
    description: str
    significance: str

class NonceEngine:
    """Complete nonce fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" NONCE FUNDAMENTALS ENGINE")
        print("=" * 60)
    
    def explain_nonce_overview(self) -> None:
        """Provide comprehensive nonce overview"""
        print("\n 🔢 NONCE OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  NONCE - TRANSACTION COUNTER                             │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Nonce = Number of transactions sent         │
│  Per address, starts at 0                                 │
│                                                           │
│  PURPOSE:                                                │
│  ✓ Prevent replay attacks                                 │
│  ✓ Ensure transaction order                              │
│  ✓ Track transaction history                              │
│  ✓ Prevent double-spending                                │
│                                                           │
│  NONCE PROPERTIES:                                       │
│                                                           │
│  1. STARTS AT 0                                         │
│     • First transaction: nonce = 0                       │
│     • Second transaction: nonce = 1                      │
│     • Third transaction: nonce = 2                       │
│                                                           │
│  2. INCREMENTS BY 1                                     │
│     • Each transaction increases nonce                   │
│     • Never reused                                       │
│     • Sequential order                                   │
│                                                           │
│  3. ADDRESS-SPECIFIC                                    │
│     • Each address has its own nonce                    │
│     • Independent per address                            │
│     • Not global                                         │
│                                                           │
│  4. TRANSACTION ORDERING                                │
│     • Processed in nonce order                          │
│     • Lower nonce processed first                       │
│     • Higher nonce waits                                 │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def demonstrate_nonce_sequence(self) -> None:
        """Demonstrate nonce sequence"""
        print("\n 📊 NONCE SEQUENCE")
        print("-" * 40)
        
        transactions = [
            NonceTransaction(
                nonce=0,
                status="Completed",
                description="First transaction from address",
                timestamp="2024-01-01 10:00:00"
            ),
            NonceTransaction(
                nonce=1,
                status="Completed",
                description="Second transaction",
                timestamp="2024-01-01 10:05:00"
            ),
            NonceTransaction(
                nonce=2,
                status="Pending",
                description="Third transaction waiting",
                timestamp="2024-01-01 10:10:00"
            ),
            NonceTransaction(
                nonce=3,
                status="Queued",
                description="Fourth transaction queued",
                timestamp="2024-01-01 10:15:00"
            ),
            NonceTransaction(
                nonce=4,
                status="Queued",
                description="Fifth transaction queued",
                timestamp="2024-01-01 10:20:00"
            )
        ]
        
        print("\n📋 Transaction Sequence:")
        print(f" {'Nonce':>8} | {'Status':>15} | {'Description':>35} | {'Timestamp':>20}")
        print("-" * 85)
        
        for tx in transactions:
            print(f" {tx.nonce:>8} | {tx.status[:15]:>15} | {tx.description[:35]:>35} | {tx.timestamp[:20]:>20}")
    
    def explain_nonce_problems(self) -> None:
        """Explain common nonce problems"""
        print("\n ⚠️  NONCE PROBLEMS AND SOLUTIONS")
        print("-" * 40)
        
        problems = {
            "Stuck Transaction": {
                "description": "Transaction with nonce not processed",
                "cause": "Low gas price or network congestion",
                "solution": "Cancel or replace with higher gas",
                "prevention": "Use adequate gas price"
            },
            "Nonce Gap": {
                "description": "Missing nonce in sequence",
                "cause": "Transaction stuck, skipped nonce",
                "solution": "Wait or replace stuck transaction",
                "prevention": "Monitor pending transactions"
            },
            "Replay Attack": {
                "description": "Transaction reused on different chain",
                "cause": "Same nonce, different chain",
                "solution": "Use chain ID in transaction",
                "prevention": "Always include chain ID"
            },
            "Out of Order": {
                "description": "Transactions processed in wrong order",
                "cause": "Different nonce values",
                "solution": "Process in nonce order",
                "prevention": "Submit in sequence"
            }
        }
        
        print("\n📋 Problems and Solutions:")
        for problem, details in problems.items():
            print(f"\n  {problem}:")
            print(f"    Description: {details['description']}")
            print(f"    Cause: {details['cause']}")
            print(f"    Solution: {details['solution']}")
            print(f"    Prevention: {details['prevention']}")
    
    def explain_nonce_management(self) -> None:
        """Explain nonce management strategies"""
        print("\n 🎯 NONCE MANAGEMENT")
        print("-" * 40)
        
        strategies = {
            "Automatic Nonce": {
                "description": "Wallet automatically manages nonce",
                "benefit": "Eliminates user error",
                "best_practice": "Trust wallet implementation",
                "when_use": "Most transactions"
            },
            "Manual Nonce": {
                "description": "User sets nonce manually",
                "benefit": "Fine control over transaction ordering",
                "best_practice": "Check current nonce first",
                "when_use": "Advanced users, complex scenarios"
            },
            "Nonce Monitoring": {
                "description": "Track pending transactions",
                "benefit": "Avoid nonce gaps",
                "best_practice": "Use blockchain explorers",
                "when_use": "Multiple pending transactions"
            },
            "Transaction Replacement": {
                "description": "Replace stuck transactions",
                "benefit": "Unblock nonce sequence",
                "best_practice": "Use same nonce, higher gas",
                "when_use": "Stuck transactions"
            }
        }
        
        print("\n📋 Management Strategies:")
        for strategy, details in strategies.items():
            print(f"\n  {strategy}:")
            print(f"    Description: {details['description']}")
            print(f"    Benefit: {details['benefit']}")
            print(f"    Best Practice: {details['best_practice']}")
            print(f"    When to Use: {details['when_use']}")

class NonceAnalytics:
    """Additional analysis tools for nonce"""
    
    @staticmethod
    def analyze_nonce_metrics() -> None:
        """Analyze nonce metrics"""
        print("\n 📊 NONCE METRICS")
        print("-" * 40)
        
        metrics = [
            NonceMetric(
                metric="Current Nonce",
                value="Next expected nonce",
                description="Number of transactions sent",
                significance="Determines next transaction nonce"
            ),
            NonceMetric(
                metric="Pending Nonce",
                value="Transaction in mempool",
                description="Transactions waiting for confirmation",
                significance="Shows pending transaction count"
            ),
            NonceMetric(
                metric="Nonce Gap",
                value="Missing nonce value",
                description="Nonce not yet used",
                significance="Indicates stuck transaction"
            ),
            NonceMetric(
                metric="Nonce Order",
                value="Sequential processing",
                description="Transactions in order",
                significance="Ensures correct execution"
            ),
            NonceMetric(
                metric="Replay Protection",
                value="Chain ID included",
                description="Prevents cross-chain replay",
                significance="Security feature"
            )
        ]
        
        print("\n📋 Nonce Metrics:")
        print(f" {'Metric':>25} | {'Value':>20} | {'Description':>30} | {'Significance':>30}")
        print("-" * 110)
        
        for metric in metrics:
            print(f" {metric.metric[:25]:>25} | {metric.value[:20]:>20} | "
                  f"{metric.description[:30]:>30} | {metric.significance[:30]:>30}")
    
    @staticmethod
    def analyze_nonce_history() -> None:
        """Analyze nonce history examples"""
        print("\n 📈 NONCE HISTORY EXAMPLES")
        print("-" * 40)
        
        examples = {
            "Scenario": [
                "First Transaction",
                "Second Transaction",
                "High Gas Priority",
                "Stuck Transaction",
                "Replacement Transaction"
            ],
            "Nonce": [
                "0",
                "1",
                "5",
                "3 (stuck)",
                "3 (replaced)"
            ],
            "Status": [
                "Confirmed",
                "Confirmed",
                "Pending",
                "Stuck/Pending",
                "Confirmed"
            ],
            "Result": [
                "Success",
                "Success",
                "Waiting",
                "Not confirmed",
                "Replaced successfully"
            ]
        }
        
        print("\n📋 Historical Examples:")
        print(f" {'Scenario':>25} | {'Nonce':>10} | {'Status':>15} | {'Result':>30}")
        print("-" * 85)
        
        for i in range(len(examples["Scenario"])):
            scenario = examples["Scenario"][i]
            nonce = examples["Nonce"][i]
            status = examples["Status"][i]
            result = examples["Result"][i]
            
            print(f" {scenario[:25]:>25} | {nonce:>10} | {status[:15]:>15} | {result[:30]:>30}")

def demonstrate_nonce_engine():
    """Execute comprehensive nonce demonstration"""
    print("=" * 60)
    print(" NONCE FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = NonceEngine()
    
    # Run demonstrations
    engine.explain_nonce_overview()
    engine.demonstrate_nonce_sequence()
    engine.explain_nonce_problems()
    engine.explain_nonce_management()
    
    # Additional analytics
    NonceAnalytics.analyze_nonce_metrics()
    NonceAnalytics.analyze_nonce_history()
    
    print("\n" + "=" * 60)
    print(" NONCE SUMMARY:")
    print("   ✓ Nonce = Transaction counter per address")
    print("   ✓ Starts at 0, increments by 1")
    print("   ✓ Prevents replay attacks")
    print("   ✓ Ensures transaction order")
    print("   ✓ Address-specific (not global)")
    print("   ✓ Stuck transaction = Nonce problem")
    print("   ✓ Can replace stuck transactions")
    print("   ✓ Use chain ID for replay protection")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_nonce_engine()

5.14 Multi-Signature Wallets

What are Multi-Signature Wallets?

Multi-signature (multi-sig) wallets require multiple private keys to authorize a transaction. This adds security by distributing control.

Multi-Sig Configurations:

ConfigDescriptionUse Case
1-of-2One key neededRedundancy
2-of-3Two of three keysCommon (business)
3-of-5Three of five keysHigh security

Code Example – Multi-Signature:

"""
MULTI-SIGNATURE WALLET FRAMEWORK
=================================
Complete multi-sig fundamentals and implementation analysis
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class MultiSigType(Enum):
    """Classification of multi-sig configurations"""
    ONE_OF_TWO = "1-of-2"
    TWO_OF_THREE = "2-of-3"
    TWO_OF_TWO = "2-of-2"
    THREE_OF_FIVE = "3-of-5"
    THREE_OF_SIX = "3-of-6"
    CUSTOM = "Custom"

@dataclass
class MultiSigWallet:
    """Represents a multi-signature wallet"""
    name: str
    config_type: MultiSigType
    required_signatures: int
    total_signers: int
    security_level: str
    use_case: str
    features: List[str]

@dataclass
class MultiSigMetric:
    """Represents a multi-sig metric"""
    metric: str
    value: str
    description: str
    significance: str

class MultiSigEngine:
    """Complete multi-sig wallet demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" MULTI-SIGNATURE WALLET ENGINE")
        print("=" * 60)
    
    def explain_multisig_overview(self) -> None:
        """Provide comprehensive multi-sig overview"""
        print("\n 🔐 MULTI-SIGNATURE WALLET OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  MULTI-SIGNATURE WALLETS - DISTRIBUTED CONTROL           │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Multi-Sig = Requires M-of-N signatures      │
│  Purpose: Distributed control and enhanced security       │
│                                                           │
│  HOW IT WORKS:                                           │
│  • Create wallet with N signers                          │
│  • Set threshold M (minimum signatures required)         │
│  • Transactions need M signatures to execute             │
│  • Keys can be distributed among parties                  │
│                                                           │
│  COMMON CONFIGURATIONS:                                  │
│                                                           │
│  1-OF-2                                                 │
│  • One signature required                                │
│  • Redundancy, not security                              │
│  • Use: Backup purposes                                  │
│                                                           │
│  2-OF-3                                                 │
│  • Two signatures required                               │
│  • Most common                                           │
│  • Use: DAOs, corporate treasuries                      │
│                                                           │
│  2-OF-2                                                 │
│  • Two signatures required                               │
│  • Both must sign                                        │
│  • Use: Joint accounts                                   │
│                                                           │
│  3-OF-5                                                 │
│  • Three signatures required                             │
│  • High security                                         │
│  • Use: Institutional storage                            │
│                                                           │
│  3-OF-6                                                 │
│  • Three signatures required                             │
│  • Maximum security                                      │
│  • Use: Large organizations                              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_multisig_configurations(self) -> None:
        """List multi-sig configurations"""
        print("\n 📊 MULTI-SIG CONFIGURATIONS")
        print("-" * 40)
        
        wallets = [
            MultiSigWallet(
                name="Personal Backup",
                config_type=MultiSigType.ONE_OF_TWO,
                required_signatures=1,
                total_signers=2,
                security_level="Medium",
                use_case="Backup, redundancy",
                features=["Easy setup", "Low cost", "Simple"]
            ),
            MultiSigWallet(
                name="Joint Account",
                config_type=MultiSigType.TWO_OF_TWO,
                required_signatures=2,
                total_signers=2,
                security_level="High",
                use_case="Joint accounts, business",
                features=["Both must approve", "Shared control"]
            ),
            MultiSigWallet(
                name="Standard DAO",
                config_type=MultiSigType.TWO_OF_THREE,
                required_signatures=2,
                total_signers=3,
                security_level="High",
                use_case="DAOs, corporate treasuries",
                features=["Most common", "Balanced security", "Flexible"]
            ),
            MultiSigWallet(
                name="Institutional",
                config_type=MultiSigType.THREE_OF_FIVE,
                required_signatures=3,
                total_signers=5,
                security_level="Very High",
                use_case="Institutional storage",
                features=["High security", "Distributed", "Audit trail"]
            ),
            MultiSigWallet(
                name="Maximum Security",
                config_type=MultiSigType.THREE_OF_SIX,
                required_signatures=3,
                total_signers=6,
                security_level="Maximum",
                use_case="Large organizations",
                features=["Highest security", "Redundancy", "Complex"]
            )
        ]
        
        print("\n📋 Multi-Sig Configurations:")
        print(f" {'Name':>18} | {'Config':>12} | {'Required':>12} | {'Total':>10} | {'Security':>15} | {'Use Case':>20}")
        print("-" * 90)
        
        for wallet in wallets:
            print(f" {wallet.name[:18]:>18} | {wallet.config_type.value[:12]:>12} | "
                  f"{wallet.required_signatures:>12} | {wallet.total_signers:>10} | "
                  f"{wallet.security_level[:15]:>15} | {wallet.use_case[:20]:>20}")
        
        print("\n📋 Features:")
        for wallet in wallets[:3]:
            print(f"  • {wallet.name}: {', '.join(wallet.features)}")
    
    def explain_multisig_benefits(self) -> None:
        """Explain multi-sig benefits"""
        print("\n 💎 MULTI-SIG BENEFITS")
        print("-" * 40)
        
        benefits = {
            "Enhanced Security": {
                "description": "No single point of failure",
                "impact": "Multiple keys needed to compromise",
                "example": "Single key loss doesn't lose funds"
            },
            "Key Distribution": {
                "description": "Keys held by different parties",
                "impact": "Reduced risk of collusion",
                "example": "CEO, CFO, and legal hold keys"
            },
            "Shared Control": {
                "description": "Multiple parties approve transactions",
                "impact": "Democratic decision-making",
                "example": "DAO proposals need consensus"
            },
            "Decentralization": {
                "description": "No single authority",
                "impact": "Trust minimized",
                "example": "Community-controlled treasury"
            },
            "Audit Trail": {
                "description": "Clear approval history",
                "impact": "Transparency and accountability",
                "example": "Who signed what and when"
            }
        }
        
        print("\n📋 Benefits:")
        for benefit, details in benefits.items():
            print(f"\n  {benefit}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Example: {details['example']}")
    
    def explain_multisig_risks(self) -> None:
        """Explain multi-sig risks"""
        print("\n ⚠️  MULTI-SIG RISKS")
        print("-" * 40)
        
        risks = {
            "Key Management": {
                "description": "Managing multiple keys",
                "impact": "Lost keys = Lost access",
                "mitigation": "Backup all keys, redundant storage"
            },
            "Coordination": {
                "description": "Need multiple signers to act",
                "impact": "Transaction delays",
                "mitigation": "Clear signing policies, communication"
            },
            "Complexity": {
                "description": "More complex setup and use",
                "impact": "Higher chance of errors",
                "mitigation": "Use user-friendly multi-sig tools"
            },
            "Cost": {
                "description": "Higher gas costs for multi-sig",
                "impact": "More expensive transactions",
                "mitigation": "Batch transactions when possible"
            }
        }
        
        print("\n📋 Risks:")
        for risk, details in risks.items():
            print(f"\n  {risk}:")
            print(f"    Description: {details['description']}")
            print(f"    Impact: {details['impact']}")
            print(f"    Mitigation: {details['mitigation']}")

class MultiSigAnalytics:
    """Additional analysis tools for multi-sig"""
    
    @staticmethod
    def compare_multisig_configs() -> None:
        """Compare multi-sig configurations"""
        print("\n 📊 MULTI-SIG CONFIGURATION COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Attribute": ["Security Level", "Key Management", "Cost", "Flexibility", "Complexity"],
            "1-of-2": ["Medium", "Low", "Low", "High", "Low"],
            "2-of-2": ["High", "Medium", "Medium", "Low", "Medium"],
            "2-of-3": ["High", "Medium", "Medium", "High", "Medium"],
            "3-of-5": ["Very High", "High", "High", "High", "High"],
            "3-of-6": ["Maximum", "Very High", "Very High", "High", "Very High"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Attribute':>20} | {'1-of-2':>10} | {'2-of-2':>10} | {'2-of-3':>10} | {'3-of-5':>10} | {'3-of-6':>10}")
        print("-" * 75)
        
        for i in range(len(comparison["Attribute"])):
            attr = comparison["Attribute"][i]
            one = comparison["1-of-2"][i]
            two = comparison["2-of-2"][i]
            three = comparison["2-of-3"][i]
            five = comparison["3-of-5"][i]
            six = comparison["3-of-6"][i]
            
            print(f" {attr[:20]:>20} | {one:>10} | {two:>10} | {three:>10} | {five:>10} | {six:>10}")
    
    @staticmethod
    def analyze_multisig_use_cases() -> None:
        """Analyze multi-sig use cases"""
        print("\n 🎯 MULTI-SIG USE CASES")
        print("-" * 40)
        
        use_cases = {
            "DAOs": {
                "description": "Decentralized organizations",
                "configuration": "2-of-3 or 3-of-5",
                "benefits": ["Community control", "Transparency", "No single authority"]
            },
            "Corporate Treasuries": {
                "description": "Company crypto assets",
                "configuration": "2-of-3 or 3-of-5",
                "benefits": ["Executive approval", "Audit trail", "Security"]
            },
            "Joint Accounts": {
                "description": "Shared assets",
                "configuration": "2-of-2 or 2-of-3",
                "benefits": ["Shared control", "Mutual approval", "Transparency"]
            },
            "Institutional Storage": {
                "description": "Large asset custody",
                "configuration": "3-of-5 or 3-of-6",
                "benefits": ["Multiple custodians", "High security", "Redundancy"]
            }
        }
        
        print("\n📋 Use Cases:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Configuration: {details['configuration']}")
            print(f"    Benefits: {', '.join(details['benefits'])}")

def demonstrate_multisig_engine():
    """Execute comprehensive multi-sig demonstration"""
    print("=" * 60)
    print(" MULTI-SIGNATURE WALLET ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = MultiSigEngine()
    
    # Run demonstrations
    engine.explain_multisig_overview()
    engine.list_multisig_configurations()
    engine.explain_multisig_benefits()
    engine.explain_multisig_risks()
    
    # Additional analytics
    MultiSigAnalytics.compare_multisig_configs()
    MultiSigAnalytics.analyze_multisig_use_cases()
    
    print("\n" + "=" * 60)
    print(" MULTI-SIGNATURE WALLET SUMMARY:")
    print("   ✓ Multi-Sig = M-of-N signatures required")
    print("   ✓ Common: 2-of-3 (most popular)")
    print("   ✓ Benefits: Enhanced security, distributed control")
    print("   ✓ Use Cases: DAOs, treasuries, joint accounts")
    print("   ✓ Configurations: 1-of-2, 2-of-3, 3-of-5")
    print("   ✓ Risks: Key management, coordination, complexity")
    print("   ✓ Reduces single point of failure")
    print("   ✓ Ideal for organizations and security-sensitive users")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_multisig_engine()

5.15 Block Explorers

What are Block Explorers?

Block explorers are web applications that allow users to view blockchain data. They provide transparency and enable transaction verification.

Popular Block Explorers:

BlockchainExplorer
Bitcoinblockchain.com
Ethereumetherscan.io
Solanasolscan.io
Polygonpolygonscan.com

Code Example – Block Explorers:

"""
BLOCK EXPLORER FUNDAMENTALS FRAMEWORK
======================================
Complete block explorer analysis and usage guide
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class ExplorerType(Enum):
    """Classification of block explorer types"""
    FULL = "Full Explorer"
    LIGHT = "Light Explorer"
    TOKEN = "Token Focused"
    NFT = "NFT Explorer"
    ANALYTICS = "Analytics Explorer"

@dataclass
class BlockExplorer:
    """Represents a block explorer with its properties"""
    name: str
    explorer_type: ExplorerType
    supported_chains: List[str]
    features: List[str]
    use_case: str
    url: str

@dataclass
class ExplorerFeature:
    """Represents an explorer feature"""
    feature: str
    description: str
    benefit: str
    usage: str

class BlockExplorerEngine:
    """Complete block explorer fundamentals demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" BLOCK EXPLORER ENGINE")
        print("=" * 60)
    
    def explain_explorer_overview(self) -> None:
        """Provide comprehensive block explorer overview"""
        print("\n 🔍 BLOCK EXPLORER OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BLOCK EXPLORERS - BLOCKCHAIN VIEWER                    │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Block Explorer = Blockchain data viewer     │
│  Purpose: View and verify blockchain data                 │
│                                                           │
│  KEY FUNCTIONS:                                          │
│  ✓ View transaction details                               │
│  ✓ Check address balances                                │
│  ✓ Explore blocks                                        │
│  ✓ Verify smart contracts                                 │
│  ✓ Monitor network statistics                            │
│  ✓ Search for transactions                               │
│  ✓ View token transfers                                  │
│  ✓ Check gas prices                                      │
│                                                           │
│  DATA AVAILABLE:                                         │
│  • Transaction history                                   │
│  • Address balances                                      │
│  • Block details                                         │
│  • Mining information                                    │
│  • Network statistics                                    │
│  • Smart contract data                                   │
│  • Token information                                     │
│  • Gas price updates                                     │
│                                                           │
│  TYPES OF EXPLORERS:                                     │
│  • Full Explorers: Complete data                         │
│  • Light Explorers: Basic data                           │
│  • Token Explorers: Token-focused                        │
│  • NFT Explorers: NFT data                               │
│  • Analytics: Data analysis                              │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_block_explorers(self) -> None:
        """List popular block explorers"""
        print("\n 📊 POPULAR BLOCK EXPLORERS")
        print("-" * 40)
        
        explorers = [
            BlockExplorer(
                name="Etherscan",
                explorer_type=ExplorerType.FULL,
                supported_chains=["Ethereum", "Polygon", "BSC"],
                features=["Transaction search", "Address tracking", "Contract verification", "Token analytics"],
                use_case="Ethereum ecosystem",
                url="etherscan.io"
            ),
            BlockExplorer(
                name="Blockchain.com",
                explorer_type=ExplorerType.FULL,
                supported_chains=["Bitcoin", "Ethereum", "Bitcoin Cash"],
                features=["Block viewing", "Address lookup", "Transaction history"],
                use_case="Bitcoin ecosystem",
                url="blockchain.com/explorer"
            ),
            BlockExplorer(
                name="Solscan",
                explorer_type=ExplorerType.FULL,
                supported_chains=["Solana"],
                features=["NFT tracking", "Token analytics", "Validator stats"],
                use_case="Solana ecosystem",
                url="solscan.io"
            ),
            BlockExplorer(
                name="Polygonscan",
                explorer_type=ExplorerType.FULL,
                supported_chains=["Polygon"],
                features=["Transaction search", "Contract verification", "Token tracking"],
                use_case="Polygon ecosystem",
                url="polygonscan.com"
            ),
            BlockExplorer(
                name="BscScan",
                explorer_type=ExplorerType.FULL,
                supported_chains=["BSC"],
                features=["Transaction search", "Address tracking", "Token analytics"],
                use_case="BSC ecosystem",
                url="bscscan.com"
            )
        ]
        
        print("\n📋 Block Explorers:")
        print(f" {'Name':>15} | {'Chains':>30} | {'Features':>35} | {'URL':>20}")
        print("-" * 105)
        
        for explorer in explorers:
            chains = ', '.join(explorer.supported_chains[:3])
            features = ', '.join(explorer.features[:2])
            if len(explorer.features) > 2:
                features += f" +{len(explorer.features)-2} more"
            
            print(f" {explorer.name[:15]:>15} | {chains[:30]:>30} | {features[:35]:>35} | {explorer.url[:20]:>20}")
    
    def explain_explorer_features(self) -> None:
        """Explain block explorer features"""
        print("\n 🛠️  BLOCK EXPLORER FEATURES")
        print("-" * 40)
        
        features = [
            ExplorerFeature(
                feature="Transaction Search",
                description="Search for transactions by hash",
                benefit="Verify transaction status and details",
                usage="Check transaction confirmation"
            ),
            ExplorerFeature(
                feature="Address Lookup",
                description="View address balances and history",
                benefit="Check balances and transaction history",
                usage="Verify fund receipt or balance"
            ),
            ExplorerFeature(
                feature="Block Viewing",
                description="Explore block details",
                benefit="Verify block transactions and timestamps",
                usage="Monitor blockchain activity"
            ),
            ExplorerFeature(
                feature="Contract Verification",
                description="Verify smart contract code",
                benefit="Check contract authenticity",
                usage="Verify deployed contracts"
            ),
            ExplorerFeature(
                feature="Token Tracking",
                description="Track token transfers and holders",
                benefit="Monitor token distribution",
                usage="Analyze token activity"
            ),
            ExplorerFeature(
                feature="Network Statistics",
                description="View network metrics",
                benefit="Monitor network health",
                usage="Check gas prices, transaction volume"
            )
        ]
        
        print("\n📋 Features:")
        print(f" {'Feature':>25} | {'Description':>30} | {'Benefit':>30} | {'Usage':>30}")
        print("-" * 120)
        
        for feature in features:
            print(f" {feature.feature[:25]:>25} | {feature.description[:30]:>30} | "
                  f"{feature.benefit[:30]:>30} | {feature.usage[:30]:>30}")
    
    def explain_explorer_usage(self) -> None:
        """Explain how to use block explorers"""
        print("\n 📋 HOW TO USE BLOCK EXPLORERS")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  BLOCK EXPLORER USAGE GUIDE                              │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  CHECK TRANSACTION STATUS:                               │
│  1. Copy transaction hash                                 │
│  2. Paste into search bar                                 │
│  3. View status, confirmations, details                   │
│  4. Check gas used and fee                                │
│                                                           │
│  VIEW ADDRESS BALANCE:                                   │
│  1. Copy wallet address                                   │
│  2. Paste into search bar                                 │
│  3. View balance and transaction history                  │
│  4. Check recent activity                                 │
│                                                           │
│  EXPLORE BLOCKS:                                         │
│  1. Navigate to block section                             │
│  2. View latest blocks                                    │
│  3. Explore specific block                                │
│  4. See included transactions                             │
│                                                           │
│  VERIFY SMART CONTRACT:                                  │
│  1. Go to contract address                                │
│  2. View contract code                                    │
│  3. Check verification status                             │
│  4. Read contract source                                  │
│                                                           │
│  TRACK TOKENS:                                           │
│  1. Search token address                                  │
│  2. View holders                                          │
│  3. Check transfers                                       │
│  4. Analyze distribution                                  │
└─────────────────────────────────────────────────────────────┘
        """)

class ExplorerAnalytics:
    """Additional analysis tools for block explorers"""
    
    @staticmethod
    def compare_explorer_types() -> None:
        """Compare explorer types"""
        print("\n 📊 EXPLORER TYPE COMPARISON")
        print("-" * 40)
        
        comparison = {
            "Type": ["Full", "Light", "Token", "NFT", "Analytics"],
            "Data Depth": ["Very High", "Basic", "Medium", "Medium", "High"],
            "Speed": ["Medium", "Very Fast", "Fast", "Fast", "Slow"],
            "Complexity": ["High", "Low", "Medium", "Medium", "High"],
            "Best For": ["Complete data", "Quick checks", "Token analysis", "NFT tracking", "Research"]
        }
        
        print("\n📋 Comparison Matrix:")
        print(f" {'Type':>15} | {'Data Depth':>15} | {'Speed':>15} | {'Complexity':>15} | {'Best For':>20}")
        print("-" * 85)
        
        for i in range(len(comparison["Type"])):
            type_name = comparison["Type"][i]
            depth = comparison["Data Depth"][i]
            speed = comparison["Speed"][i]
            complexity = comparison["Complexity"][i]
            best_for = comparison["Best For"][i]
            
            print(f" {type_name[:15]:>15} | {depth[:15]:>15} | {speed[:15]:>15} | "
                  f"{complexity[:15]:>15} | {best_for[:20]:>20}")
    
    @staticmethod
    def analyze_explorer_usage() -> None:
        """Analyze explorer usage patterns"""
        print("\n 📈 EXPLORER USAGE PATTERNS")
        print("-" * 40)
        
        usage = {
            "Feature": [
                "Transaction Lookup",
                "Address Monitoring",
                "Token Tracking",
                "Contract Verification",
                "Block Exploration",
                "Gas Price Check"
            ],
            "Frequency": [
                "Very High",
                "High",
                "Medium",
                "Low",
                "Medium",
                "High"
            ],
            "User Type": [
                "All Users",
                "Investors",
                "Traders",
                "Developers",
                "Researchers",
                "Traders"
            ],
            "Importance": [
                "Critical",
                "High",
                "Medium",
                "High",
                "Low",
                "High"
            ]
        }
        
        print("\n📋 Usage Patterns:")
        print(f" {'Feature':>25} | {'Frequency':>15} | {'User Type':>20} | {'Importance':>15}")
        print("-" * 80)
        
        for i in range(len(usage["Feature"])):
            feature = usage["Feature"][i]
            frequency = usage["Frequency"][i]
            user_type = usage["User Type"][i]
            importance = usage["Importance"][i]
            
            print(f" {feature[:25]:>25} | {frequency[:15]:>15} | {user_type[:20]:>20} | {importance[:15]:>15}")

def demonstrate_block_explorer_engine():
    """Execute comprehensive block explorer demonstration"""
    print("=" * 60)
    print(" BLOCK EXPLORER FUNDAMENTALS ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = BlockExplorerEngine()
    
    # Run demonstrations
    engine.explain_explorer_overview()
    engine.list_block_explorers()
    engine.explain_explorer_features()
    engine.explain_explorer_usage()
    
    # Additional analytics
    ExplorerAnalytics.compare_explorer_types()
    ExplorerAnalytics.analyze_explorer_usage()
    
    print("\n" + "=" * 60)
    print(" BLOCK EXPLORER SUMMARY:")
    print("   ✓ Block Explorer = Blockchain data viewer")
    print("   ✓ Popular: Etherscan, Blockchain.com, Solscan")
    print("   ✓ Features: Transaction search, address lookup")
    print("   ✓ Data: Balances, history, blocks, tokens")
    print("   ✓ Use Cases: Verification, monitoring, research")
    print("   ✓ Essential for blockchain transparency")
    print("   ✓ Verify all transactions on explorer")
    print("   ✓ Free and accessible to everyone")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_block_explorer_engine()

5.16 Wallet Security

What is Wallet Security?

Wallet security is the protection of cryptocurrency private keys and funds from unauthorized access, theft, and loss. It’s the most important aspect of cryptocurrency ownership.

Security Best Practices:

PracticeDescription
Seed Phrase BackupWrite down, store securely
Cold StorageKeep keys offline
Multi-SigDistribute control
Two-Factor AuthenticationAdditional security layer
Regular UpdatesKeep software current

Code Example – Wallet Security:

"""
WALLET SECURITY FUNDAMENTALS FRAMEWORK
=======================================
Complete wallet security analysis and best practices
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

class SecurityLevel(Enum):
    """Classification of security levels"""
    BASIC = "Basic Security"
    STANDARD = "Standard Security"
    HIGH = "High Security"
    MAXIMUM = "Maximum Security"

@dataclass
class SecurityLayer:
    """Represents a security layer"""
    layer_name: str
    description: str
    implementation: str
    protection_level: str

@dataclass
class SecurityMetric:
    """Represents a security metric"""
    metric: str
    value: str
    description: str
    significance: str

class WalletSecurityEngine:
    """Complete wallet security demonstration suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" WALLET SECURITY ENGINE")
        print("=" * 60)
    
    def explain_security_overview(self) -> None:
        """Provide comprehensive security overview"""
        print("\n 🛡️  WALLET SECURITY OVERVIEW")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  WALLET SECURITY - PRIVATE KEY PROTECTION                │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  DEFINITION: Wallet Security = Protection of private keys│
│  Purpose: Prevent unauthorized access to funds            │
│                                                           │
│  SECURITY LAYERS:                                        │
│                                                           │
│  1. SEED PHRASE SECURITY                                 │
│     • Write on paper or metal                            │
│     • Store in secure location                           │
│     • Multiple copies                                     │
│     • Never store digitally                              │
│     • Never share with anyone                            │
│                                                           │
│  2. HARDWARE WALLET                                     │
│     • Private key offline                                 │
│     • PIN protection                                      │
│     • Secure chip                                        │
│     • Physical verification                               │
│                                                           │
│  3. MULTI-SIGNATURE                                      │
│     • Multiple keys required                             │
│     • Distributed control                                 │
│     • Shared responsibility                              │
│     • Reduced single point of failure                    │
│                                                           │
│  4. TWO-FACTOR AUTHENTICATION                            │
│     • Additional verification layer                      │
│     • SMS or authenticator                               │
│     • Prevents unauthorized access                       │
│                                                           │
│  5. REGULAR UPDATES                                      │
│     • Software updates                                    │
│     • Security patches                                    │
│     • Latest features                                     │
│     • Bug fixes                                          │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def list_security_layers(self) -> None:
        """List security layers"""
        print("\n 📊 SECURITY LAYERS")
        print("-" * 40)
        
        layers = [
            SecurityLayer(
                layer_name="Seed Phrase Backup",
                description="Physical backup of recovery phrase",
                implementation="Paper, metal, or steel storage",
                protection_level="Critical"
            ),
            SecurityLayer(
                layer_name="Hardware Wallet",
                description="Physical device for key storage",
                implementation="Ledger, Trezor, SafePal",
                protection_level="Maximum"
            ),
            SecurityLayer(
                layer_name="Multi-Signature",
                description="Multiple signatures required",
                implementation="2-of-3, 3-of-5 configurations",
                protection_level="High"
            ),
            SecurityLayer(
                layer_name="Two-Factor Authentication",
                description="Second verification step",
                implementation="Authenticator app, SMS",
                protection_level="Medium-High"
            ),
            SecurityLayer(
                layer_name="Software Updates",
                description="Regular security patches",
                implementation="Automatic or manual updates",
                protection_level="Medium"
            ),
            SecurityLayer(
                layer_name="Strong Passwords",
                description="Complex, unique passwords",
                implementation="Password manager, unique passwords",
                protection_level="Medium"
            )
        ]
        
        print("\n📋 Security Layers:")
        print(f" {'Layer Name':>25} | {'Description':>35} | {'Implementation':>30} | {'Protection':>15}")
        print("-" * 110)
        
        for layer in layers:
            print(f" {layer.layer_name[:25]:>25} | {layer.description[:35]:>35} | "
                  f"{layer.implementation[:30]:>30} | {layer.protection_level[:15]:>15}")
    
    def explain_common_mistakes(self) -> None:
        """Explain common security mistakes"""
        print("\n ⚠️  COMMON SECURITY MISTAKES")
        print("-" * 40)
        
        mistakes = {
            "Digital Seed Storage": {
                "description": "Storing seed phrase on devices",
                "risk": "Exposed to malware, hackers",
                "consequence": "Funds stolen",
                "solution": "Physical storage only"
            },
            "Sharing Private Keys": {
                "description": "Sharing keys with others",
                "risk": "Unauthorized access",
                "consequence": "Funds stolen",
                "solution": "Never share private keys"
            },
            "Weak Passwords": {
                "description": "Using simple passwords",
                "risk": "Brute force attacks",
                "consequence": "Account compromised",
                "solution": "Strong, unique passwords"
            },
            "Ignoring Updates": {
                "description": "Not updating software",
                "risk": "Known vulnerabilities",
                "consequence": "Exploited by attackers",
                "solution": "Regular updates"
            },
            "No Backup": {
                "description": "No backup of seed phrase",
                "risk": "Lost access to funds",
                "consequence": "Funds lost forever",
                "solution": "Multiple backups"
            },
            "Phishing": {
                "description": "Falling for fake websites",
                "risk": "Seed phrase theft",
                "consequence": "Funds stolen",
                "solution": "Verify URLs, use bookmarks"
            }
        }
        
        print("\n📋 Common Mistakes:")
        for mistake, details in mistakes.items():
            print(f"\n  {mistake}:")
            print(f"    Description: {details['description']}")
            print(f"    Risk: {details['risk']}")
            print(f"    Consequence: {details['consequence']}")
            print(f"    Solution: {details['solution']}")
    
    def explain_security_best_practices(self) -> None:
        """Explain security best practices"""
        print("\n ✅ SECURITY BEST PRACTICES")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  SECURITY BEST PRACTICES                                 │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  SEED PHRASE MANAGEMENT:                                │
│  ✅ Write on paper or metal                              │
│  ✅ Store in multiple locations                          │
│  ✅ Use fireproof/waterproof storage                     │
│  ✅ Test recovery process                               │
│  ❌ Never store digitally                               │
│  ❌ Never share with anyone                             │
│                                                           │
│  WALLET SELECTION:                                      │
│  ✅ Use hardware wallet for large holdings              │
│  ✅ Verify wallet authenticity                          │
│  ✅ Use official sources                                │
│  ✅ Check reviews and audits                            │
│  ❌ Avoid unknown/untrusted wallets                     │
│                                                           │
│  TRANSACTION SECURITY:                                  │
│  ✅ Verify addresses before sending                     │
│  ✅ Check transaction details                           │
│  ✅ Use test transactions for large amounts             │
│  ✅ Double-check everything                             │
│  ❌ Never rush transactions                             │
│                                                           │
│  GENERAL SECURITY:                                      │
│  ✅ Enable 2FA                                         │
│  ✅ Keep software updated                               │
│  ✅ Use secure networks                                 │
│  ✅ Monitor account activity                            │
│  ❌ Avoid public Wi-Fi for transactions                 │
└─────────────────────────────────────────────────────────────┘
        """)

class SecurityAnalytics:
    """Additional analysis tools for wallet security"""
    
    @staticmethod
    def analyze_security_levels() -> None:
        """Analyze security levels"""
        print("\n 📊 SECURITY LEVELS")
        print("-" * 40)
        
        levels = {
            "Level": ["Basic", "Standard", "High", "Maximum"],
            "Security Features": ["Password", "2FA", "Hardware Wallet", "Multi-Sig"],
            "Risk Level": ["High", "Medium", "Low", "Very Low"],
            "Best For": ["Small amounts", "Medium amounts", "Large amounts", "Institutions"]
        }
        
        print("\n📋 Security Level Matrix:")
        print(f" {'Level':>12} | {'Security Features':>30} | {'Risk Level':>15} | {'Best For':>20}")
        print("-" * 85)
        
        for i in range(len(levels["Level"])):
            level = levels["Level"][i]
            features = levels["Security Features"][i]
            risk = levels["Risk Level"][i]
            best_for = levels["Best For"][i]
            
            print(f" {level[:12]:>12} | {features[:30]:>30} | {risk[:15]:>15} | {best_for[:20]:>20}")
    
    @staticmethod
    def analyze_attack_vectors() -> None:
        """Analyze common attack vectors"""
        print("\n 🎯 COMMON ATTACK VECTORS")
        print("-" * 40)
        
        attacks = {
            "Phishing": {
                "method": "Fake websites/emails",
                "target": "Seed phrase, private keys",
                "prevention": "Verify URLs, use bookmarks",
                "impact": "Critical"
            },
            "Malware": {
                "method": "Keyloggers, clipboard hijackers",
                "target": "Private keys, passwords",
                "prevention": "Antivirus, safe downloads",
                "impact": "High"
            },
            "Social Engineering": {
                "method": "Trick users into revealing info",
                "target": "Seed phrase, security info",
                "prevention": "Educate, verify identities",
                "impact": "High"
            },
            "SIM Swapping": {
                "method": "Take over phone number",
                "target": "2FA SMS codes",
                "prevention": "Use authenticator apps",
                "impact": "Medium-High"
            },
            "Man-in-the-Middle": {
                "method": "Intercept communications",
                "target": "Transaction data",
                "prevention": "Use HTTPS, secure networks",
                "impact": "Medium"
            }
        }
        
        print("\n📋 Attack Vectors:")
        for attack, details in attacks.items():
            print(f"\n  {attack}:")
            print(f"    Method: {details['method']}")
            print(f"    Target: {details['target']}")
            print(f"    Prevention: {details['prevention']}")
            print(f"    Impact: {details['impact']}")

def demonstrate_security_engine():
    """Execute comprehensive wallet security demonstration"""
    print("=" * 60)
    print(" WALLET SECURITY ENGINE DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = WalletSecurityEngine()
    
    # Run demonstrations
    engine.explain_security_overview()
    engine.list_security_layers()
    engine.explain_common_mistakes()
    engine.explain_security_best_practices()
    
    # Additional analytics
    SecurityAnalytics.analyze_security_levels()
    SecurityAnalytics.analyze_attack_vectors()
    
    print("\n" + "=" * 60)
    print(" WALLET SECURITY SUMMARY:")
    print("   ✓ Security = Private key protection")
    print("   ✓ Layers: Seed, hardware, multi-sig, 2FA")
    print("   ✓ Never share seed phrase or private keys")
    print("   ✓ Hardware wallet for large holdings")
    print("   ✓ Backup seed phrase securely offline")
    print("   ✓ Regular updates and strong passwords")
    print("   ✓ Security is your responsibility")
    print("   ✓ Follow best practices always")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_security_engine()

PHASE 1 – COMPLETE PROJECT

Blockchain Explorer & Wallet System

Complete Project: A fully functional blockchain explorer and wallet system with real-time transaction tracking, balance checking, and transaction history.

"""
DISTRIBUTED LEDGER EXPLORER & ASSET MANAGEMENT SUITE
====================================================
A fully functional blockchain explorer and wallet system
with real-time transaction tracking, balance checking,
and transaction history.

Features:
- View blockchain blocks
- Check account balances
- Send transactions
- View transaction history
- Mempool monitoring
- Block mining simulation
- Wallet management
- Transaction signing
"""

import hashlib
import json
import time
import secrets
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
from datetime import datetime
import random

# ============================================================================
# CORE BLOCKCHAIN COMPONENTS
# ============================================================================

@dataclass
class TransferRecord:
    """Blockchain transaction record"""
    record_hash: str
    sender: str
    recipient: str
    value: float
    processing_fee: float
    timestamp: float
    block_position: Optional[int] = None
    settlement_status: str = "Pending"
    verifications: int = 0

    def to_summary(self) -> Dict:
        return {
            "hash": self.record_hash[:16] + "...",
            "from": self.sender[:12] + "...",
            "to": self.recipient[:12] + "...",
            "amount": self.value,
            "fee": self.processing_fee,
            "status": self.settlement_status,
            "confirmations": self.verifications,
            "time": datetime.fromtimestamp(self.timestamp).strftime("%Y-%m-%d %H:%M:%S")
        }

@dataclass
class LedgerBlock:
    """Blockchain block"""
    sequence: int
    records: List[TransferRecord]
    timestamp: float
    prior_digest: str
    digest: str
    puzzle_solution: int = 0

    def to_summary(self) -> Dict:
        return {
            "index": self.sequence,
            "hash": self.digest[:16] + "...",
            "previous": self.prior_digest[:16] + "...",
            "transactions": len(self.records),
            "time": datetime.fromtimestamp(self.timestamp).strftime("%Y-%m-%d %H:%M:%S")
        }

class DistributedLedger:
    """Complete blockchain implementation"""

    def __init__(self):
        self.chain: List[LedgerBlock] = []
        self.unconfirmed_records: List[TransferRecord] = []
        self.account_holdings: Dict[str, float] = {}
        self.record_history: Dict[str, List[TransferRecord]] = {}
        self.complexity = 3
        self.block_subsidy = 10

        # Create genesis block
        self.initialize_genesis()
        print(" 📊 Distributed Ledger initialized!")

    def initialize_genesis(self):
        """Create the genesis block"""
        genesis_record = TransferRecord(
            record_hash="0" * 64,
            sender="GENESIS",
            recipient="GENESIS",
            value=0,
            processing_fee=0,
            timestamp=time.time(),
            settlement_status="Confirmed",
            verifications=1
        )

        genesis_block = LedgerBlock(
            sequence=0,
            records=[genesis_record],
            timestamp=time.time(),
            prior_digest="0" * 64,
            digest=hashlib.sha256(b"genesis").hexdigest()
        )
        self.chain.append(genesis_block)
        print(" 🔱 Genesis block established")

    def submit_transfer(self, sender: str, recipient: str, value: float) -> Optional[TransferRecord]:
        """Create a new transfer record"""
        # Validate
        if value <= 0:
            print(" ❌ Value must be positive")
            return None

        if sender != "MINING_REWARD":
            balance = self.query_holdings(sender)
            if balance < value:
                print(f" ❌ Insufficient funds: {balance:.2f} < {value:.2f}")
                return None

        # Create transfer record
        record_hash = hashlib.sha256(
            f"{sender}{recipient}{value}{time.time()}".encode()
        ).hexdigest()

        record = TransferRecord(
            record_hash=record_hash,
            sender=sender,
            recipient=recipient,
            value=value,
            processing_fee=0.001,
            timestamp=time.time(),
            settlement_status="Pending"
        )

        self.unconfirmed_records.append(record)
        print(f" 📝 Transfer created: {record_hash[:16]}...")
        return record

    def process_block(self, beneficiary: str):
        """Process pending transfers into a block"""
        if not self.unconfirmed_records:
            print(" ⏳ No pending transfers to process")
            return

        # Add block reward
        reward_record = self.submit_transfer("MINING_REWARD", beneficiary, self.block_subsidy)
        if reward_record:
            reward_record.settlement_status = "Pending"
            self.unconfirmed_records.append(reward_record)

        # Create block
        new_block = LedgerBlock(
            sequence=len(self.chain),
            records=self.unconfirmed_records.copy(),
            timestamp=time.time(),
            prior_digest=self.chain[-1].digest,
            digest=""
        )

        # Solve the puzzle
        target = "0" * self.complexity
        while new_block.digest[:self.complexity] != target:
            new_block.puzzle_solution += 1
            new_block.digest = hashlib.sha256(
                f"{new_block.sequence}{new_block.prior_digest}{new_block.puzzle_solution}{time.time()}".encode()
            ).hexdigest()

        # Append to chain
        self.chain.append(new_block)

        # Update records
        for record in new_block.records:
            record.settlement_status = "Confirmed"
            record.block_position = new_block.sequence
            record.verifications = 1

        # Clear pending
        self.unconfirmed_records = []
        print(f" ⛏️  Block {new_block.sequence} processed! ({len(new_block.records)} transfers)")

    def query_holdings(self, account: str) -> float:
        """Get balance for an account"""
        if account == "MINING_REWARD":
            return float('inf')

        balance = 0.0
        for block in self.chain:
            for record in block.records:
                if record.sender == account:
                    balance -= record.value
                if record.recipient == account:
                    balance += record.value

        return balance

    def fetch_transfers(self, account: str, limit: int = 20) -> List[Dict]:
        """Get transfer history for an account"""
        transfers = []
        for block in reversed(self.chain):
            for record in block.records:
                if record.sender == account or record.recipient == account:
                    record.verifications = len(self.chain) - record.block_position if record.block_position else 0
                    transfers.append(record.to_summary())
                    if len(transfers) >= limit:
                        return transfers

        # Add pending transfers
        for record in self.unconfirmed_records:
            if record.sender == account or record.recipient == account:
                transfers.append(record.to_summary())

        return transfers

    def retrieve_block(self, sequence: int) -> Optional[Dict]:
        """Get block by sequence"""
        if 0 <= sequence < len(self.chain):
            block = self.chain[sequence]
            return block.to_summary()
        return None

    def fetch_recent_blocks(self, count: int = 10) -> List[Dict]:
        """Get recent blocks"""
        return [block.to_summary() for block in self.chain[-count:][::-1]]

    def compile_metrics(self) -> Dict:
        """Get blockchain statistics"""
        total_records = sum(len(block.records) for block in self.chain)
        return {
            "blocks": len(self.chain),
            "transactions": total_records,
            "pending": len(self.unconfirmed_records),
            "difficulty": self.complexity,
            "reward": self.block_subsidy
        }


# ============================================================================
# BLOCKCHAIN EXPLORER
# ============================================================================

class LedgerExplorer:
    """Interactive blockchain explorer"""

    def __init__(self, ledger: DistributedLedger):
        self.ledger = ledger

    def display_blocks(self):
        """View all blocks"""
        print("\n" + "=" * 60)
        print(" 🔍 LEDGER EXPLORER")
        print("=" * 60)

        print(f"\n 📊 Ledger Metrics:")
        metrics = self.ledger.compile_metrics()
        for key, value in metrics.items():
            print(f"   {key}: {value}")

        print("\n 🏗️  Recent Blocks:")
        for block in self.ledger.fetch_recent_blocks(10):
            print(f"   Block #{block['index']:>4} | Hash: {block['hash']:>20} | "
                  f"Records: {block['transactions']:>2} | {block['time']}")

    def inspect_account(self, account: str):
        """View transfers for an account"""
        print("\n" + "=" * 60)
        print(f" 📋 TRANSFER HISTORY FOR: {account[:16]}...")
        print("=" * 60)

        balance = self.ledger.query_holdings(account)
        print(f"\n 💰 Balance: {balance:.2f} units")

        transfers = self.ledger.fetch_transfers(account)
        if not transfers:
            print(" 📭 No transfers found")
            return

        print("\n 📜 Transfer History:")
        for transfer in transfers[:10]:
            status_marker = "" if transfer['status'] == "Confirmed" else ""
            print(f"   {status_marker} {transfer['time']} | {transfer['from']} → {transfer['to']} | {transfer['amount']} units")


# ============================================================================
# WALLET SYSTEM
# ============================================================================

class AssetVault:
    """Cryptocurrency wallet"""

    def __init__(self, ledger: DistributedLedger):
        self.ledger = ledger
        self.accounts: Dict[str, Dict] = {}
        self.active_account: Optional[str] = None
        self.recovery_phrase = self._generate_recovery_phrase()
        print(f" 🔐 Vault created with recovery phrase: {self.recovery_phrase[:20]}...")

    def _generate_recovery_phrase(self) -> str:
        """Generate a recovery phrase (12 words)"""
        word_pool = [
            "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"
        ]
        return " ".join(random.sample(word_pool, 12))

    def register_account(self, label: str, initial_funds: float = 0):
        """Create a new wallet account"""
        private_key = secrets.token_hex(32)
        public_key = hashlib.sha256(private_key.encode()).hexdigest()
        address = f"0x{hashlib.md5(public_key.encode()).hexdigest()[:16]}"

        self.accounts[address] = {
            "label": label,
            "private_key": private_key,
            "public_key": public_key,
            "balance": initial_funds
        }

        # Add initial funds through mining
        if initial_funds > 0:
            record = self.ledger.submit_transfer("MINING_REWARD", address, initial_funds)
            if record:
                self.ledger.process_block(address)

        self.active_account = address
        print(f" ✅ Account created: {address[:16]}... ({label})")
        print(f"   🔑 Private Key: {private_key[:16]}... (SAVE THIS!)")
        return address

    def check_balance(self, account: Optional[str] = None) -> float:
        """Get wallet balance"""
        target = account or self.active_account
        if not target:
            print(" ❌ No account selected")
            return 0
        return self.ledger.query_holdings(target)

    def initiate_transfer(self, destination: str, value: float) -> Optional[TransferRecord]:
        """Send funds to another account"""
        if not self.active_account:
            print(" ❌ No account selected")
            return None

        if destination not in self.accounts:
            print(f" ⚠️  Recipient not in vault: {destination[:16]}...")

        record = self.ledger.submit_transfer(self.active_account, destination, value)
        if record:
            print(f" 💸 Sent {value:.2f} units to {destination[:16]}...")
            return record
        return None

    def display_vault_info(self):
        """Display vault information"""
        print("\n" + "=" * 60)
        print(" 🏦 VAULT INFORMATION")
        print("=" * 60)

        print(f"\n 🔑 Recovery Phrase: {self.recovery_phrase}")
        print("  ⚠️  NEVER SHARE YOUR RECOVERY PHRASE!\n")

        if not self.accounts:
            print(" 📭 No accounts found. Create one first!")
            return

        for addr, info in self.accounts.items():
            balance = self.ledger.query_holdings(addr)
            is_active = "▶ " if addr == self.active_account else "   "
            print(f"{is_active} {info['label']:12} | {addr[:16]}... | Balance: {balance:.2f} units")


# ============================================================================
# MAIN APPLICATION
# ============================================================================

def run_demo():
    """Main application entry point"""
    print("=" * 60)
    print(" 🚀 DISTRIBUTED LEDGER EXPLORER & VAULT SUITE")
    print("=" * 60)

    # Initialize ledger
    ledger = DistributedLedger()
    explorer = LedgerExplorer(ledger)
    vault = AssetVault(ledger)

    # Create some accounts
    print("\n" + "=" * 60)
    print(" 🏗️  CREATING ACCOUNTS")
    print("=" * 60)

    alice_addr = vault.register_account("Alice", 100)
    bob_addr = vault.register_account("Bob", 50)
    charlie_addr = vault.register_account("Charlie", 0)

    # Execute transfers
    print("\n" + "=" * 60)
    print(" 🔄 EXECUTING TRANSFERS")
    print("=" * 60)

    vault.active_account = alice_addr
    vault.initiate_transfer(bob_addr, 25)
    vault.initiate_transfer(charlie_addr, 10)

    vault.active_account = bob_addr
    vault.initiate_transfer(charlie_addr, 5)

    # Process block
    print("\n" + "=" * 60)
    print(" ⛏️  PROCESSING BLOCK")
    print("=" * 60)

    ledger.process_block(alice_addr)

    # Execute more transfers
    print("\n" + "=" * 60)
    print(" 🔄 MORE TRANSFERS")
    print("=" * 60)

    vault.active_account = charlie_addr
    vault.initiate_transfer(alice_addr, 3)

    vault.active_account = alice_addr
    vault.initiate_transfer(bob_addr, 8)

    # Process another block
    print("\n" + "=" * 60)
    print(" ⛏️  PROCESSING ANOTHER BLOCK")
    print("=" * 60)

    ledger.process_block(bob_addr)

    # Display final state
    print("\n" + "=" * 60)
    print(" 📊 FINAL STATE")
    print("=" * 60)

    vault.display_vault_info()
    explorer.display_blocks()

    # View individual transfer histories
    print("\n" + "=" * 60)
    print(" 📋 TRANSFER HISTORIES")
    print("=" * 60)

    for name, addr in [("Alice", alice_addr), ("Bob", bob_addr), ("Charlie", charlie_addr)]:
        explorer.inspect_account(addr)

    print("\n" + "=" * 60)
    print(" ✅ DEMONSTRATION COMPLETE!")
    print("=" * 60)

if __name__ == "__main__":
    run_demo()

PHASE 2: WEB3 DEVELOPMENT & DECENTRALIZED APPLICATIONS

Build Smart Contracts, Tokens, and Decentralized Applications

1. Web3 Fundamentals

1.1 Web1 vs Web2 vs Web3

Web1 (The Read-Only Web – 1990s-2000s):
The first generation of the internet was static and read-only. Users could only consume content created by a small number of publishers. Websites were simple HTML pages with basic text and images. There was no interaction, no user-generated content, and no dynamic applications.

Example: A personal homepage with basic HTML, an online encyclopedia that only displays information, a news website where you can only read articles.

Web2 (The Read-Write Web – 2000s-Present):
The second generation of the web introduced interactivity, dynamic content, and user-generated content.Platforms like Facebook, YouTube, Twitter, and Google allowed users to create, share, and interact with content. However, these platforms are centralized – a few companies control all the data, content, and user interactions.

Example: Facebook where you post photos but Facebook owns your data, YouTube where you upload videos but YouTube controls monetization, Amazon where you shop but Amazon controls the marketplace.

Web3 (The Read-Write-Own Web – Emerging):
The third generation is built on blockchain technology. Users not only create and consume content but also own their data, digital assets, and participate in platform governance. Web3 applications are decentralized, permissionless, and trustless.

Example: Uniswap where you trade tokens without a central exchange, OpenSea where you own your NFTs, DAOs where you vote on governance decisions.

Code Example – Web Evolution Comparison:

"""
WEB EVOLUTION FRAMEWORK
========================
Comprehensive comparison of Web1, Web2, and Web3 generations
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class WebGeneration:
    """Represents a web generation"""
    name: str
    era: str
    description: str
    characteristics: List[str]
    examples: List[str]
    technology: List[str]
    control: str
    data_ownership: str
    monetization: List[str]

@dataclass
class FeatureComparison:
    """Represents a feature comparison across generations"""
    feature: str
    web1: str
    web2: str
    web3: str

class WebEvolutionEngine:
    """Complete Web1 vs Web2 vs Web3 comparison suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" WEB EVOLUTION ENGINE")
        print("=" * 60)
    
    def display_generations(self) -> None:
        """Display all web generations"""
        print("\n 🌐 WEB GENERATIONS OVERVIEW")
        print("-" * 40)
        
        generations = [
            WebGeneration(
                name="Web1 (The Read-Only Web)",
                era="1990s - 2000s",
                description="Static, read-only content",
                characteristics=[
                    "Static HTML pages",
                    "Read-only content",
                    "Few content creators",
                    "No user interaction",
                    "Centralized hosting"
                ],
                examples=[
                    "Personal homepages",
                    "Online encyclopedias",
                    "News websites"
                ],
                technology=["HTML", "CSS", "HTTP"],
                control="Centralized (companies, ISPs)",
                data_ownership="Publisher owns data",
                monetization=["Advertising"]
            ),
            WebGeneration(
                name="Web2 (The Read-Write Web)",
                era="2000s - Present",
                description="Interactive, user-generated content",
                characteristics=[
                    "User-generated content",
                    "Social media platforms",
                    "Interactive applications",
                    "Data collection",
                    "Centralized services"
                ],
                examples=[
                    "Facebook, Twitter, YouTube",
                    "Google, Amazon, Netflix",
                    "Mobile apps, Cloud computing"
                ],
                technology=["JavaScript", "AJAX", "APIs", "Cloud"],
                control="Centralized (Big Tech companies)",
                data_ownership="Platform owns data",
                monetization=["Advertising", "Subscriptions", "Data selling"]
            ),
            WebGeneration(
                name="Web3 (The Read-Write-Own Web)",
                era="2015 - Future",
                description="Decentralized, user-owned, trustless",
                characteristics=[
                    "Decentralized applications (dApps)",
                    "User-owned data",
                    "Cryptocurrency payments",
                    "Smart contracts",
                    "Token-based governance"
                ],
                examples=[
                    "Uniswap, OpenSea",
                    "DAOs (Decentralized Autonomous Organizations)",
                    "NFT marketplaces, DeFi protocols"
                ],
                technology=["Blockchain", "Smart Contracts", "IPFS", "ZKPs"],
                control="Decentralized (users, protocols)",
                data_ownership="User owns data",
                monetization=["Token sales", "Transaction fees", "NFTs", "DeFi"]
            )
        ]
        
        print("\n📋 Web Generations:")
        for gen in generations:
            print(f"\n  {gen.name}")
            print(f"    Era: {gen.era}")
            print(f"    Description: {gen.description}")
            print(f"    Control: {gen.control}")
            print(f"    Data Ownership: {gen.data_ownership}")
            print(f"    Technology: {', '.join(gen.technology)}")
            print(f"    Examples: {', '.join(gen.examples[:3])}")
            print(f"    Monetization: {', '.join(gen.monetization)}")
    
    def compare_features(self) -> None:
        """Compare features across generations"""
        print("\n 📊 FEATURE COMPARISON")
        print("-" * 40)
        
        comparisons = [
            FeatureComparison(
                feature="Data Ownership",
                web1="Publisher owns data",
                web2="Platform owns data",
                web3="User owns data"
            ),
            FeatureComparison(
                feature="Content Creation",
                web1="Publishers only",
                web2="All users",
                web3="All users (with ownership)"
            ),
            FeatureComparison(
                feature="Monetization",
                web1="Advertising",
                web2="Advertising, subscriptions",
                web3="Token-based, NFTs, DeFi"
            ),
            FeatureComparison(
                feature="Identity",
                web1="Anonymous",
                web2="Platform accounts",
                web3="Self-sovereign identity"
            ),
            FeatureComparison(
                feature="Governance",
                web1="Centralized",
                web2="Centralized",
                web3="Community DAOs"
            ),
            FeatureComparison(
                feature="Censorship Resistance",
                web1="ISP level",
                web2="Platform level",
                web3="Censorship-resistant"
            ),
            FeatureComparison(
                feature="Security",
                web1="Basic HTTP",
                web2="HTTPS, 2FA",
                web3="Cryptographic"
            ),
            FeatureComparison(
                feature="Interactivity",
                web1="Low",
                web2="High",
                web3="Very High"
            ),
            FeatureComparison(
                feature="Privacy",
                web1="Low",
                web2="Low (data collected)",
                web3="High (user controlled)"
            ),
            FeatureComparison(
                feature="Trust Model",
                web1="Trust in publishers",
                web2="Trust in platforms",
                web3="Trustless (cryptographic)"
            )
        ]
        
        print("\n📋 Feature Comparison Matrix:")
        print(f" {'Feature':>25} | {'Web1':>25} | {'Web2':>25} | {'Web3':>25}")
        print("-" * 105)
        
        for comp in comparisons:
            print(f" {comp.feature[:25]:>25} | {comp.web1[:25]:>25} | {comp.web2[:25]:>25} | {comp.web3[:25]:>25}")
    
    def explain_evolution(self) -> None:
        """Explain the evolution of the web"""
        print("\n 🔄 WEB EVOLUTION TIMELINE")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  WEB EVOLUTION TIMELINE                                  │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  1990s - 2000s: Web1                                    │
│  • Static HTML pages                                      │
│  • Read-only content                                      │
│  • Publishers controlled content                         │
│  • Information access improved                            │
│  • Dot-com boom                                           │
│                                                           │
│  2000s - Present: Web2                                  │
│  • User-generated content                                 │
│  • Social media platforms                                 │
│  • Interactive applications                               │
│  • Mobile revolution                                      │
│  • Data economy                                           │
│  • Big Tech dominance                                     │
│                                                           │
│  2015 - Future: Web3                                    │
│  • Decentralized applications                             │
│  • User-owned data                                        │
│  • Blockchain technology                                  │
│  • Cryptocurrency economy                                 │
│  • DAOs and governance                                    │
│  • User sovereignty                                       │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def explain_key_concepts(self) -> None:
        """Explain key concepts of each generation"""
        print("\n 💡 KEY CONCEPTS")
        print("-" * 40)
        
        concepts = {
            "Web1 Concepts": [
                "Static pages: Content doesn't change",
                "Hyperlinks: Navigation between pages",
                "Search engines: Finding information",
                "Email: Digital communication",
                "E-commerce: Online shopping"
            ],
            "Web2 Concepts": [
                "User generated: Anyone can create content",
                "Social networks: Connecting people",
                "Mobile apps: Smartphone revolution",
                "Cloud computing: Scalable infrastructure",
                "API economy: Service integration",
                "Data as asset: User data monetization"
            ],
            "Web3 Concepts": [
                "Decentralization: No single point of control",
                "Blockchain: Trustless transactions",
                "Smart contracts: Automated agreements",
                "Token economy: Digital ownership",
                "DAOs: Decentralized governance",
                "Self-sovereign identity: User-controlled identity",
                "Interoperability: Seamless integration"
            ]
        }
        
        print("\n📋 Key Concepts:")
        for generation, items in concepts.items():
            print(f"\n  {generation}:")
            for item in items:
                print(f"    • {item}")

class WebEvolutionAnalytics:
    """Additional analysis tools for web evolution"""
    
    @staticmethod
    def analyze_technology_stack() -> None:
        """Analyze technology stack across generations"""
        print("\n 📊 TECHNOLOGY STACK ANALYSIS")
        print("-" * 40)
        
        stacks = {
            "Layer": ["Frontend", "Backend", "Database", "Storage", "Identity", "Payments"],
            "Web1": ["HTML/CSS", "CGI/PHP", "MySQL", "Web Hosting", "N/A", "Credit Cards"],
            "Web2": ["React/Vue", "Node/Python", "PostgreSQL", "Cloud/S3", "OAuth/Google", "Stripe/PayPal"],
            "Web3": ["React/Vue", "Solidity/Rust", "Ethereum/IPFS", "Decentralized", "Wallet Connect", "Crypto/DeFi"]
        }
        
        print("\n📋 Technology Stack:")
        print(f" {'Layer':>20} | {'Web1':>25} | {'Web2':>25} | {'Web3':>25}")
        print("-" * 100)
        
        for i in range(len(stacks["Layer"])):
            layer = stacks["Layer"][i]
            web1 = stacks["Web1"][i]
            web2 = stacks["Web2"][i]
            web3 = stacks["Web3"][i]
            
            print(f" {layer[:20]:>20} | {web1[:25]:>25} | {web2[:25]:>25} | {web3[:25]:>25}")
    
    @staticmethod
    def analyze_adoption_metrics() -> None:
        """Analyze adoption metrics"""
        print("\n 📈 ADOPTION METRICS")
        print("-" * 40)
        
        metrics = {
            "Metric": ["Users", "Websites", "Transactions", "Devices", "Data Generated"],
            "Web1": ["~100M", "~10M", "N/A", "Desktops", "N/A"],
            "Web2": ["~5B", "~1.5B", "~500M/day", "Multiple", ">100GB/day/user"],
            "Web3": ["~100M", "~10k dApps", "~1M/day", "Mobile/Wallets", "N/A"]
        }
        
        print("\n📋 Adoption Metrics:")
        print(f" {'Metric':>25} | {'Web1':>25} | {'Web2':>25} | {'Web3':>25}")
        print("-" * 105)
        
        for i in range(len(metrics["Metric"])):
            metric = metrics["Metric"][i]
            web1 = metrics["Web1"][i]
            web2 = metrics["Web2"][i]
            web3 = metrics["Web3"][i]
            
            print(f" {metric[:25]:>25} | {web1[:25]:>25} | {web2[:25]:>25} | {web3[:25]:>25}")

def demonstrate_web_evolution():
    """Execute comprehensive web evolution comparison"""
    print("=" * 60)
    print(" WEB EVOLUTION COMPARISON DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = WebEvolutionEngine()
    
    # Run demonstrations
    engine.display_generations()
    engine.compare_features()
    engine.explain_evolution()
    engine.explain_key_concepts()
    
    # Additional analytics
    WebEvolutionAnalytics.analyze_technology_stack()
    WebEvolutionAnalytics.analyze_adoption_metrics()
    
    print("\n" + "=" * 60)
    print(" WEB EVOLUTION SUMMARY:")
    print("   ✓ Web1: Read-only, publishers control")
    print("   ✓ Web2: Read-write, platforms control")
    print("   ✓ Web3: Read-write-own, users control")
    print("   ✓ Key Difference: Ownership and control")
    print("   ✓ Web1: Information access")
    print("   ✓ Web2: Interaction and community")
    print("   ✓ Web3: Trustless and decentralized")
    print("   ✓ Future: Web3 is the next evolution")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_web_evolution()

1.2 Decentralization

What is Decentralization? Decentralization is the distribution of power, control, and decision-making away from a central authority to a distributed network of participants. In blockchain, this means no single entity controls the network, and decisions are made through consensus.

Three Types of Decentralization:

1. Architectural Decentralization:
How many physical computers make up the system? A fully decentralized system has thousands of independent nodes worldwide.

Example: Bitcoin has over 15,000 nodes in 100+ countries. No single government or company controls the network.

2. Political Decentralization:
Who controls the system? A decentralized system has no central authority. Decisions are made by the community through governance mechanisms.

Example: Ethereum’s governance involves EIPs (Ethereum Improvement Proposals), community discussions, and validator voting.

3. Logical Decentralization:
Does the system present as a single monolithic service or as an amorphous swarm? A logically decentralized system has no single point of failure.

Example: The Bitcoin network continues to operate even if entire countries try to block it.

Benefits of Decentralization:

BenefitDescriptionExample
Censorship ResistanceNo central authority can shut it downBitcoin cannot be blocked by any government
No Single Point of FailureSystem continues even if nodes failEthereum runs on thousands of nodes
User ControlUsers own their data and assetsSelf-custody of crypto assets
TransparencyAll actions are public and verifiableAnyone can audit the code
PermissionlessAnyone can participateNo approval needed to use DeFi

Example: Uniswap is a decentralized exchange that allows anyone to trade tokens without needing to create an account or get approval from a central authority.

Code Example – Decentralization Demonstration:

"""
DECENTRALIZATION DEMONSTRATION FRAMEWORK
=========================================
Understanding how decentralization works through practical comparison
"""

import hashlib
import json
import time
from typing import List, Dict, Any, Optional
from dataclasses import dataclass, field
from enum import Enum

@dataclass
class TransactionRecord:
    """Represents a transaction in the decentralized system"""
    proposal_id: str
    key: str
    old_value: Any
    new_value: Any
    proposer: str
    votes: int
    total_voters: int
    timestamp: float
    status: str

@dataclass
class NodeState:
    """Represents a node in the decentralized system"""
    node_id: str
    public_key: str
    data: Dict[str, Any]
    is_active: bool
    reputation: float

class CentralizedController:
    """Simulate a centralized system with single point of control"""
    
    def __init__(self):
        self.data_store: Dict[str, Any] = {}
        self.authority = "Central Administrator"
        self.activity_log: List[Dict] = []
        self.operation_count = 0
        print(f" 🏢 Centralized Controller created. Authority: {self.authority}")
    
    def insert_record(self, key: str, value: Any, requester: str) -> bool:
        """Add data to the centralized system"""
        if requester != self.authority:
            print(f" ⛔ User {requester} not authorized!")
            return False
        
        self.data_store[key] = value
        self.activity_log.append({
            "action": "INSERT",
            "key": key,
            "value": value,
            "requester": requester,
            "timestamp": time.time()
        })
        self.operation_count += 1
        print(f" ✅ Record inserted: {key} = {value}")
        return True
    
    def update_record(self, key: str, value: Any, requester: str) -> bool:
        """Modify data in the centralized system"""
        if requester != self.authority:
            print(f" ⛔ User {requester} not authorized!")
            return False
        
        old_value = self.data_store.get(key, None)
        self.data_store[key] = value
        self.activity_log.append({
            "action": "UPDATE",
            "key": key,
            "old_value": old_value,
            "new_value": value,
            "requester": requester,
            "timestamp": time.time()
        })
        self.operation_count += 1
        print(f" ✅ Record updated: {key} = {value} (was {old_value})")
        return True
    
    def remove_record(self, key: str, requester: str) -> bool:
        """Delete data from the centralized system"""
        if requester != self.authority:
            print(f" ⛔ User {requester} not authorized!")
            return False
        
        if key in self.data_store:
            del self.data_store[key]
            self.activity_log.append({
                "action": "REMOVE",
                "key": key,
                "requester": requester,
                "timestamp": time.time()
            })
            self.operation_count += 1
            print(f" ✅ Record removed: {key}")
            return True
        return False
    
    def fetch_record(self, key: str) -> Optional[Any]:
        """Retrieve data from the centralized system"""
        return self.data_store.get(key, None)
    
    def display_status(self):
        """Show the current state"""
        print("\n" + "=" * 60)
        print(" 📊 CENTRALIZED SYSTEM STATUS")
        print("=" * 60)
        print(f"\nAuthority: {self.authority}")
        print(f"Data: {json.dumps(self.data_store, indent=2) if self.data_store else 'Empty'}")
        print(f"Total Operations: {self.operation_count}")
        print(f"Log Entries: {len(self.activity_log)}")

class DecentralizedNetwork:
    """Simulate a decentralized system with distributed control"""
    
    def __init__(self, node_count: int = 5):
        self.nodes: List[NodeState] = []
        self.consensus_required = node_count // 2 + 1
        self.ledger: Dict[str, Any] = {}
        self.proposal_history: List[TransactionRecord] = []
        self.operation_count = 0
        
        # Initialize nodes
        for i in range(node_count):
            node_key = hashlib.sha256(f"node_key_{i}".encode()).hexdigest()
            self.nodes.append(NodeState(
                node_id=f"Validator_{i+1}",
                public_key=node_key,
                data={},
                is_active=True,
                reputation=1.0
            ))
        
        print(f" 🌐 Decentralized Network created with {node_count} validators")
        print(f"   Consensus threshold: {self.consensus_required} validators")
    
    def propose_change(self, key: str, value: Any, proposer_id: str) -> bool:
        """Propose a change to the system (requires consensus)"""
        print(f"\n 📝 Proposal: {key} = {value} by {proposer_id}")
        
        # Find proposer node
        proposer = self._find_node(proposer_id)
        if not proposer:
            print(f" ❌ Validator {proposer_id} not found!")
            return False
        
        # Gather consensus from other nodes
        approval_votes = 0
        rejection_votes = 0
        responses = []
        
        for node in self.nodes:
            if node.node_id != proposer_id and node.is_active:
                if self._simulate_consensus(node, key, value):
                    approval_votes += 1
                    responses.append(f"{node.node_id}: ✅ APPROVED")
                else:
                    rejection_votes += 1
                    responses.append(f"{node.node_id}: ❌ REJECTED")
        
        total_votes = approval_votes + rejection_votes
        
        # Check if consensus reached
        if approval_votes >= self.consensus_required:
            # Apply the change
            old_value = self.ledger.get(key, None)
            self.ledger[key] = value
            
            # Update all nodes
            for node in self.nodes:
                node.data[key] = value
            
            # Record proposal
            self.proposal_history.append(TransactionRecord(
                proposal_id=hashlib.sha256(f"{key}{value}{time.time()}".encode()).hexdigest()[:16],
                key=key,
                old_value=old_value,
                new_value=value,
                proposer=proposer_id,
                votes=approval_votes,
                total_voters=total_votes,
                timestamp=time.time(),
                status="Accepted"
            ))
            
            self.operation_count += 1
            print(f" ✅ Consensus reached! Change accepted.")
            print(f"   Votes: {approval_votes}/{total_votes} approved")
            print(f"   Responses: {', '.join(responses[:3])}...")
            return True
        else:
            self.proposal_history.append(TransactionRecord(
                proposal_id=hashlib.sha256(f"{key}{value}{time.time()}".encode()).hexdigest()[:16],
                key=key,
                old_value=self.ledger.get(key, None),
                new_value=value,
                proposer=proposer_id,
                votes=approval_votes,
                total_voters=total_votes,
                timestamp=time.time(),
                status="Rejected"
            ))
            print(f" ❌ Consensus failed. Votes: {approval_votes}/{total_votes}")
            print(f"   Responses: {', '.join(responses[:3])}...")
            return False
    
    def _find_node(self, node_id: str) -> Optional[NodeState]:
        """Find a node by ID"""
        for node in self.nodes:
            if node.node_id == node_id:
                return node
        return None
    
    def _simulate_consensus(self, node: NodeState, key: str, value: Any) -> bool:
        """Simulate a node voting on a proposal"""
        # In reality, this involves cryptographic verification
        # For simulation, we use reputation-based rules
        
        # Low reputation nodes sometimes reject
        if node.reputation < 0.5:
            return False
        
        # Some nodes might be Byzantine (malicious)
        if node.node_id in ["Validator_3"] and time.time() % 3 < 1:
            return False
        
        # Invalid proposals always rejected
        if key == "invalid" or value is None:
            return False
        
        return True
    
    def fetch_record(self, key: str) -> Optional[Any]:
        """Retrieve data from the decentralized system"""
        return self.ledger.get(key, None)
    
    def display_status(self):
        """Show the current state"""
        print("\n" + "=" * 60)
        print(" 📊 DECENTRALIZED NETWORK STATUS")
        print("=" * 60)
        
        print(f"\nValidators: {len(self.nodes)}")
        for node in self.nodes:
            status_symbol = "🟢" if node.is_active else "🔴"
            print(f"   {status_symbol} {node.node_id} (Reputation: {node.reputation:.2f})")
        
        print(f"\nLedger: {json.dumps(self.ledger, indent=2) if self.ledger else 'Empty'}")
        
        print(f"\nRecent Proposals:")
        for proposal in self.proposal_history[-5:]:
            status = "✅" if proposal.status == "Accepted" else "❌"
            print(f"   {status} {proposal.proposer} → {proposal.key} = {proposal.new_value} ({proposal.votes}/{proposal.total_voters} votes)")
        
        print(f"\nTotal Proposals: {len(self.proposal_history)}")
        print(f"Total Operations: {self.operation_count}")

def compare_governance_systems():
    """Compare centralized vs decentralized governance"""
    
    print("=" * 60)
    print(" 🏛️  CENTRALIZED vs DECENTRALIZED GOVERNANCE")
    print("=" * 60)
    
    # ===== CENTRALIZED DEMONSTRATION =====
    print("\n 🏢 CENTRALIZED SYSTEM DEMONSTRATION")
    print("-" * 40)
    
    central = CentralizedController()
    central.insert_record("user_count", 1000, "Central Administrator")
    central.insert_record("revenue", 50000, "Central Administrator")
    central.update_record("revenue", 75000, "Central Administrator")
    
    # Alice tries to modify (should fail)
    print("\n 👤 Alice attempts to modify data...")
    central.update_record("revenue", 100000, "Alice")
    
    central.display_status()
    
    # ===== DECENTRALIZED DEMONSTRATION =====
    print("\n\n 🌐 DECENTRALIZED SYSTEM DEMONSTRATION")
    print("-" * 40)
    
    decentralized = DecentralizedNetwork(node_count=5)
    
    # Alice proposes a change
    print("\n 👤 Alice proposes change...")
    decentralized.propose_change("user_count", 1000, "Validator_1")
    
    # Bob proposes a change
    print("\n 👤 Bob proposes change...")
    decentralized.propose_change("user_count", 2000, "Validator_2")
    
    # Charlie proposes invalid change
    print("\n 👤 Charlie proposes invalid change...")
    decentralized.propose_change("invalid", None, "Validator_3")
    
    decentralized.display_status()
    
    # ===== COMPARISON SUMMARY =====
    print("\n" + "=" * 60)
    print(" 📋 GOVERNANCE COMPARISON SUMMARY")
    print("=" * 60)
    
    print("""
┌─────────────────────────────────────────────────────────────┐
│  CENTRALIZED VS DECENTRALIZED COMPARISON                  │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│  CENTRALIZED GOVERNANCE:                                 │
│  ✓ Fast decisions                                         │
│  ✓ Efficient execution                                    │
│  ✓ Clear accountability                                   │
│  ✗ Single point of failure                                │
│  ✗ Users have no control                                  │
│  ✗ Censorship possible                                    │
│  ✗ Trust in central authority                             │
│                                                           │
│  DECENTRALIZED GOVERNANCE:                               │
│  ✓ No single point of failure                             │
│  ✓ User participation                                     │
│  ✓ Censorship-resistant                                   │
│  ✓ Distributed trust                                      │
│  ✗ Slower decisions                                       │
│  ✗ Requires consensus                                     │
│  ✗ Less efficient                                         │
│  ✗ More complex                                           │
└─────────────────────────────────────────────────────────────┘
        """)
    
    print("\n💡 Key Insight:")
    print("  Decentralization provides resilience and user empowerment")
    print("  but sacrifices speed and efficiency.")
    print("  The choice depends on the use case and trust assumptions.")

if __name__ == "__main__":
    compare_governance_systems()

1.3 Ethereum Ecosystem

What is Ethereum? Ethereum is a decentralized, open-source blockchain with smart contract functionality. It was proposed by Vitalik Buterin in 2013 and launched in 2015. Unlike Bitcoin, which was designed as a digital currency, Ethereum is designed as a platform for building decentralized applications (dApps).

The Ethereum Ecosystem Components:

ComponentDescriptionPurpose
Ethereum BlockchainThe underlying ledgerStore transactions and state
ETH (Ether)Native cryptocurrencyPay for transactions (gas)
EVMEthereum Virtual MachineExecute smart contracts
Smart ContractsProgrammable codeBuild dApps and tokens
dAppsDecentralized applicationsUser-facing applications
WalletsKey managementStore and send ETH
NodesNetwork participantsValidate and secure the network

Ethereum’s Evolution:

PhaseYearDescription
Frontier2015Initial launch, basic functionality
Homestead2016First production release
Metropolis2017-2018Improved security and scalability
Serenity (ETH 2.0)2020-2023Proof of Stake, sharding
The Merge2022Transition to Proof of Stake

Example: Uniswap is a popular dApp built on Ethereum that allows users to swap tokens without a centralized exchange. It uses smart contracts to create automated market makers.

Code Example – Ethereum Ecosystem Overview:

"""
ETHEREUM ECOSYSTEM FRAMEWORK
=============================
Comprehensive overview of the Ethereum ecosystem components and interactions
"""

from typing import Dict, List, Optional
from dataclasses import dataclass
from enum import Enum

@dataclass
class EcosystemComponent:
    """Represents a component in the Ethereum ecosystem"""
    name: str
    description: str
    features: List[str]
    example: str
    dependencies: List[str]

@dataclass
class EcosystemInteraction:
    """Represents an interaction between components"""
    from_component: str
    to_component: str
    description: str
    transaction_flow: str

class EthereumEcosystemEngine:
    """Complete Ethereum ecosystem overview suite"""
    
    def __init__(self):
        print("=" * 60)
        print(" ETHEREUM ECOSYSTEM ENGINE")
        print("=" * 60)
    
    def display_components(self) -> None:
        """Display all ecosystem components"""
        print("\n 🏗️  ETHEREUM ECOSYSTEM COMPONENTS")
        print("-" * 40)
        
        components = [
            EcosystemComponent(
                name="Ethereum Blockchain",
                description="The underlying distributed ledger",
                features=[
                    "Stores all transactions",
                    "Maintains account balances",
                    "Stores smart contract code",
                    "Immutable and transparent"
                ],
                example="Ethereum mainnet with over 18M blocks",
                dependencies=["Consensus mechanism", "Nodes"]
            ),
            EcosystemComponent(
                name="ETH (Ether)",
                description="Native cryptocurrency of Ethereum",
                features=[
                    "Used to pay transaction fees (gas)",
                    "Store of value",
                    "Collateral in DeFi",
                    "Rewards for validators"
                ],
                example="1 ETH can pay gas fees for complex transactions",
                dependencies=["Blockchain", "Wallets"]
            ),
            EcosystemComponent(
                name="EVM (Ethereum Virtual Machine)",
                description="Runtime environment for smart contracts",
                features=[
                    "Executes smart contract code",
                    "Isolated execution environment",
                    "Deterministic execution",
                    "Gas metering"
                ],
                example="EVM executes Solidity code on the blockchain",
                dependencies=["Blockchain", "Smart Contracts"]
            ),
            EcosystemComponent(
                name="Smart Contracts",
                description="Self-executing code on the blockchain",
                features=[
                    "Programmable logic",
                    "Immutable once deployed",
                    "Can hold and transfer assets",
                    "Permanent and deterministic"
                ],
                example="ERC-20 tokens, Uniswap, Aave",
                dependencies=["EVM", "Blockchain"]
            ),
            EcosystemComponent(
                name="dApps",
                description="Decentralized applications",
                features=[
                    "User-facing interfaces",
                    "Backend on blockchain",
                    "Open source",
                    "Transparent and trustless"
                ],
                example="Uniswap (trading), OpenSea (NFTs), Compound (lending)",
                dependencies=["Smart Contracts", "Wallets"]
            ),
            EcosystemComponent(
                name="Wallets",
                description="Key management interfaces",
                features=[
                    "Store private keys",
                    "Manage ETH and tokens",
                    "Sign transactions",
                    "Connect to dApps"
                ],
                example="MetaMask, Ledger, Trust Wallet",
                dependencies=["Private keys", "Blockchain"]
            ),
            EcosystemComponent(
                name="Nodes",
                description="Network participants",
                features=[
                    "Validate transactions",
                    "Store blockchain data",
                    "Execute code",
                    "Maintain network security"
                ],
                example="Full nodes, validator nodes, light nodes",
                dependencies=["Blockchain", "Consensus"]
            )
        ]
        
        print("\n📋 Ecosystem Components:")
        for comp in components:
            print(f"\n  🟣 {comp.name}:")
            print(f"    Description: {comp.description}")
            print(f"    Features:")
            for feature in comp.features:
                print(f"      • {feature}")
            print(f"    Example: {comp.example}")
            print(f"    Dependencies: {', '.join(comp.dependencies)}")
    
    def display_interactions(self) -> None:
        """Show how components interact"""
        print("\n 🔄 COMPONENT INTERACTIONS")
        print("-" * 40)
        
        interactions = [
            EcosystemInteraction(
                from_component="User",
                to_component="Wallet",
                description="User opens wallet (MetaMask)",
                transaction_flow="1. User initiates interaction"
            ),
            EcosystemInteraction(
                from_component="Wallet",
                to_component="Blockchain",
                description="User creates and signs transaction",
                transaction_flow="2. Transaction is broadcast"
            ),
            EcosystemInteraction(
                from_component="Blockchain",
                to_component="Nodes",
                description="Transaction is propagated to nodes",
                transaction_flow="3. Nodes validate transaction"
            ),
            EcosystemInteraction(
                from_component="Nodes",
                to_component="Validators",
                description="Validators propose block",
                transaction_flow="4. Block is proposed"
            ),
            EcosystemInteraction(
                from_component="Validators",
                to_component="EVM",
                description="EVM executes smart contract code",
                transaction_flow="5. Code execution"
            ),
            EcosystemInteraction(
                from_component="EVM",
                to_component="Blockchain",
                description="Block is added to chain",
                transaction_flow="6. Block finalization"
            ),
            EcosystemInteraction(
                from_component="Blockchain",
                to_component="dApps",
                description="dApp updates UI",
                transaction_flow="7. Results displayed"
            )
        ]
        
        print("\n📋 Interaction Flow:")
        print(f" {'Step':>6} | {'From':>15} | {'To':>15} | {'Description':>35}")
        print("-" * 80)
        
        for i, interaction in enumerate(interactions, 1):
            print(f" {i:>6} | {interaction.from_component[:15]:>15} | "
                  f"{interaction.to_component[:15]:>15} | {interaction.description[:35]:>35}")
    
    def display_ecosystem_diagram(self) -> None:
        """Display ecosystem diagram"""
        print("\n 📊 ECOSYSTEM DIAGRAM")
        print("-" * 40)
        
        print("""
┌─────────────────────────────────────────────────────────────┐
│  ETHEREUM ECOSYSTEM                                        │
├─────────────────────────────────────────────────────────────┤
│                                                           │
│                 ┌─────────────┐                           │
│                 │   USERS     │                           │
│                 └──────┬──────┘                           │
│                        │                                   │
│                 ┌──────▼──────┐                           │
│                 │  WALLETS    │                           │
│                 └──────┬──────┘                           │
│                        │                                   │
│                 ┌──────▼──────┐                           │
│                 │    dApps    │                           │
│                 └──────┬──────┘                           │
│                        │                                   │
│           ┌────────────┼────────────┐                     │
│           │            │            │                     │
│    ┌──────▼─────┐ ┌────▼────┐ ┌───▼──────┐              │
│    │ SMART      │ │   ETH   │ │   EVM    │              │
│    │ CONTRACTS  │ │   TOKEN │ │          │              │
│    └──────┬─────┘ └────┬────┘ └───┬──────┘              │
│           │            │            │                     │
│           └────────────┼────────────┘                     │
│                        │                                   │
│                 ┌──────▼──────┐                           │
│                 │ BLOCKCHAIN  │                           │
│                 │  (LEDGER)   │                           │
│                 └──────┬──────┘                           │
│                        │                                   │
│                 ┌──────▼──────┐                           │
│                 │   NODES     │                           │
│                 └─────────────┘                           │
│                                                           │
└─────────────────────────────────────────────────────────────┘
        """)
    
    def display_use_cases(self) -> None:
        """Display ecosystem use cases"""
        print("\n 🎯 ECOSYSTEM USE CASES")
        print("-" * 40)
        
        use_cases = {
            "Decentralized Finance (DeFi)": {
                "description": "Financial services without intermediaries",
                "examples": ["Uniswap (DEX)", "Aave (Lending)", "Compound (Interest)"],
                "components_used": ["Smart Contracts", "ETH", "dApps", "Wallets"]
            },
            "NFTs": {
                "description": "Digital ownership and provenance",
                "examples": ["OpenSea (Marketplace)", "CryptoPunks", "Bored Ape Yacht Club"],
                "components_used": ["Smart Contracts", "dApps", "Wallets"]
            },
            "DAOs": {
                "description": "Decentralized organizations",
                "examples": ["ENS", "Uniswap DAO", "Gitcoin"],
                "components_used": ["Smart Contracts", "dApps", "ETH"]
            },
            "Gaming": {
                "description": "Blockchain-based games",
                "examples": ["Axie Infinity", "Decentraland", "Sandbox"],
                "components_used": ["Smart Contracts", "dApps", "Wallets"]
            }
        }
        
        print("\n📋 Use Cases:")
        for use_case, details in use_cases.items():
            print(f"\n  {use_case}:")
            print(f"    Description: {details['description']}")
            print(f"    Examples: {', '.join(details['examples'])}")
            print(f"    Components Used: {', '.join(details['components_used'])}")

class EcosystemAnalytics:
    """Additional analysis tools for Ethereum ecosystem"""
    
    @staticmethod
    def analyze_adoption_metrics() -> None:
        """Analyze ecosystem adoption metrics"""
        print("\n 📊 ECOSYSTEM ADOPTION METRICS")
        print("-" * 40)
        
        metrics = {
            "Metric": [
                "Total ETH Supply",
                "Daily Transactions",
                "Active Addresses",
                "DeFi TVL",
                "NFT Volume",
                "dApps"
            ],
            "Value": [
                "~120M ETH",
                "~1.2M/day",
                "~500K/day",
                "~$50B",
                "~$1B/month",
                "~3,000+"
            ],
            "Growth": [
                "Steady",
                "Up",
                "Up",
                "Recovering",
                "Growing",
                "Expanding"
            ]
        }
        
        print("\n📋 Ecosystem Metrics:")
        print(f" {'Metric':>25} | {'Value':>25} | {'Growth':>15}")
        print("-" * 70)
        
        for i in range(len(metrics["Metric"])):
            metric = metrics["Metric"][i]
            value = metrics["Value"][i]
            growth = metrics["Growth"][i]
            
            print(f" {metric[:25]:>25} | {value[:25]:>25} | {growth[:15]:>15}")

def demonstrate_ethereum_ecosystem():
    """Execute comprehensive Ethereum ecosystem demonstration"""
    print("=" * 60)
    print(" ETHEREUM ECOSYSTEM OVERVIEW DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = EthereumEcosystemEngine()
    
    # Run demonstrations
    engine.display_components()
    engine.display_interactions()
    engine.display_ecosystem_diagram()
    engine.display_use_cases()
    
    # Additional analytics
    EcosystemAnalytics.analyze_adoption_metrics()
    
    print("\n" + "=" * 60)
    print(" ECOSYSTEM SUMMARY:")
    print("   ✓ Ethereum = Platform for decentralized applications")
    print("   ✓ Components: Blockchain, ETH, EVM, Smart Contracts")
    print("   ✓ Supports: DeFi, NFTs, DAOs, Gaming")
    print("   ✓ Key Feature: Smart contracts (programmable)")
    print("   ✓ Native Token: ETH (gas fees, staking)")
    print("   ✓ Ecosystem: Growing, vibrant, innovative")
    print("   ✓ Future: ETH 2.0, L2 scaling, mass adoption")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    demonstrate_ethereum_ecosystem()

1.4 Ethereum Virtual Machine (EVM)

What is the EVM? The Ethereum Virtual Machine (EVM) is the runtime environment for smart contracts on Ethereum. It is a Turing-complete virtual machine that executes smart contract bytecode. Every node in the Ethereum network runs the EVM.

How the EVM Works:

  1. Compilation: Smart contract code (Solidity) is compiled to EVM bytecode
  2. Deployment: Bytecode is deployed to the blockchain
  3. Execution: When called, the EVM executes the bytecode
  4. State Changes: The EVM updates the blockchain state

EVM Characteristics:

CharacteristicDescription
Turing-CompleteCan execute any program (given enough resources)
DeterministicSame input always produces same output
IsolatedEach contract runs in its own environment
Gas MeteredEach operation costs gas to prevent infinite loops
Stack-BasedUses a stack architecture

Example: When you call a function on a smart contract, the EVM executes the bytecode, calculates the gas cost, and updates the state if the transaction is valid.

Code Example – EVM Simulation:

"""
ETHEREUM VIRTUAL MACHINE SIMULATION FRAMEWORK
==============================================
Comprehensive EVM execution simulation with gas metering and state management
"""

import hashlib
import json
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class OpCode(Enum):
    """EVM OpCodes"""
    PUSH = "PUSH"
    ADD = "ADD"
    SUB = "SUB"
    MUL = "MUL"
    DIV = "DIV"
    SSTORE = "SSTORE"
    SLOAD = "SLOAD"
    MSTORE = "MSTORE"
    MLOAD = "MLOAD"
    STOP = "STOP"
    REVERT = "REVERT"
    JUMP = "JUMP"
    JUMPI = "JUMPI"
    EQ = "EQ"
    LT = "LT"
    GT = "GT"

@dataclass
class EVMState:
    """Represents the EVM execution state"""
    stack: List[int] = field(default_factory=list)
    memory: Dict[int, int] = field(default_factory=dict)
    storage: Dict[int, int] = field(default_factory=dict)
    program_counter: int = 0
    gas_used: int = 0
    running: bool = True
    last_error: Optional[str] = None

@dataclass
class ExecutionResult:
    """Represents the result of EVM execution"""
    final_stack: List[int]
    final_memory: Dict[int, int]
    final_storage: Dict[int, int]
    gas_consumed: int
    gas_remaining: int
    success: bool
    error: Optional[str]

class EVMExecutionEngine:
    """Complete EVM simulation with gas metering"""
    
    def __init__(self, gas_limit: int = 1000000):
        self.state = EVMState()
        self.gas_limit = gas_limit
        self.gas_costs = {
            OpCode.PUSH: 3,
            OpCode.ADD: 3,
            OpCode.SUB: 3,
            OpCode.MUL: 5,
            OpCode.DIV: 5,
            OpCode.SSTORE: 20000,
            OpCode.SLOAD: 200,
            OpCode.MSTORE: 3,
            OpCode.MLOAD: 3,
            OpCode.STOP: 0,
            OpCode.REVERT: 0,
            OpCode.JUMP: 8,
            OpCode.JUMPI: 10,
            OpCode.EQ: 3,
            OpCode.LT: 3,
            OpCode.GT: 3
        }
        self.operation_count = 0
        print(f" 🔧 EVM Engine initialized (Gas Limit: {gas_limit})")
    
    def execute_bytecode(self, bytecode: List[Any]) -> ExecutionResult:
        """Execute EVM bytecode"""
        print("\n" + "=" * 60)
        print(" ⚡ EVM EXECUTION STARTED")
        print("=" * 60)
        print(f"\nBytecode: {bytecode}")
        print(f"Gas Limit: {self.gas_limit}")
        print("\n🔍 Executing...")
        
        # Reset state
        self.state = EVMState()
        self.operation_count = 0
        program_length = len(bytecode)
        
        while self.state.running and self.state.program_counter < program_length:
            op = bytecode[self.state.program_counter]
            self.state.program_counter += 1
            self.operation_count += 1
            
            print(f"\n  PC: {self.state.program_counter-1} | Op: {op} | Stack: {self.state.stack}")
            
            try:
                self._execute_operation(op, bytecode)
            except Exception as e:
                self.state.running = False
                self.state.last_error = str(e)
                print(f"  ❌ Error: {e}")
                break
            
            # Check gas
            if self.state.gas_used > self.gas_limit:
                self.state.running = False
                self.state.last_error = "Out of gas"
                print("  ❌ Out of gas!")
                break
        
        # Determine success
        success = self.state.running and not self.state.last_error
        
        print("\n" + "=" * 60)
        print(" ✅ EXECUTION COMPLETE")
        print("=" * 60)
        print(f"  Success: {success}")
        print(f"  Operations Executed: {self.operation_count}")
        print(f"  Final Stack: {self.state.stack}")
        print(f"  Final Memory: {self.state.memory}")
        print(f"  Final Storage: {self.state.storage}")
        print(f"  Gas Used: {self.state.gas_used}")
        print(f"  Gas Remaining: {self.gas_limit - self.state.gas_used}")
        
        return ExecutionResult(
            final_stack=self.state.stack,
            final_memory=self.state.memory,
            final_storage=self.state.storage,
            gas_consumed=self.state.gas_used,
            gas_remaining=self.gas_limit - self.state.gas_used,
            success=success,
            error=self.state.last_error
        )
    
    def _execute_operation(self, op: Any, bytecode: List[Any]) -> None:
        """Execute a single operation"""
        if op == OpCode.PUSH.value or op == "PUSH":
            if self.state.program_counter < len(bytecode):
                value = bytecode[self.state.program_counter]
                self.state.program_counter += 1
                self._push(value)
                self._consume_gas(OpCode.PUSH)
            else:
                raise ValueError("PUSH requires a value")
        
        elif op == OpCode.ADD.value or op == "ADD":
            self._add()
            self._consume_gas(OpCode.ADD)
        
        elif op == OpCode.SUB.value or op == "SUB":
            self._sub()
            self._consume_gas(OpCode.SUB)
        
        elif op == OpCode.MUL.value or op == "MUL":
            self._mul()
            self._consume_gas(OpCode.MUL)
        
        elif op == OpCode.DIV.value or op == "DIV":
            self._div()
            self._consume_gas(OpCode.DIV)
        
        elif op == OpCode.SSTORE.value or op == "SSTORE":
            self._sstore()
            self._consume_gas(OpCode.SSTORE)
        
        elif op == OpCode.SLOAD.value or op == "SLOAD":
            self._sload()
            self._consume_gas(OpCode.SLOAD)
        
        elif op == OpCode.MSTORE.value or op == "MSTORE":
            self._mstore()
            self._consume_gas(OpCode.MSTORE)
        
        elif op == OpCode.MLOAD.value or op == "MLOAD":
            self._mload()
            self._consume_gas(OpCode.MLOAD)
        
        elif op == OpCode.STOP.value or op == "STOP":
            self._stop()
            self._consume_gas(OpCode.STOP)
        
        elif op == OpCode.REVERT.value or op == "REVERT":
            self._revert()
            self._consume_gas(OpCode.REVERT)
        
        elif op == OpCode.EQ.value or op == "EQ":
            self._eq()
            self._consume_gas(OpCode.EQ)
        
        elif op == OpCode.LT.value or op == "LT":
            self._lt()
            self._consume_gas(OpCode.LT)
        
        elif op == OpCode.GT.value or op == "GT":
            self._gt()
            self._consume_gas(OpCode.GT)
        
        elif op == OpCode.JUMP.value or op == "JUMP":
            self._jump()
            self._consume_gas(OpCode.JUMP)
        
        elif op == OpCode.JUMPI.value or op == "JUMPI":
            self._jumpi()
            self._consume_gas(OpCode.JUMPI)
        
        else:
            raise ValueError(f"Unknown opcode: {op}")
    
    def _push(self, value: int) -> None:
        """Push value onto stack"""
        self.state.stack.append(value)
        print(f"    PUSH: {value}")
    
    def _add(self) -> None:
        """Add top two stack values"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (ADD)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(a + b)
        print(f"    ADD: {a} + {b} = {a+b}")
    
    def _sub(self) -> None:
        """Subtract top two stack values"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (SUB)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(b - a)
        print(f"    SUB: {b} - {a} = {b-a}")
    
    def _mul(self) -> None:
        """Multiply top two stack values"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (MUL)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(a * b)
        print(f"    MUL: {a} * {b} = {a*b}")
    
    def _div(self) -> None:
        """Divide top two stack values"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (DIV)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        if a == 0:
            raise ValueError("Division by zero")
        self.state.stack.append(b // a)
        print(f"    DIV: {b} // {a} = {b//a}")
    
    def _sstore(self) -> None:
        """Store value in storage"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (SSTORE)")
        key = self.state.stack.pop()
        value = self.state.stack.pop()
        self.state.storage[key] = value
        print(f"    SSTORE: storage[{key}] = {value}")
    
    def _sload(self) -> None:
        """Load value from storage"""
        if len(self.state.stack) < 1:
            raise ValueError("Stack underflow (SLOAD)")
        key = self.state.stack.pop()
        value = self.state.storage.get(key, 0)
        self.state.stack.append(value)
        print(f"    SLOAD: storage[{key}] = {value}")
    
    def _mstore(self) -> None:
        """Store value in memory"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (MSTORE)")
        offset = self.state.stack.pop()
        value = self.state.stack.pop()
        self.state.memory[offset] = value
        print(f"    MSTORE: memory[{offset}] = {value}")
    
    def _mload(self) -> None:
        """Load value from memory"""
        if len(self.state.stack) < 1:
            raise ValueError("Stack underflow (MLOAD)")
        offset = self.state.stack.pop()
        value = self.state.memory.get(offset, 0)
        self.state.stack.append(value)
        print(f"    MLOAD: memory[{offset}] = {value}")
    
    def _stop(self) -> None:
        """Stop execution"""
        self.state.running = False
        print("    STOP: Execution halted")
    
    def _revert(self) -> None:
        """Revert changes"""
        self.state.running = False
        self.state.last_error = "Reverted"
        print("    REVERT: State changes reverted")
    
    def _eq(self) -> None:
        """Check equality"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (EQ)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(1 if a == b else 0)
        print(f"    EQ: {a} == {b} = {a == b}")
    
    def _lt(self) -> None:
        """Check less than"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (LT)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(1 if b < a else 0)
        print(f"    LT: {b} < {a} = {b < a}")
    
    def _gt(self) -> None:
        """Check greater than"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (GT)")
        a = self.state.stack.pop()
        b = self.state.stack.pop()
        self.state.stack.append(1 if b > a else 0)
        print(f"    GT: {b} > {a} = {b > a}")
    
    def _jump(self) -> None:
        """Jump to program counter"""
        if len(self.state.stack) < 1:
            raise ValueError("Stack underflow (JUMP)")
        destination = self.state.stack.pop()
        self.state.program_counter = destination
        print(f"    JUMP: PC = {destination}")
    
    def _jumpi(self) -> None:
        """Jump if condition is true"""
        if len(self.state.stack) < 2:
            raise ValueError("Stack underflow (JUMPI)")
        destination = self.state.stack.pop()
        condition = self.state.stack.pop()
        if condition != 0:
            self.state.program_counter = destination
            print(f"    JUMPI: PC = {destination} (condition true)")
        else:
            print(f"    JUMPI: Not jumping (condition false)")
    
    def _consume_gas(self, op: OpCode) -> None:
        """Consume gas for operation"""
        gas_cost = self.gas_costs.get(op, 3)
        self.state.gas_used += gas_cost

def evm_demonstration():
    """Execute comprehensive EVM demonstration"""
    print("=" * 60)
    print(" ETHEREUM VIRTUAL MACHINE DEMONSTRATION")
    print("=" * 60)
    
    # Program 1: Simple Arithmetic
    print("\n 📝 PROGRAM 1: Arithmetic Operations (5 + 3 - 2 = 6)")
    print("-" * 40)
    
    bytecode1 = ["PUSH", 5, "PUSH", 3, "ADD", "PUSH", 2, "SUB", "STOP"]
    evm1 = EVMExecutionEngine(gas_limit=100000)
    result1 = evm1.execute_bytecode(bytecode1)
    
    # Program 2: Storage Operations
    print("\n 📝 PROGRAM 2: Storage Operations")
    print("-" * 40)
    
    bytecode2 = ["PUSH", 100, "PUSH", 0, "SSTORE", "PUSH", 0, "SLOAD", "STOP"]
    evm2 = EVMExecutionEngine(gas_limit=100000)
    result2 = evm2.execute_bytecode(bytecode2)
    
    # Program 3: Memory Operations
    print("\n 📝 PROGRAM 3: Memory Operations")
    print("-" * 40)
    
    bytecode3 = ["PUSH", 42, "PUSH", 0, "MSTORE", "PUSH", 0, "MLOAD", "STOP"]
    evm3 = EVMExecutionEngine(gas_limit=100000)
    result3 = evm3.execute_bytecode(bytecode3)
    
    # Program 4: Conditional Execution
    print("\n 📝 PROGRAM 4: Conditional Execution")
    print("-" * 40)
    
    bytecode4 = ["PUSH", 10, "PUSH", 5, "GT", "PUSH", 8, "PUSH", 2, "MUL", "STOP"]
    evm4 = EVMExecutionEngine(gas_limit=100000)
    result4 = evm4.execute_bytecode(bytecode4)
    
    # Summary
    print("\n" + "=" * 60)
    print(" 📊 EXECUTION SUMMARY")
    print("=" * 60)
    
    results = [result1, result2, result3, result4]
    for i, result in enumerate(results, 1):
        print(f"\nProgram {i}:")
        print(f"  Success: {result.success}")
        print(f"  Gas Used: {result.gas_consumed}")
        print(f"  Gas Remaining: {result.gas_remaining}")
        print(f"  Stack Size: {len(result.final_stack)}")
        if result.error:
            print(f"  Error: {result.error}")

if __name__ == "__main__":
    evm_demonstration()

1.5 Smart Contracts

What is a Smart Contract? A smart contract is a self-executing program stored on the blockchain that automatically executes when predetermined conditions are met. It’s code that runs exactly as programmed without any possibility of downtime, censorship, fraud, or third-party interference.

Key Characteristics:

CharacteristicDescription
Self-ExecutingAutomatically executes when conditions are met
ImmutableOnce deployed, cannot be changed
TransparentCode is visible on the blockchain
TrustlessNo need for third-party trust
AutomatedNo manual intervention needed

Example: A simple escrow smart contract that holds funds until both parties agree, then automatically releases the payment.

Common Use Cases:

Use CaseDescription
Token ContractsCreate and manage tokens (ERC-20, ERC-721)
DeFi ProtocolsLending, borrowing, trading
DAOsDecentralized governance
NFTsDigital ownership and royalties
MarketplacesDecentralized trading platforms

Code Example – Solidity Smart Contract (Python Simulation):

"""
SMART CONTRACT SIMULATION FRAMEWORK
===================================
Comprehensive implementation of smart contract logic with Python
"""

import hashlib
import json
import time
from typing import Dict, List, Any, Optional
from dataclasses import dataclass, field
from enum import Enum

class ContractStatus(Enum):
    """Contract status states"""
    PENDING = "Pending"
    ACTIVE = "Active"
    COMPLETED = "Completed"
    DISPUTED = "Disputed"
    FAILED = "Failed"

@dataclass
class ContractEvent:
    """Represents an event emitted by a contract"""
    event_name: str
    data: Dict[str, Any]
    block_number: int
    timestamp: float
    transaction_hash: str

@dataclass
class ContractState:
    """Represents the state of a contract"""
    contract_name: str
    contract_address: str
    creator: str
    deployed_at: float
    state_data: Dict[str, Any]
    balance: float
    event_count: int

class BaseSmartContract:
    """Base class for all smart contracts"""
    
    def __init__(self, name: str, creator: str):
        self.name = name
        self.creator = creator
        self.address = f"0x{hashlib.md5(name.encode()).hexdigest()[:16]}"
        self.state: Dict[str, Any] = {}
        self.events: List[ContractEvent] = []
        self.deployed_at = time.time()
        self.balance = 0.0
        self.block_number = 0
        self.status = ContractStatus.ACTIVE
        print(f" 📜 Contract '{name}' deployed at {self.address} by {creator}")
    
    def emit_event(self, event_name: str, data: Dict[str, Any]) -> None:
        """Emit an event from the contract"""
        self.block_number += 1
        event = ContractEvent(
            event_name=event_name,
            data=data,
            block_number=self.block_number,
            timestamp=time.time(),
            transaction_hash=hashlib.sha256(
                f"{self.address}{event_name}{time.time()}".encode()
            ).hexdigest()[:16]
        )
        self.events.append(event)
        print(f"  📢 Event: {event_name} → {data}")
    
    def get_contract_state(self) -> ContractState:
        """Get the current state of the contract"""
        return ContractState(
            contract_name=self.name,
            contract_address=self.address,
            creator=self.creator,
            deployed_at=self.deployed_at,
            state_data=self.state,
            balance=self.balance,
            event_count=len(self.events)
        )
    
    def display_summary(self) -> None:
        """Display contract summary"""
        state = self.get_contract_state()
        print(f"\n  Contract: {state.contract_name}")
        print(f"  Address: {state.contract_address}")
        print(f"  Creator: {state.creator}")
        print(f"  Status: {self.status.value}")
        print(f"  Balance: {state.balance}")
        print(f"  Events: {state.event_count}")
        print(f"  State: {json.dumps(state.state_data, indent=2) if state.state_data else 'Empty'}")

class EscrowAgreement(BaseSmartContract):
    """Escrow smart contract implementation"""
    
    def __init__(self, creator: str, buyer: str, seller: str, amount: float):
        super().__init__("EscrowAgreement", creator)
        self.state = {
            "buyer": buyer,
            "seller": seller,
            "amount": amount,
            "status": "PENDING",
            "buyer_confirmed": False,
            "seller_confirmed": False,
            "release_time": None
        }
        self.balance = amount
        print(f" 🔒 Escrow created: {buyer} → {seller} for {amount} units")
        self.emit_event("EscrowCreated", {
            "buyer": buyer, 
            "seller": seller, 
            "amount": amount
        })
    
    def confirm_delivery(self, user: str) -> bool:
        """Confirm delivery by buyer or seller"""
        if self.status != ContractStatus.ACTIVE:
            print(f" ❌ Contract is {self.status.value}")
            return False
        
        if user == self.state["buyer"]:
            self.state["buyer_confirmed"] = True
            print(f"  ✅ Buyer confirmed delivery")
        elif user == self.state["seller"]:
            self.state["seller_confirmed"] = True
            print(f"  ✅ Seller confirmed delivery")
        else:
            print(f"  ❌ User {user} not authorized")
            return False
        
        self.emit_event("DeliveryConfirmed", {"user": user})
        
        # Check if both confirmed
        if self.state["buyer_confirmed"] and self.state["seller_confirmed"]:
            self._release_funds()
        
        return True
    
    def _release_funds(self) -> None:
        """Release funds to seller"""
        if self.state["status"] != "PENDING":
            print(f"  ⚠️  Escrow already {self.state['status']}")
            return
        
        self.state["status"] = "COMPLETED"
        self.state["release_time"] = time.time()
        self.status = ContractStatus.COMPLETED
        
        # Transfer funds (simulated)
        print(f"  💰 Funds released: {self.state['amount']} to {self.state['seller']}")
        self.emit_event("FundsReleased", {
            "to": self.state["seller"],
            "amount": self.state["amount"]
        })
    
    def raise_dispute(self, user: str) -> bool:
        """Raise a dispute on the escrow"""
        if self.status != ContractStatus.ACTIVE:
            print(f" ❌ Contract is {self.status.value}")
            return False
        
        if user not in [self.state["buyer"], self.state["seller"]]:
            print(f" ❌ User {user} not authorized")
            return False
        
        self.state["status"] = "DISPUTED"
        self.status = ContractStatus.DISPUTED
        print(f"  ⚠️  Escrow disputed by {user}")
        self.emit_event("DisputeRaised", {"by": user})
        return True
    
    def resolve_dispute(self, resolution: str) -> bool:
        """Resolve a dispute (admin function)"""
        if self.status != ContractStatus.DISPUTED:
            print(f" ❌ No active dispute")
            return False
        
        self.state["status"] = f"RESOLVED_{resolution}"
        self.status = ContractStatus.COMPLETED
        
        if resolution == "BUYER":
            self.balance = 0  # Return funds to buyer (simulated)
            print(f"  ⚖️  Dispute resolved: Funds returned to buyer")
        elif resolution == "SELLER":
            self._release_funds()
            print(f"  ⚖️  Dispute resolved: Funds released to seller")
        else:
            self.balance = 0
            print(f"  ⚖️  Dispute resolved: Split 50/50")
        
        self.emit_event("DisputeResolved", {"resolution": resolution})
        return True

class TokenContract(BaseSmartContract):
    """ERC-20 style token contract"""
    
    def __init__(self, creator: str, token_name: str, symbol: str, total_supply: int):
        super().__init__(f"Token_{token_name}", creator)
        self.state = {
            "name": token_name,
            "symbol": symbol,
            "total_supply": total_supply,
            "balances": {creator: total_supply},
            "allowances": {},
            "holders": [creator]
        }
        self.balance = 0
        print(f" 🪙 Token '{token_name}' ({symbol}) created with {total_supply} supply")
        self.emit_event("TokenCreated", {
            "name": token_name, 
            "symbol": symbol, 
            "supply": total_supply
        })
    
    def transfer(self, sender: str, recipient: str, amount: int) -> bool:
        """Transfer tokens from sender to recipient"""
        if self.status != ContractStatus.ACTIVE:
            print(f" ❌ Contract is {self.status.value}")
            return False
        
        if self.state["balances"].get(sender, 0) < amount:
            print(f" ❌ Insufficient balance: {sender} has {self.state['balances'].get(sender, 0)}")
            return False
        
        self.state["balances"][sender] -= amount
        self.state["balances"][recipient] = self.state["balances"].get(recipient, 0) + amount
        
        if recipient not in self.state["holders"]:
            self.state["holders"].append(recipient)
        
        print(f"  💸 Transfer: {amount} {self.state['symbol']} from {sender[:8]}... to {recipient[:8]}...")
        self.emit_event("Transfer", {
            "from": sender, 
            "to": recipient, 
            "amount": amount
        })
        return True
    
    def approve(self, owner: str, spender: str, amount: int) -> bool:
        """Approve spending allowance"""
        if self.status != ContractStatus.ACTIVE:
            print(f" ❌ Contract is {self.status.value}")
            return False
        
        if owner not in self.state["balances"]:
            print(f" ❌ Owner not found")
            return False
        
        self.state["allowances"][(owner, spender)] = amount
        print(f"  ✅ Allowance set: {spender[:8]}... can spend {amount} from {owner[:8]}...")
        self.emit_event("Approval", {
            "owner": owner, 
            "spender": spender, 
            "amount": amount
        })
        return True
    
    def transfer_from(self, sender: str, recipient: str, amount: int) -> bool:
        """Transfer using allowance"""
        if self.status != ContractStatus.ACTIVE:
            print(f" ❌ Contract is {self.status.value}")
            return False
        
        allowance = self.state["allowances"].get((sender, recipient), 0)
        if allowance < amount:
            print(f" ❌ Insufficient allowance: {allowance}")
            return False
        
        self.state["allowances"][(sender, recipient)] -= amount
        return self.transfer(sender, recipient, amount)
    
    def get_balance(self, address: str) -> int:
        """Get token balance for an address"""
        return self.state["balances"].get(address, 0)
    
    def get_holders(self) -> List[str]:
        """Get list of token holders"""
        return self.state["holders"]
    
    def total_supply(self) -> int:
        """Get total token supply"""
        return self.state["total_supply"]

def run_smart_contract_demo():
    """Execute comprehensive smart contract demonstration"""
    print("=" * 60)
    print(" SMART CONTRACT SIMULATION DEMONSTRATION")
    print("=" * 60)
    
    # 1. Escrow Contract
    print("\n 🔒 ESCROW CONTRACT DEMONSTRATION")
    print("-" * 40)
    
    escrow = EscrowAgreement(
        creator="Lawyer",
        buyer="Alice",
        seller="Bob",
        amount=100
    )
    escrow.display_summary()
    
    print("\n 📝 Confirming delivery...")
    escrow.confirm_delivery("Alice")
    escrow.confirm_delivery("Bob")
    escrow.display_summary()
    
    # 2. Escrow with Dispute
    print("\n 🔒 ESCROW WITH DISPUTE")
    print("-" * 40)
    
    escrow2 = EscrowAgreement(
        creator="Lawyer",
        buyer="Alice",
        seller="Bob",
        amount=200
    )
    
    print("\n 📝 Disputing escrow...")
    escrow2.raise_dispute("Alice")
    escrow2.display_summary()
    
    print("\n 📝 Resolving dispute...")
    escrow2.resolve_dispute("SELLER")
    escrow2.display_summary()
    
    # 3. Token Contract
    print("\n 🪙 TOKEN CONTRACT DEMONSTRATION")
    print("-" * 40)
    
    token = TokenContract(
        creator="Alice",
        token_name="MyToken",
        symbol="MTK",
        total_supply=1000
    )
    token.display_summary()
    
    print("\n 📝 Token transfers...")
    token.transfer("Alice", "Bob", 100)
    token.transfer("Alice", "Charlie", 50)
    
    print(f"\n  Balances:")
    print(f"    Alice: {token.get_balance('Alice')} MTK")
    print(f"    Bob: {token.get_balance('Bob')} MTK")
    print(f"    Charlie: {token.get_balance('Charlie')} MTK")
    
    print("\n 📝 Allowance and transfer_from...")
    token.approve("Alice", "Bob", 200)
    token.transfer_from("Alice", "Charlie", 30)
    
    print(f"\n  Final Balances:")
    print(f"    Alice: {token.get_balance('Alice')} MTK")
    print(f"    Bob: {token.get_balance('Bob')} MTK")
    print(f"    Charlie: {token.get_balance('Charlie')} MTK")
    
    # Show events
    print("\n 📊 Recent Events:")
    for event in token.events[-3:]:
        print(f"    📢 {event.event_name}: {event.data}")

if __name__ == "__main__":
    run_smart_contract_demo()

1.6 Externally Owned Accounts (EOA)

What is an EOA? An Externally Owned Account (EOA) is a regular Ethereum account controlled by a private key. It’s the most common type of account used by individuals to hold and transfer ETH and interact with smart contracts.

EOA Characteristics:

CharacteristicDescription
Controlled ByPrivate key
Can Send ETHYes, to any address
Can Send TransactionsYes, any transaction originates from an EOA
Can Deploy ContractsYes, by sending a contract creation transaction
Has BalanceYes, holds ETH
Can Hold TokensYes, can hold ERC-20 tokens

Example: Your MetaMask wallet is an EOA. When you send ETH or interact with a dApp, you’re using your EOA.

Code Example – EOA Management:

"""
EXTERNALLY OWNED ACCOUNT SIMULATION FRAMEWORK
==============================================
Complete EOA simulation with key generation, signing, and transactions
"""

import hashlib
import secrets
import json
import time
from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from enum import Enum

@dataclass
class Transaction:
    """Represents a transaction from an EOA"""
    from_address: str
    to_address: str
    amount: float
    nonce: int
    data: str
    signature: str
    timestamp: float
    hash: str
    status: str

@dataclass
class AccountInfo:
    """Represents EOA information"""
    name: str
    address: str
    balance: float
    nonce: int
    transaction_count: int
    public_key: str
    private_key: str

class EOASimulation:
    """
    Externally Owned Account simulation with key management
    """

    def __init__(self, name: str):
        self.name = name
        self.private_key = secrets.token_hex(32)
        self.public_key = self._derive_public_key(self.private_key)
        self.address = self._derive_address(self.public_key)
        self.balance = 0.0
        self.nonce = 0
        self.transactions: List[Transaction] = []
        self.created_at = time.time()
        self.is_active = True

        print(f" 👤 Account created: {self.name}")
        print(f"   📍 Address: {self.address}")
        print(f"   🔑 Private Key: {self.private_key[:16]}... (KEEP SECRET!)")
        print(f"   🔐 Public Key: {self.public_key[:16]}...")
    
    def _derive_public_key(self, private_key: str) -> str:
        """Derive public key from private key (simulated)"""
        return hashlib.sha256(private_key.encode()).hexdigest()
    
    def _derive_address(self, public_key: str) -> str:
        """Derive address from public key (simulated)"""
        hash_value = hashlib.sha256(public_key.encode()).hexdigest()
        return f"0x{hash_value[:16]}"
    
    def _generate_signature(self, to_address: str, amount: float, data: str) -> str:
        """Generate a signature for a transaction (simulated ECDSA)"""
        message = f"{self.address}{to_address}{amount}{self.nonce}{data}"
        return hashlib.sha256((self.private_key + message).encode()).hexdigest()
    
    def _compute_transaction_hash(self, tx_data: Dict) -> str:
        """Compute transaction hash"""
        return hashlib.sha256(
            json.dumps(tx_data, sort_keys=True).encode()
        ).hexdigest()
    
    def sign_transaction(self, to_address: str, amount: float, data: str = "") -> Optional[Transaction]:
        """Sign and broadcast a transaction"""
        if not self.is_active:
            print(f" ❌ Account {self.name} is inactive")
            return None
        
        if self.balance < amount:
            print(f" ❌ Insufficient balance: {self.balance:.2f} < {amount:.2f}")
            return None
        
        # Create transaction
        tx_data = {
            "from": self.address,
            "to": to_address,
            "amount": amount,
            "nonce": self.nonce,
            "data": data,
            "timestamp": time.time()
        }
        
        signature = self._generate_signature(to_address, amount, data)
        tx_hash = self._compute_transaction_hash(tx_data)
        
        transaction = Transaction(
            from_address=self.address,
            to_address=to_address,
            amount=amount,
            nonce=self.nonce,
            data=data,
            signature=signature,
            timestamp=tx_data["timestamp"],
            hash=tx_hash,
            status="Signed"
        )
        
        # Update account state
        self.nonce += 1
        self.balance -= amount
        self.transactions.append(transaction)
        
        print(f"  ✅ Transaction signed: {amount:.2f} ETH to {to_address[:16]}...")
        print(f"    Nonce: {transaction.nonce}")
        print(f"    Hash: {transaction.hash[:16]}...")
        print(f"    Signature: {transaction.signature[:16]}...")
        
        return transaction
    
    def receive_funds(self, amount: float, source: str = "Unknown") -> bool:
        """Receive funds into the account"""
        self.balance += amount
        print(f"  💰 Received {amount:.2f} ETH from {source[:16]}...")
        return True
    
    def get_balance(self) -> float:
        """Get current balance"""
        return self.balance
    
    def get_nonce(self) -> int:
        """Get current nonce"""
        return self.nonce
    
    def get_transaction_history(self, limit: int = 10) -> List[Dict]:
        """Get transaction history"""
        return [
            {
                "hash": tx.hash[:16] + "...",
                "to": tx.to_address[:16] + "...",
                "amount": tx.amount,
                "nonce": tx.nonce,
                "status": tx.status,
                "time": time.ctime(tx.timestamp)
            }
            for tx in self.transactions[-limit:]
        ]
    
    def get_account_info(self) -> AccountInfo:
        """Get account information"""
        return AccountInfo(
            name=self.name,
            address=self.address,
            balance=self.balance,
            nonce=self.nonce,
            transaction_count=len(self.transactions),
            public_key=self.public_key,
            private_key=self.private_key[:16] + "..."
        )
    
    def display_info(self) -> None:
        """Display account information"""
        info = self.get_account_info()
        print(f"\n  👤 {info.name}")
        print(f"    📍 Address: {info.address}")
        print(f"    💰 Balance: {info.balance:.2f} ETH")
        print(f"    🔢 Nonce: {info.nonce}")
        print(f"    📊 Transactions: {info.transaction_count}")
        print(f"    🔐 Public Key: {info.public_key[:16]}...")
    
    def verify_transaction(self, tx: Transaction) -> bool:
        """Verify a transaction signature"""
        expected = self._generate_signature(
            tx.to_address, tx.amount, tx.data
        )
        return tx.signature == expected

class EOAWallet:
    """EOA Wallet managing multiple accounts"""
    
    def __init__(self):
        self.accounts: Dict[str, EOASimulation] = {}
        self.active_account: Optional[str] = None
        print(" 🔐 EOA Wallet initialized")
    
    def create_account(self, name: str) -> EOASimulation:
        """Create a new EOA"""
        if name in self.accounts:
            print(f" ⚠️  Account '{name}' already exists")
            return self.accounts[name]
        
        account = EOASimulation(name)
        self.accounts[name] = account
        if not self.active_account:
            self.active_account = name
        return account
    
    def switch_account(self, name: str) -> bool:
        """Switch active account"""
        if name in self.accounts:
            self.active_account = name
            print(f" 🔄 Switched to account: {name}")
            return True
        print(f" ❌ Account '{name}' not found")
        return False
    
    def get_active_account(self) -> Optional[EOASimulation]:
        """Get the active account"""
        if self.active_account:
            return self.accounts.get(self.active_account)
        return None
    
    def send_transaction(self, to_name: str, amount: float, data: str = "") -> bool:
        """Send transaction from active account"""
        active = self.get_active_account()
        if not active:
            print(" ❌ No active account")
            return False
        
        if to_name not in self.accounts:
            print(f" ⚠️  Recipient '{to_name}' not found in wallet")
            return False
        
        to_account = self.accounts[to_name]
        transaction = active.sign_transaction(to_account.address, amount, data)
        if transaction:
            to_account.receive_funds(amount, active.name)
            return True
        return False
    
    def display_all_accounts(self) -> None:
        """Display all accounts"""
        print("\n" + "=" * 60)
        print(" 📊 EOA WALLET ACCOUNTS")
        print("=" * 60)
        
        for name, account in self.accounts.items():
            marker = "▶ " if name == self.active_account else "   "
            print(f"\n {marker}{name}:")
            print(f"    Address: {account.address}")
            print(f"    Balance: {account.balance:.2f} ETH")
            print(f"    Nonce: {account.nonce}")

def eoa_demonstration():
    """Execute comprehensive EOA demonstration"""
    print("=" * 60)
    print(" EOA SIMULATION DEMONSTRATION")
    print("=" * 60)
    
    # Create wallet
    wallet = EOAWallet()
    
    # Create accounts
    print("\n 🏗️  Creating Accounts")
    print("-" * 40)
    
    alice = wallet.create_account("Alice")
    bob = wallet.create_account("Bob")
    charlie = wallet.create_account("Charlie")
    
    # Fund accounts
    print("\n 💰 Funding Accounts")
    print("-" * 40)
    
    alice.receive_funds(100, "Genesis")
    bob.receive_funds(50, "Genesis")
    
    print(f"\n  Initial Balances:")
    for name in ["Alice", "Bob", "Charlie"]:
        acc = wallet.accounts[name]
        print(f"    {name}: {acc.balance:.2f} ETH")
    
    # Make transactions
    print("\n 📝 Making Transactions")
    print("-" * 40)
    
    wallet.switch_account("Alice")
    wallet.send_transaction("Bob", 30)
    
    wallet.switch_account("Bob")
    wallet.send_transaction("Charlie", 10)
    
    wallet.switch_account("Alice")
    wallet.send_transaction("Charlie", 15)
    
    print(f"\n  Final Balances:")
    for name in ["Alice", "Bob", "Charlie"]:
        acc = wallet.accounts[name]
        print(f"    {name}: {acc.balance:.2f} ETH")
    
    # Display transaction histories
    print("\n 📋 Transaction Histories")
    print("-" * 40)
    
    for name in ["Alice", "Bob", "Charlie"]:
        acc = wallet.accounts[name]
        print(f"\n  {name}'s Transactions:")
        for tx in acc.get_transaction_history(3):
            print(f"    → {tx['to']} : {tx['amount']:.2f} ETH (nonce: {tx['nonce']})")
    
    # Display account info
    wallet.display_all_accounts()
    
    print("\n" + "=" * 60)
    print(" EOA CHARACTERISTICS:")
    print("   ✓ Controlled by private key")
    print("   ✓ Can hold ETH and tokens")
    print("   ✓ Can initiate transactions")
    print("   ✓ Has unique address")
    print("   ✓ Nonce prevents replay attacks")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    eoa_demonstration()

1.7 Smart Contract Accounts

What is a Smart Contract Account? A smart contract account is an account controlled by code rather than a private key. It has no private key and cannot initiate transactions on its own – it can only react to transactions sent to it by EOAs or other contracts.

Smart Contract Account Characteristics:

CharacteristicDescription
Controlled ByCode (smart contract logic)
Can Send ETHYes, when triggered by a transaction
Can Send TransactionsNo, cannot initiate transactions
Can Deploy ContractsYes, can create other contracts
Has BalanceYes, can hold ETH and tokens
Has StorageYes, persistent state

Example: A DeFi protocol like Uniswap is a smart contract account. Users send transactions to it, and it executes the code to swap tokens.

Code Example – Smart Contract Account:

"""
SMART CONTRACT ACCOUNT SIMULATION FRAMEWORK
===========================================
Complete implementation of contract account functionality and interactions
"""

import hashlib
import json
import time
from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass, field
from enum import Enum

class ContractStatus(Enum):
    """Contract status states"""
    DEPLOYED = "Deployed"
    ACTIVE = "Active"
    PAUSED = "Paused"
    DESTROYED = "Destroyed"

@dataclass
class ContractEvent:
    """Represents an event emitted by a contract"""
    event_name: str
    data: Dict[str, Any]
    timestamp: float
    block_height: int

@dataclass
class ContractFunction:
    """Represents a contract function"""
    name: str
    function: Callable
    parameters: List[str]
    visibility: str
    is_view: bool

class ContractAccount:
    """
    Smart contract account simulation with full functionality
    """

    def __init__(self, name: str, creator: str):
        self.name = name
        self.creator = creator
        self.address = f"0x{hashlib.md5(name.encode()).hexdigest()[:16]}"
        self.balance = 0.0
        self.functions: Dict[str, ContractFunction] = {}
        self.storage: Dict[str, Any] = {}
        self.events: List[ContractEvent] = []
        self.nonce = 0
        self.deployed_at = time.time()
        self.status = ContractStatus.DEPLOYED
        self.block_height = 0
        self.owner = creator
        
        print(f" 📜 Contract '{name}' deployed at {self.address} by {creator}")
    
    def define_function(self, name: str, func: Callable, 
                        parameters: List[str] = [], 
                        visibility: str = "public",
                        is_view: bool = False) -> None:
        """Define a function in the contract"""
        self.functions[name] = ContractFunction(
            name=name,
            function=func,
            parameters=parameters,
            visibility=visibility,
            is_view=is_view
        )
        print(f"    ✅ Defined function: {name} ({visibility})")
    
    def call_function(self, function_name: str, caller: str, *args) -> Any:
        """Call a contract function"""
        if self.status == ContractStatus.DESTROYED:
            print(f" ❌ Contract has been destroyed")
            return None
        
        if function_name not in self.functions:
            print(f" ❌ Function '{function_name}' not found")
            return None
        
        function = self.functions[function_name]
        print(f"\n  🔄 Calling {function_name} on {self.name}")
        print(f"    Caller: {caller}")
        print(f"    Args: {args}")
        
        try:
            self.block_height += 1
            result = function.function(self, caller, *args)
            print(f"    ✅ Result: {result}")
            return result
        except Exception as e:
            print(f"    ❌ Error: {e}")
            return None
    
    def receive_funds(self, amount: float, source: str) -> bool:
        """Receive ETH into the contract"""
        if amount <= 0:
            print(f" ❌ Invalid amount")
            return False
        
        self.balance += amount
        self.emit_event("FundsReceived", {"from": source, "amount": amount})
        print(f"  💰 Contract received {amount:.2f} ETH from {source[:16]}...")
        return True
    
    def send_funds(self, destination: str, amount: float, caller: str) -> bool:
        """Send ETH from the contract"""
        if self.balance < amount:
            print(f" ❌ Insufficient balance: {self.balance:.2f} < {amount:.2f}")
            return False
        
        self.balance -= amount
        self.emit_event("FundsSent", {"to": destination, "amount": amount})
        print(f"  💸 Contract sent {amount:.2f} ETH to {destination[:16]}...")
        return True
    
    def emit_event(self, event_name: str, data: Dict[str, Any]) -> None:
        """Emit an event from the contract"""
        event = ContractEvent(
            event_name=event_name,
            data=data,
            timestamp=time.time(),
            block_height=self.block_height
        )
        self.events.append(event)
        print(f"    📢 Event: {event_name} → {data}")
    
    def get_contract_info(self) -> Dict[str, Any]:
        """Get contract information"""
        return {
            "name": self.name,
            "address": self.address,
            "creator": self.creator,
            "owner": self.owner,
            "balance": self.balance,
            "status": self.status.value,
            "functions": list(self.functions.keys()),
            "storage": self.storage,
            "events": len(self.events),
            "block_height": self.block_height,
            "deployed_at": time.ctime(self.deployed_at)
        }
    
    def display_summary(self) -> None:
        """Display contract summary"""
        info = self.get_contract_info()
        print(f"\n  📋 {info['name']} Summary:")
        print(f"    Address: {info['address']}")
        print(f"    Creator: {info['creator']}")
        print(f"    Owner: {info['owner']}")
        print(f"    Balance: {info['balance']:.2f} ETH")
        print(f"    Status: {info['status']}")
        print(f"    Functions: {', '.join(info['functions'])}")
        print(f"    Events: {info['events']}")

# ============================================================================
# EXAMPLE CONTRACT FUNCTIONS
# ============================================================================

def simple_storage(contract: ContractAccount, caller: str, key: str, value: Any) -> bool:
    """Store a value in contract storage"""
    if caller != contract.owner:
        print(f"  ❌ Only owner can modify storage")
        return False
    
    old_value = contract.storage.get(key)
    contract.storage[key] = value
    contract.emit_event("StorageUpdated", {"key": key, "old_value": old_value, "new_value": value})
    print(f"  💾 Stored {key} = {value}")
    return True

def get_storage(contract: ContractAccount, caller: str, key: str) -> Any:
    """Get value from contract storage"""
    value = contract.storage.get(key, None)
    print(f"  📖 Retrieved {key} = {value}")
    return value

def transfer_ownership(contract: ContractAccount, caller: str, new_owner: str) -> bool:
    """Transfer contract ownership"""
    if caller != contract.owner:
        print(f"  ❌ Only current owner can transfer ownership")
        return False
    
    old_owner = contract.owner
    contract.owner = new_owner
    contract.emit_event("OwnershipTransferred", {"from": old_owner, "to": new_owner})
    print(f"  🔄 Ownership transferred from {old_owner[:8]}... to {new_owner[:8]}...")
    return True

def withdraw_balance(contract: ContractAccount, caller: str, amount: float) -> bool:
    """Withdraw ETH from the contract"""
    if caller != contract.owner:
        print(f"  ❌ Only owner can withdraw")
        return False
    
    if contract.balance < amount:
        print(f"  ❌ Insufficient balance: {contract.balance:.2f} < {amount:.2f}")
        return False
    
    contract.balance -= amount
    contract.emit_event("Withdrawal", {"to": caller, "amount": amount})
    print(f"  💰 Withdrew {amount:.2f} ETH to {caller[:16]}...")
    return True

def pause_contract(contract: ContractAccount, caller: str) -> bool:
    """Pause the contract"""
    if caller != contract.owner:
        print(f"  ❌ Only owner can pause")
        return False
    
    contract.status = ContractStatus.PAUSED
    contract.emit_event("ContractPaused", {"by": caller})
    print(f"  ⏸️  Contract paused by {caller[:16]}...")
    return True

def unpause_contract(contract: ContractAccount, caller: str) -> bool:
    """Unpause the contract"""
    if caller != contract.owner:
        print(f"  ❌ Only owner can unpause")
        return False
    
    contract.status = ContractStatus.ACTIVE
    contract.emit_event("ContractUnpaused", {"by": caller})
    print(f"  ▶️  Contract unpaused by {caller[:16]}...")
    return True

def destroy_contract(contract: ContractAccount, caller: str) -> bool:
    """Destroy the contract"""
    if caller != contract.owner:
        print(f"  ❌ Only owner can destroy")
        return False
    
    contract.status = ContractStatus.DESTROYED
    contract.emit_event("ContractDestroyed", {"by": caller})
    print(f"  💀 Contract destroyed by {caller[:16]}...")
    return True

def get_balance(contract: ContractAccount, caller: str) -> float:
    """Get contract balance (view function)"""
    return contract.balance

def add_number(contract: ContractAccount, caller: str, a: int, b: int) -> int:
    """Add two numbers (pure function)"""
    result = a + b
    print(f"  🧮 {a} + {b} = {result}")
    return result

# ============================================================================
# DEMONSTRATION
# ============================================================================

def contract_account_demonstration():
    """Execute comprehensive contract account demonstration"""
    print("=" * 60)
    print(" SMART CONTRACT ACCOUNT DEMONSTRATION")
    print("=" * 60)
    
    # Create contract
    print("\n 🏗️  Deploying Contract")
    print("-" * 40)
    
    contract = ContractAccount("StorageContract", "Alice")
    
    # Define functions
    print("\n 📝 Defining Functions")
    contract.define_function("store", simple_storage, ["key", "value"])
    contract.define_function("get", get_storage, ["key"], is_view=True)
    contract.define_function("transfer_ownership", transfer_ownership, ["new_owner"])
    contract.define_function("withdraw", withdraw_balance, ["amount"])
    contract.define_function("pause", pause_contract, [])
    contract.define_function("unpause", unpause_contract, [])
    contract.define_function("destroy", destroy_contract, [])
    contract.define_function("get_balance", get_balance, [], is_view=True)
    contract.define_function("add", add_number, ["a", "b"], is_view=True)
    
    # Fund the contract
    print("\n 💰 Funding Contract")
    print("-" * 40)
    contract.receive_funds(100, "Alice")
    contract.display_summary()
    
    # Call functions
    print("\n 📞 Calling Contract Functions")
    print("-" * 40)
    
    # Store data
    contract.call_function("store", "Alice", "user_count", 1000)
    contract.call_function("store", "Alice", "admin", "Alice")
    
    # Get data
    contract.call_function("get", "Alice", "user_count")
    contract.call_function("get", "Alice", "admin")
    
    # Add numbers
    contract.call_function("add", "Alice", 5, 3)
    
    # Transfer ownership
    print("\n 🔄 Transferring Ownership")
    print("-" * 40)
    contract.call_function("transfer_ownership", "Alice", "Bob")
    
    # Try unauthorized access
    print("\n ⛔ Unauthorized Access Attempts")
    print("-" * 40)
    contract.call_function("store", "Bob", "user_count", 2000)
    contract.call_function("withdraw", "Bob", 50)
    
    # Pause contract
    print("\n ⏸️  Pausing Contract")
    print("-" * 40)
    contract.call_function("pause", "Bob")  # Should fail
    contract.call_function("pause", "Alice")  # Should succeed
    
    # Try to use while paused
    print("\n 📞 Calling during paused state")
    print("-" * 40)
    contract.call_function("store", "Alice", "test_key", "test_value")
    
    # Unpause
    print("\n ▶️  Unpausing Contract")
    print("-" * 40)
    contract.call_function("unpause", "Alice")
    
    # Withdraw funds
    print("\n 💰 Withdrawing Funds")
    print("-" * 40)
    contract.call_function("withdraw", "Alice", 50)
    contract.call_function("get_balance", "Alice")
    
    # Final state
    print("\n 📊 Final Contract State")
    print("-" * 40)
    contract.display_summary()
    
    print("\n 📋 Recent Events:")
    for event in contract.events[-5:]:
        print(f"    📢 {event.event_name}: {event.data}")

if __name__ == "__main__":
    contract_account_demonstration()

1.8 ABI (Application Binary Interface)

What is ABI? The ABI (Application Binary Interface) is the interface between two program modules, typically between a smart contract and the outside world (like a dApp). It defines how to encode and decode data when calling contract functions.

ABI Components:

ComponentDescription
Function SignaturesNames and parameter types
Event DefinitionsEvent names and parameters
Encoding RulesHow to encode data for functions
Decoding RulesHow to decode data from functions

Example: When you interact with a smart contract through Ethers.js, the ABI tells the library how to format the function call and how to interpret the response.

Code Example – ABI Generation:

"""
ABI SIMULATION FRAMEWORK
=========================
Comprehensive ABI implementation with encoding and decoding capabilities
"""

import hashlib
import json
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class ParamType(Enum):
    """Parameter types for ABI"""
    ADDRESS = "address"
    UINT256 = "uint256"
    INT256 = "int256"
    BOOL = "bool"
    STRING = "string"
    BYTES = "bytes"
    BYTES32 = "bytes32"

@dataclass
class ABIParameter:
    """Represents an ABI parameter"""
    name: str
    param_type: ParamType
    indexed: bool = False

@dataclass
class ABIFunction:
    """Represents an ABI function"""
    name: str
    inputs: List[ABIParameter]
    outputs: List[ABIParameter]
    state_mutability: str = "nonpayable"
    constant: bool = False

@dataclass
class ABIEvent:
    """Represents an ABI event"""
    name: str
    inputs: List[ABIParameter]
    anonymous: bool = False

@dataclass
class EncodedCall:
    """Represents an encoded function call"""
    function_signature: str
    encoded_data: str
    function_hash: str
    parameters: Dict[str, Any]

class ABIEngine:
    """Complete ABI implementation with encoding/decoding"""
    
    def __init__(self, contract_name: str = "SimpleStorage"):
        self.contract_name = contract_name
        self.functions: Dict[str, ABIFunction] = {}
        self.events: Dict[str, ABIEvent] = {}
        print(f" 🔧 ABI Engine initialized for '{contract_name}'")
    
    def add_function(self, name: str, inputs: List[Tuple[str, ParamType]], 
                     outputs: List[Tuple[str, ParamType]] = None,
                     state_mutability: str = "nonpayable") -> ABIFunction:
        """Add a function to the ABI"""
        function = ABIFunction(
            name=name,
            inputs=[ABIParameter(name=p[0], param_type=p[1]) for p in inputs],
            outputs=[ABIParameter(name=p[0], param_type=p[1]) for p in (outputs or [])],
            state_mutability=state_mutability,
            constant=state_mutability == "view" or state_mutability == "pure"
        )
        self.functions[name] = function
        print(f"    ✅ Added function: {name}")
        return function
    
    def add_event(self, name: str, inputs: List[Tuple[str, ParamType, bool]]) -> ABIEvent:
        """Add an event to the ABI"""
        event = ABIEvent(
            name=name,
            inputs=[ABIParameter(name=p[0], param_type=p[1], indexed=p[2]) for p in inputs]
        )
        self.events[name] = event
        print(f"    ✅ Added event: {name}")
        return event
    
    def get_function_signature(self, function_name: str) -> str:
        """Get function signature"""
        if function_name not in self.functions:
            raise ValueError(f"Function '{function_name}' not found")
        
        func = self.functions[function_name]
        params = ",".join([p.param_type.value for p in func.inputs])
        return f"{function_name}({params})"
    
    def get_function_hash(self, function_name: str) -> str:
        """Get function hash (4 bytes)"""
        signature = self.get_function_signature(function_name)
        return hashlib.sha256(signature.encode()).hexdigest()[:8]
    
    def encode_function_call(self, function_name: str, args: List[Any]) -> EncodedCall:
        """Encode a function call"""
        if function_name not in self.functions:
            raise ValueError(f"Function '{function_name}' not found")
        
        func = self.functions[function_name]
        if len(args) != len(func.inputs):
            raise ValueError(f"Expected {len(func.inputs)} arguments, got {len(args)}")
        
        function_hash = self.get_function_hash(function_name)
        encoded_args = self._encode_parameters(func.inputs, args)
        
        return EncodedCall(
            function_signature=self.get_function_signature(function_name),
            encoded_data=function_hash + encoded_args,
            function_hash=function_hash,
            parameters={p.name: arg for p, arg in zip(func.inputs, args)}
        )
    
    def _encode_parameters(self, params: List[ABIParameter], args: List[Any]) -> str:
        """Encode parameters (simplified)"""
        encoded = ""
        for param, arg in zip(params, args):
            if param.param_type == ParamType.UINT256 or param.param_type == ParamType.INT256:
                if isinstance(arg, int):
                    encoded += f"{arg:064x}"
                else:
                    encoded += str(arg).encode().hex().rjust(64, '0')
            elif param.param_type == ParamType.ADDRESS:
                if isinstance(arg, str) and arg.startswith("0x"):
                    encoded += arg[2:].rjust(64, '0')
                else:
                    encoded += arg.rjust(64, '0')
            elif param.param_type == ParamType.BOOL:
                encoded += f"{1 if arg else 0:064x}"
            elif param.param_type == ParamType.STRING or param.param_type == ParamType.BYTES:
                # Simplified encoding: just convert to hex
                encoded += arg.encode().hex().rjust(64, '0')
            else:
                encoded += str(arg).encode().hex().rjust(64, '0')
        return encoded
    
    def decode_function_call(self, encoded_data: str) -> EncodedCall:
        """Decode an encoded function call (simplified)"""
        function_hash = encoded_data[:8]
        data = encoded_data[8:]
        
        # Find function by hash
        for name, func in self.functions.items():
            if self.get_function_hash(name) == function_hash:
                params = self._decode_parameters(func.inputs, data)
                return EncodedCall(
                    function_signature=self.get_function_signature(name),
                    encoded_data=encoded_data,
                    function_hash=function_hash,
                    parameters={p.name: arg for p, arg in zip(func.inputs, params)}
                )
        
        raise ValueError(f"Function with hash {function_hash} not found")
    
    def _decode_parameters(self, params: List[ABIParameter], data: str) -> List[Any]:
        """Decode parameters (simplified)"""
        decoded = []
        offset = 0
        for param in params:
            chunk = data[offset:offset+64]
            if param.param_type == ParamType.UINT256:
                decoded.append(int(chunk, 16))
            elif param.param_type == ParamType.INT256:
                val = int(chunk, 16)
                decoded.append(val if val < 2**255 else val - 2**256)
            elif param.param_type == ParamType.ADDRESS:
                decoded.append("0x" + chunk[-40:])
            elif param.param_type == ParamType.BOOL:
                decoded.append(int(chunk, 16) != 0)
            elif param.param_type == ParamType.STRING or param.param_type == ParamType.BYTES:
                decoded.append(bytes.fromhex(chunk).decode().strip('\x00'))
            else:
                decoded.append(chunk)
            offset += 64
        return decoded
    
    def get_abi_json(self) -> str:
        """Generate ABI as JSON"""
        abi = []
        
        # Functions
        for func in self.functions.values():
            abi_item = {
                "type": "function",
                "name": func.name,
                "inputs": [
                    {"name": p.name, "type": p.param_type.value} 
                    for p in func.inputs
                ],
                "outputs": [
                    {"name": p.name, "type": p.param_type.value} 
                    for p in func.outputs
                ],
                "stateMutability": func.state_mutability,
                "constant": func.constant
            }
            abi.append(abi_item)
        
        # Events
        for event in self.events.values():
            abi_item = {
                "type": "event",
                "name": event.name,
                "inputs": [
                    {"name": p.name, "type": p.param_type.value, "indexed": p.indexed} 
                    for p in event.inputs
                ],
                "anonymous": event.anonymous
            }
            abi.append(abi_item)
        
        return json.dumps(abi, indent=2)

def abi_demonstration():
    """Execute comprehensive ABI demonstration"""
    print("=" * 60)
    print(" ABI SIMULATION DEMONSTRATION")
    print("=" * 60)
    
    # Create ABI
    print("\n 📝 Creating ABI")
    print("-" * 40)
    
    abi_engine = ABIEngine("SimpleStorage")
    
    # Add functions
    abi_engine.add_function(
        "store",
        inputs=[("key", ParamType.STRING), ("value", ParamType.STRING)],
        outputs=[("success", ParamType.BOOL)]
    )
    
    abi_engine.add_function(
        "get",
        inputs=[("key", ParamType.STRING)],
        outputs=[("value", ParamType.STRING)],
        state_mutability="view"
    )
    
    abi_engine.add_function(
        "transfer",
        inputs=[("to", ParamType.ADDRESS), ("amount", ParamType.UINT256)],
        outputs=[("success", ParamType.BOOL)]
    )
    
    abi_engine.add_function(
        "balanceOf",
        inputs=[("account", ParamType.ADDRESS)],
        outputs=[("balance", ParamType.UINT256)],
        state_mutability="view"
    )
    
    # Add events
    abi_engine.add_event(
        "Stored",
        inputs=[("key", ParamType.STRING, False), ("value", ParamType.STRING, False), ("by", ParamType.ADDRESS, True)]
    )
    
    abi_engine.add_event(
        "Transferred",
        inputs=[("from", ParamType.ADDRESS, True), ("to", ParamType.ADDRESS, True), ("amount", ParamType.UINT256, False)]
    )
    
    # Display ABI
    print("\n 📊 ABI FUNCTIONS")
    print("-" * 40)
    
    for name, func in abi_engine.functions.items():
        inputs = ", ".join([f"{p.param_type.value} {p.name}" for p in func.inputs])
        outputs = ", ".join([o.param_type.value for o in func.outputs]) if func.outputs else "void"
        print(f"  {name}({inputs}) → {outputs} ({func.state_mutability})")
    
    print("\n 📋 ABI EVENTS")
    print("-" * 40)
    
    for name, event in abi_engine.events.items():
        inputs = ", ".join([f"{'indexed ' if p.indexed else ''}{p.param_type.value} {p.name}" for p in event.inputs])
        print(f"  {name}({inputs})")
    
    # Encode function calls
    print("\n 🔒 ENCODING DEMONSTRATION")
    print("-" * 40)
    
    # Encode store
    encoded_store = abi_engine.encode_function_call("store", ["user_count", "1000"])
    print(f"\n  store('user_count', '1000')")
    print(f"    Hash: {encoded_store.function_hash}")
    print(f"    Encoded: {encoded_store.encoded_data[:16]}...")
    print(f"    Parameters: {encoded_store.parameters}")
    
    # Encode transfer
    encoded_transfer = abi_engine.encode_function_call("transfer", ["0x742d35Cc6634C053", 1000])
    print(f"\n  transfer('0x742d35Cc6634C053', 1000)")
    print(f"    Hash: {encoded_transfer.function_hash}")
    print(f"    Encoded: {encoded_transfer.encoded_data[:16]}...")
    print(f"    Parameters: {encoded_transfer.parameters}")
    
    # Decode
    print("\n 🔓 DECODING DEMONSTRATION")
    print("-" * 40)
    
    decoded = abi_engine.decode_function_call(encoded_store.encoded_data)
    print(f"\n  Decoded: {decoded.function_signature}")
    print(f"    Parameters: {decoded.parameters}")
    
    # Show ABI JSON
    print("\n 📄 ABI JSON")
    print("-" * 40)
    print(abi_engine.get_abi_json())
    
    print("\n" + "=" * 60)
    print(" ABI SUMMARY:")
    print("   ✓ ABI = Application Binary Interface")
    print("   ✓ Defines how to interact with smart contracts")
    print("   ✓ Specifies functions, events, and parameters")
    print("   ✓ Used for encoding/decoding calls")
    print("   ✓ Essential for dApps and contract interaction")
    print("   ✓ Standardized JSON format")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    abi_demonstration()

1.9 Bytecode

What is Bytecode? Bytecode is the compiled version of smart contract code that runs on the EVM. When you write a smart contract in Solidity, it gets compiled to bytecode, which is what gets deployed to the blockchain.

Bytecode Characteristics:

CharacteristicDescription
Low-LevelMachine-like instructions
EVM ExecutableDirectly run by the EVM
Gas-OptimizedEach instruction costs gas
ImmutableCannot be changed after deployment

Example: A simple Solidity function function add(uint a, uint b) returns (uint) compiles to EVM bytecode that pushes values onto the stack, adds them, and returns the result.

Code Example – Bytecode Generation:

"""
BYTECODE GENERATION FRAMEWORK
==============================
Complete EVM bytecode generation and disassembly demonstration
"""

import hashlib
import json
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class OpCode(Enum):
    """EVM OpCodes with their byte values"""
    STOP = "00"
    ADD = "01"
    MUL = "02"
    SUB = "03"
    DIV = "04"
    SDIV = "05"
    MOD = "06"
    SMOD = "07"
    ADDMOD = "08"
    MULMOD = "09"
    EXP = "0A"
    SIGNEXTEND = "0B"
    LT = "10"
    GT = "11"
    SLT = "12"
    SGT = "13"
    EQ = "14"
    ISZERO = "15"
    AND = "16"
    OR = "17"
    XOR = "18"
    NOT = "19"
    BYTE = "1A"
    SHL = "1B"
    SHR = "1C"
    SAR = "1D"
    SHA3 = "20"
    ADDRESS = "30"
    BALANCE = "31"
    ORIGIN = "32"
    CALLER = "33"
    CALLVALUE = "34"
    CALLDATALOAD = "35"
    CALLDATASIZE = "36"
    CALLDATACOPY = "37"
    CODESIZE = "38"
    CODECOPY = "39"
    GASPRICE = "3A"
    EXTCODESIZE = "3B"
    EXTCODECOPY = "3C"
    RETURNDATASIZE = "3D"
    RETURNDATACOPY = "3E"
    EXTCODEHASH = "3F"
    BLOCKHASH = "40"
    COINBASE = "41"
    TIMESTAMP = "42"
    NUMBER = "43"
    DIFFICULTY = "44"
    GASLIMIT = "45"
    CHAINID = "46"
    SELFBALANCE = "47"
    BASEFEE = "48"
    POP = "50"
    MLOAD = "51"
    MSTORE = "52"
    MSTORE8 = "53"
    SLOAD = "54"
    SSTORE = "55"
    JUMP = "56"
    JUMPI = "57"
    PC = "58"
    MSIZE = "59"
    GAS = "5A"
    JUMPDEST = "5B"
    PUSH1 = "60"
    PUSH2 = "61"
    PUSH3 = "62"
    PUSH4 = "63"
    PUSH5 = "64"
    PUSH6 = "65"
    PUSH7 = "66"
    PUSH8 = "67"
    PUSH9 = "68"
    PUSH10 = "69"
    PUSH11 = "6A"
    PUSH12 = "6B"
    PUSH13 = "6C"
    PUSH14 = "6D"
    PUSH15 = "6E"
    PUSH16 = "6F"
    PUSH17 = "70"
    PUSH18 = "71"
    PUSH19 = "72"
    PUSH20 = "73"
    PUSH21 = "74"
    PUSH22 = "75"
    PUSH23 = "76"
    PUSH24 = "77"
    PUSH25 = "78"
    PUSH26 = "79"
    PUSH27 = "7A"
    PUSH28 = "7B"
    PUSH29 = "7C"
    PUSH30 = "7D"
    PUSH31 = "7E"
    PUSH32 = "7F"
    DUP1 = "80"
    DUP2 = "81"
    DUP3 = "82"
    DUP4 = "83"
    DUP5 = "84"
    DUP6 = "85"
    DUP7 = "86"
    DUP8 = "87"
    DUP9 = "88"
    DUP10 = "89"
    DUP11 = "8A"
    DUP12 = "8B"
    DUP13 = "8C"
    DUP14 = "8D"
    DUP15 = "8E"
    DUP16 = "8F"
    SWAP1 = "90"
    SWAP2 = "91"
    SWAP3 = "92"
    SWAP4 = "93"
    SWAP5 = "94"
    SWAP6 = "95"
    SWAP7 = "96"
    SWAP8 = "97"
    SWAP9 = "98"
    SWAP10 = "99"
    SWAP11 = "9A"
    SWAP12 = "9B"
    SWAP13 = "9C"
    SWAP14 = "9D"
    SWAP15 = "9E"
    SWAP16 = "9F"
    LOG0 = "A0"
    LOG1 = "A1"
    LOG2 = "A2"
    LOG3 = "A3"
    LOG4 = "A4"
    CREATE = "F0"
    CALL = "F1"
    CALLCODE = "F2"
    RETURN = "F3"
    DELEGATECALL = "F4"
    CREATE2 = "F5"
    STATICCALL = "FA"
    REVERT = "FD"
    INVALID = "FE"
    SELFDESTRUCT = "FF"

@dataclass
class BytecodeInstruction:
    """Represents a bytecode instruction"""
    opcode: OpCode
    operand: Optional[str] = None
    offset: int = 0
    size: int = 0

@dataclass
class CompiledContract:
    """Represents a compiled contract"""
    name: str
    bytecode: bytes
    hex_bytecode: str
    instructions: List[BytecodeInstruction]
    size: int
    hash: str

class BytecodeEngine:
    """Complete bytecode generation and disassembly engine"""
    
    def __init__(self):
        self.opcode_map = {op.value: op for op in OpCode}
        self.opcode_names = {op.value: op.name for op in OpCode}
        self.instruction_cache = {}
        print(" 🔧 Bytecode Engine initialized")
    
    def compile_function(self, function_name: str, args: List[Any], return_type: str = "uint") -> List[BytecodeInstruction]:
        """Compile a Solidity function to bytecode instructions"""
        instructions = []
        
        # Push arguments onto stack (in reverse order)
        for i in range(len(args) - 1, -1, -1):
            arg = args[i]
            if isinstance(arg, int):
                if arg <= 0xFF:
                    instructions.append(BytecodeInstruction(OpCode.PUSH1, hex(arg)[2:].rjust(2, '0')))
                elif arg <= 0xFFFF:
                    instructions.append(BytecodeInstruction(OpCode.PUSH2, hex(arg)[2:].rjust(4, '0')))
                elif arg <= 0xFFFFFFFF:
                    instructions.append(BytecodeInstruction(OpCode.PUSH4, hex(arg)[2:].rjust(8, '0')))
                else:
                    instructions.append(BytecodeInstruction(OpCode.PUSH32, hex(arg)[2:].rjust(64, '0')))
            elif isinstance(arg, str):
                if arg.startswith("0x"):
                    instructions.append(BytecodeInstruction(OpCode.PUSH20, arg[2:].rjust(40, '0')))
                else:
                    # String literal - simplified
                    hex_val = arg.encode().hex()
                    if len(hex_val) <= 2:
                        instructions.append(BytecodeInstruction(OpCode.PUSH1, hex_val))
                    else:
                        instructions.append(BytecodeInstruction(OpCode.PUSH32, hex_val.rjust(64, '0')))
            else:
                instructions.append(BytecodeInstruction(OpCode.PUSH1, "00"))
        
        # Function logic
        if function_name == "add":
            instructions.append(BytecodeInstruction(OpCode.ADD))
        elif function_name == "sub":
            instructions.append(BytecodeInstruction(OpCode.SUB))
        elif function_name == "mul":
            instructions.append(BytecodeInstruction(OpCode.MUL))
        elif function_name == "div":
            instructions.append(BytecodeInstruction(OpCode.DIV))
        elif function_name == "store":
            instructions.append(BytecodeInstruction(OpCode.SSTORE))
        elif function_name == "load":
            instructions.append(BytecodeInstruction(OpCode.SLOAD))
        elif function_name == "transfer":
            instructions.append(BytecodeInstruction(OpCode.CALL))
        else:
            instructions.append(BytecodeInstruction(OpCode.STOP))
        
        # Return the result
        if return_type != "void":
            instructions.append(BytecodeInstruction(OpCode.PUSH1, "00"))
            instructions.append(BytecodeInstruction(OpCode.MLOAD))
            instructions.append(BytecodeInstruction(OpCode.PUSH1, "20"))
            instructions.append(BytecodeInstruction(OpCode.RETURN))
        
        return instructions
    
    def assemble_bytecode(self, instructions: List[BytecodeInstruction]) -> str:
        """Assemble instructions into hex bytecode"""
        hex_parts = []
        offset = 0
        
        for instr in instructions:
            hex_parts.append(instr.opcode.value)
            offset += 1
            if instr.operand:
                hex_parts.append(instr.operand)
                offset += len(instr.operand) // 2
            instr.offset = offset - len(instr.operand) // 2 if instr.operand else offset - 1
            instr.size = len(instr.operand) // 2 if instr.operand else 0
        
        return "".join(hex_parts)
    
    def disassemble_bytecode(self, hex_bytecode: str) -> List[BytecodeInstruction]:
        """Disassemble hex bytecode into instructions"""
        instructions = []
        i = 0
        offset = 0
        
        while i < len(hex_bytecode):
            op_hex = hex_bytecode[i:i+2]
            opcode = self.opcode_map.get(op_hex)
            
            if not opcode:
                instructions.append(BytecodeInstruction(OpCode.INVALID, op_hex, offset))
                i += 2
                offset += 1
                continue
            
            if opcode.name.startswith("PUSH"):
                num_bytes = int(opcode.name.replace("PUSH", ""))
                if i + 2 + num_bytes * 2 <= len(hex_bytecode):
                    operand = hex_bytecode[i+2:i+2+num_bytes*2]
                    instructions.append(BytecodeInstruction(opcode, operand, offset))
                    i += 2 + num_bytes * 2
                    offset += 1 + num_bytes
                else:
                    instructions.append(BytecodeInstruction(opcode, "incomplete", offset))
                    i += 2
                    offset += 1
            else:
                instructions.append(BytecodeInstruction(opcode, None, offset))
                i += 2
                offset += 1
        
        return instructions
    
    def compile_contract(self, name: str, instructions: List[BytecodeInstruction]) -> CompiledContract:
        """Compile a complete contract"""
        hex_bytecode = self.assemble_bytecode(instructions)
        bytecode = bytes.fromhex(hex_bytecode)
        bytecode_hash = hashlib.sha256(bytecode).hexdigest()
        
        return CompiledContract(
            name=name,
            bytecode=bytecode,
            hex_bytecode=hex_bytecode,
            instructions=instructions,
            size=len(bytecode),
            hash=bytecode_hash
        )
    
    def display_instructions(self, instructions: List[BytecodeInstruction]) -> None:
        """Display instructions in a readable format"""
        print(f"\n {'Offset':>8} | {'Opcode':>15} | {'Operand':>30} | {'Hex':>30}")
        print("-" * 90)
        
        for instr in instructions:
            offset_str = f"0x{instr.offset:04x}"
            opcode_str = instr.opcode.name
            operand_str = instr.operand if instr.operand else ""
            hex_str = instr.opcode.value + (instr.operand if instr.operand else "")
            
            print(f" {offset_str:>8} | {opcode_str:>15} | {operand_str:>30} | {hex_str:>30}")

def bytecode_demonstration():
    """Execute comprehensive bytecode demonstration"""
    print("=" * 60)
    print(" BYTECODE GENERATION DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = BytecodeEngine()
    
    # Compile different functions
    print("\n 📝 COMPILING FUNCTIONS")
    print("-" * 40)
    
    functions = [
        ("add", [5, 3], "uint"),
        ("store", [0, 100], "void"),
        ("transfer", ["0x742d35Cc6634C053", 50], "bool")
    ]
    
    for func_name, args, return_type in functions:
        print(f"\n  Function: {func_name}({', '.join(str(a) for a in args)}) → {return_type}")
        
        instructions = engine.compile_function(func_name, args, return_type)
        hex_bytecode = engine.assemble_bytecode(instructions)
        
        print(f"    Instructions: {len(instructions)}")
        print(f"    Bytecode Hex: {hex_bytecode[:32]}...")
        
        # Show first few instructions
        print(f"    Instructions:")
        for instr in instructions[:5]:
            op_str = instr.opcode.name
            op_val = instr.operand if instr.operand else ""
            print(f"      {op_str} {op_val}")
        if len(instructions) > 5:
            print(f"      ... ({len(instructions)-5} more)")
    
    # Complete contract example
    print("\n 📝 COMPLETE CONTRACT EXAMPLE")
    print("-" * 40)
    
    # Storage contract: store value 100 at key 0, then load and return
    contract_instructions = [
        BytecodeInstruction(OpCode.PUSH1, "64"),   # value 100
        BytecodeInstruction(OpCode.PUSH1, "00"),   # key 0
        BytecodeInstruction(OpCode.SSTORE),         # storage[0] = 100
        BytecodeInstruction(OpCode.PUSH1, "00"),   # key 0
        BytecodeInstruction(OpCode.SLOAD),          # value = storage[0]
        BytecodeInstruction(OpCode.PUSH1, "00"),   # memory offset 0
        BytecodeInstruction(OpCode.MLOAD),          # load from memory
        BytecodeInstruction(OpCode.PUSH1, "20"),   # size 32 bytes
        BytecodeInstruction(OpCode.RETURN)          # return the value
    ]
    
    contract = engine.compile_contract("SimpleStorage", contract_instructions)
    
    print(f"\n  Contract: {contract.name}")
    print(f"  Size: {contract.size} bytes")
    print(f"  Hash: {contract.hash[:16]}...")
    print(f"  Bytecode: {contract.hex_bytecode[:64]}...")
    
    print("\n  Disassembled Instructions:")
    engine.display_instructions(contract.instructions)
    
    # Demonstrate gas estimation
    print("\n ⛽ GAS ESTIMATION")
    print("-" * 40)
    
    gas_costs = {
        "PUSH1": 3, "PUSH2": 3, "PUSH4": 3, "PUSH32": 3,
        "SSTORE": 20000, "SLOAD": 200, "MLOAD": 3, "MSTORE": 3,
        "ADD": 3, "SUB": 3, "MUL": 5, "DIV": 5,
        "RETURN": 0, "STOP": 0, "CALL": 100, "JUMP": 8
    }
    
    total_gas = 0
    print(f"\n {'Opcode':>15} | {'Gas Cost':>12} | {'Count':>10} | {'Total':>15}")
    print("-" * 60)
    
    gas_usage = {}
    for instr in contract.instructions:
        op_name = instr.opcode.name
        gas_usage[op_name] = gas_usage.get(op_name, 0) + 1
    
    for op_name, count in gas_usage.items():
        cost = gas_costs.get(op_name, 3)
        total = cost * count
        total_gas += total
        print(f" {op_name:>15} | {cost:>12} | {count:>10} | {total:>15}")
    
    print(f"\n  Total Gas Estimate: {total_gas}")
    print(f"  Base Cost: 21000")
    print(f"  Total with Base: {total_gas + 21000}")

if __name__ == "__main__":
    bytecode_demonstration()

1.10 Gas & Execution

What is Gas? Gas is the fee paid to execute transactions and smart contracts on Ethereum. It’s measured in “gas units” and paid in ETH (Gwei). Gas ensures that the network remains secure and prevents infinite loops.

Gas Components:

ComponentDescription
Gas LimitMaximum gas a user is willing to pay
Gas PriceAmount per gas unit (in Gwei)
Base FeeMinimum fee set by the network
Priority FeeTip to validators for faster inclusion

Example: A standard ETH transfer typically requires 21,000 units of gas. If gas price is 50 Gwei, the total cost is 21,000 × 50 Gwei = 1,050,000 Gwei = 0.00105 ETH.

Code Example – Gas Calculation:

"""
GAS EXECUTION FRAMEWORK
========================
Comprehensive gas cost simulation and transaction execution demonstration
"""

import time
import math
from typing import Dict, List, Any, Optional, Tuple
from dataclasses import dataclass, field
from enum import Enum

class OperationType(Enum):
    """Classification of EVM operations"""
    ARITHMETIC = "Arithmetic"
    STORAGE = "Storage"
    MEMORY = "Memory"
    STACK = "Stack"
    FLOW = "Flow Control"
    ENVIRONMENT = "Environment"
    LOG = "Log"
    SYSTEM = "System"
    BASE = "Base"

@dataclass
class GasCost:
    """Represents gas cost for an operation"""
    operation: str
    cost: int
    operation_type: OperationType
    description: str

@dataclass
class ExecutionResult:
    """Represents the result of transaction execution"""
    success: bool
    gas_used: int
    gas_limit: int
    gas_price_gwei: int
    total_cost_eth: float
    operations_executed: int
    execution_time: float
    error: Optional[str] = None

@dataclass
class TransactionExecution:
    """Represents a transaction execution"""
    from_address: str
    to_address: str
    value: float
    data: str
    gas_limit: int
    gas_price: int

class GasExecutionEngine:
    """Complete gas and execution simulation engine"""
    
    def __init__(self):
        self.gas_costs: Dict[str, GasCost] = {}
        self._initialize_gas_costs()
        self.total_gas_used = 0
        self.operation_count = 0
        print(" ⛽ Gas Execution Engine initialized")
    
    def _initialize_gas_costs(self) -> None:
        """Initialize gas costs for all operations"""
        costs = [
            # Arithmetic operations
            GasCost("ADD", 3, OperationType.ARITHMETIC, "Addition"),
            GasCost("SUB", 3, OperationType.ARITHMETIC, "Subtraction"),
            GasCost("MUL", 5, OperationType.ARITHMETIC, "Multiplication"),
            GasCost("DIV", 5, OperationType.ARITHMETIC, "Integer Division"),
            GasCost("SDIV", 5, OperationType.ARITHMETIC, "Signed Division"),
            GasCost("MOD", 5, OperationType.ARITHMETIC, "Modulo"),
            GasCost("SMOD", 5, OperationType.ARITHMETIC, "Signed Modulo"),
            GasCost("ADDMOD", 8, OperationType.ARITHMETIC, "Add Modulo"),
            GasCost("MULMOD", 8, OperationType.ARITHMETIC, "Multiply Modulo"),
            GasCost("EXP", 10, OperationType.ARITHMETIC, "Exponentiation"),
            
            # Storage operations
            GasCost("SLOAD", 200, OperationType.STORAGE, "Storage Load"),
            GasCost("SSTORE", 20000, OperationType.STORAGE, "Storage Store (Cold)"),
            GasCost("SSTORE_WARM", 100, OperationType.STORAGE, "Storage Store (Warm)"),
            
            # Memory operations
            GasCost("MLOAD", 3, OperationType.MEMORY, "Memory Load"),
            GasCost("MSTORE", 3, OperationType.MEMORY, "Memory Store"),
            GasCost("MSTORE8", 3, OperationType.MEMORY, "Memory Store 8-bit"),
            
            # Stack operations
            GasCost("POP", 2, OperationType.STACK, "Pop from Stack"),
            GasCost("DUP", 3, OperationType.STACK, "Duplicate Stack Item"),
            GasCost("SWAP", 3, OperationType.STACK, "Swap Stack Items"),
            
            # Flow control
            GasCost("JUMP", 8, OperationType.FLOW, "Jump"),
            GasCost("JUMPI", 10, OperationType.FLOW, "Jump If"),
            GasCost("JUMPDEST", 1, OperationType.FLOW, "Jump Destination"),
            
            # Environment
            GasCost("ADDRESS", 2, OperationType.ENVIRONMENT, "Get Address"),
            GasCost("BALANCE", 700, OperationType.ENVIRONMENT, "Get Balance"),
            GasCost("CALLER", 2, OperationType.ENVIRONMENT, "Get Caller"),
            GasCost("CALLVALUE", 2, OperationType.ENVIRONMENT, "Get Call Value"),
            
            # Log
            GasCost("LOG0", 375, OperationType.LOG, "Log 0 Topics"),
            GasCost("LOG1", 750, OperationType.LOG, "Log 1 Topic"),
            GasCost("LOG2", 1125, OperationType.LOG, "Log 2 Topics"),
            GasCost("LOG3", 1500, OperationType.LOG, "Log 3 Topics"),
            GasCost("LOG4", 1875, OperationType.LOG, "Log 4 Topics"),
            
            # System operations
            GasCost("CREATE", 32000, OperationType.SYSTEM, "Create Contract"),
            GasCost("CALL", 700, OperationType.SYSTEM, "Call Contract"),
            GasCost("DELEGATECALL", 700, OperationType.SYSTEM, "Delegate Call"),
            GasCost("RETURN", 0, OperationType.SYSTEM, "Return"),
            GasCost("REVERT", 0, OperationType.SYSTEM, "Revert"),
            GasCost("SELFDESTRUCT", 5000, OperationType.SYSTEM, "Self Destruct"),
            
            # Base
            GasCost("BASE", 21000, OperationType.BASE, "Base Transaction Cost"),
        ]
        
        for cost in costs:
            self.gas_costs[cost.operation] = cost
    
    def get_gas_cost(self, operation: str) -> int:
        """Get gas cost for an operation"""
        return self.gas_costs.get(operation, GasCost(operation, 0, OperationType.SYSTEM, "Unknown")).cost
    
    def execute_operation(self, operation: str, **kwargs) -> int:
        """Execute a single operation and return gas cost"""
        gas_cost = self.get_gas_cost(operation)
        self.total_gas_used += gas_cost
        self.operation_count += 1
        
        # Simulate execution based on operation
        if operation in ["SSTORE", "SLOAD"]:
            time.sleep(0.0001)  # Storage operations are slower
        elif operation in ["CREATE", "CALL"]:
            time.sleep(0.0005)  # System operations are slower
        else:
            time.sleep(0.00001)  # Normal operations
        
        return gas_cost
    
    def execute_transaction(self, tx: TransactionExecution) -> ExecutionResult:
        """Execute a complete transaction with gas metering"""
        start_time = time.time()
        self.total_gas_used = 0
        self.operation_count = 0
        error = None
        success = True
        
        try:
            # Base cost
            self.execute_operation("BASE")
            
            # Parse and execute operations from data
            operations = tx.data.split() if tx.data else []
            
            for op in operations:
                if self.total_gas_used > tx.gas_limit:
                    raise ValueError("Out of gas")
                self.execute_operation(op)
            
            # If there's a value transfer
            if tx.value > 0:
                self.execute_operation("CALL")
                
        except Exception as e:
            success = False
            error = str(e)
        
        execution_time = time.time() - start_time
        total_cost_eth = (self.total_gas_used * tx.gas_price) / 1e9
        
        return ExecutionResult(
            success=success,
            gas_used=self.total_gas_used,
            gas_limit=tx.gas_limit,
            gas_price_gwei=tx.gas_price,
            total_cost_eth=total_cost_eth,
            operations_executed=self.operation_count,
            execution_time=execution_time,
            error=error
        )
    
    def estimate_gas(self, operations: List[str]) -> int:
        """Estimate gas for a sequence of operations"""
        total = self.get_gas_cost("BASE")
        for op in operations:
            total += self.get_gas_cost(op)
        return total
    
    def display_gas_costs(self, operation_type: Optional[OperationType] = None) -> None:
        """Display gas costs"""
        print("\n 📊 GAS COSTS")
        print("-" * 40)
        
        filtered = [
            cost for cost in self.gas_costs.values()
            if not operation_type or cost.operation_type == operation_type
        ]
        
        print(f"\n {'Operation':>20} | {'Cost':>10} | {'Type':>15} | {'Description':>25}")
        print("-" * 80)
        
        for cost in sorted(filtered, key=lambda x: -x.cost):
            if cost.cost > 0:
                print(f" {cost.operation:>20} | {cost.cost:>10} | {cost.operation_type.value:>15} | {cost.description:>25}")

def gas_execution_demonstration():
    """Execute comprehensive gas and execution demonstration"""
    print("=" * 60)
    print(" ⛽ GAS EXECUTION DEMONSTRATION")
    print("=" * 60)
    
    # Initialize engine
    engine = GasExecutionEngine()
    
    # Display gas costs
    engine.display_gas_costs()
    
    # High-cost operations
    print("\n 📊 HIGH-COST OPERATIONS")
    print("-" * 40)
    
    high_cost = [cost for cost in engine.gas_costs.values() if cost.cost >= 1000]
    print(f"\n {'Operation':>20} | {'Cost':>10} | {'Description':>30}")
    print("-" * 65)
    for cost in sorted(high_cost, key=lambda x: -x.cost):
        print(f" {cost.operation:>20} | {cost.cost:>10} | {cost.description:>30}")
    
    # Execute transactions
    print("\n 📝 EXECUTING TRANSACTIONS")
    print("-" * 40)
    
    transactions = [
        TransactionExecution(
            from_address="0xAlice",
            to_address="0xBob",
            value=1.0,
            data="",
            gas_limit=21000,
            gas_price=50
        ),
        TransactionExecution(
            from_address="0xAlice",
            to_address="0xContract",
            value=0,
            data="SSTORE SLOAD ADD",
            gas_limit=100000,
            gas_price=50
        ),
        TransactionExecution(
            from_address="0xAlice",
            to_address="0xContract",
            value=0,
            data="SSTORE SLOAD ADD MUL DIV LOG2 CREATE CALL",
            gas_limit=200000,
            gas_price=50
        )
    ]
    
    for i, tx in enumerate(transactions, 1):
        print(f"\n  Transaction {i}:")
        print(f"    From: {tx.from_address}")
        print(f"    To: {tx.to_address}")
        print(f"    Value: {tx.value} ETH")
        print(f"    Data: {tx.data}")
        print(f"    Gas Limit: {tx.gas_limit}")
        print(f"    Gas Price: {tx.gas_price} Gwei")
        
        result = engine.execute_transaction(tx)
        
        print(f"\n  ⛽ Results:")
        print(f"    Success: {'✅' if result.success else '❌'}")
        print(f"    Gas Used: {result.gas_used}")
        print(f"    Gas Remaining: {result.gas_limit - result.gas_used}")
        print(f"    Total Cost: {result.total_cost_eth:.6f} ETH")
        print(f"    Operations: {result.operations_executed}")
        print(f"    Execution Time: {result.execution_time:.4f}s")
        if result.error:
            print(f"    Error: {result.error}")
    
    # Gas estimation
    print("\n 📊 GAS ESTIMATION")
    print("-" * 40)
    
    operation_sets = [
        ["SSTORE", "SLOAD"],
        ["ADD", "SUB", "MUL", "DIV"],
        ["CALL", "CREATE"],
        ["LOG0", "LOG1", "LOG2", "LOG3", "LOG4"]
    ]
    
    for ops in operation_sets:
        estimate = engine.estimate_gas(ops)
        print(f"\n  {', '.join(ops)}")
        print(f"    Estimated Gas: {estimate}")
        print(f"    Cost (50 Gwei): {estimate * 50 / 1e9:.6f} ETH")
        print(f"    Cost (100 Gwei): {estimate * 100 / 1e9:.6f} ETH")

if __name__ == "__main__":
    gas_execution_demonstration()

1.11 JSON-RPC

What is JSON-RPC? JSON-RPC is a lightweight remote procedure call (RPC) protocol that uses JSON to encode requests and responses. It’s used to communicate with blockchain nodes, sending requests and receiving responses.

Common JSON-RPC Methods:

MethodDescription
eth_blockNumberGet current block number
eth_getBalanceGet balance of an address
eth_sendTransactionSend a transaction
eth_callExecute a smart contract call
eth_getTransactionReceiptGet transaction receipt

Example: When MetaMask sends a transaction, it uses JSON-RPC to communicate with an Ethereum node.

Code Example – JSON-RPC Simulation:

"""
JSON-RPC COMMUNICATION FRAMEWORK
=================================
Complete JSON-RPC implementation for blockchain node communication
"""

import json
import hashlib
import time
from typing import Dict, Any, List, Optional, Union
from dataclasses import dataclass, field
from enum import Enum

class RPCErrorCode(Enum):
    """JSON-RPC error codes"""
    PARSE_ERROR = -32700
    INVALID_REQUEST = -32600
    METHOD_NOT_FOUND = -32601
    INVALID_PARAMS = -32602
    INTERNAL_ERROR = -32603
    SERVER_ERROR = -32000

@dataclass
class RPCRequest:
    """Represents a JSON-RPC request"""
    jsonrpc: str = "2.0"
    method: str = ""
    params: List[Any] = field(default_factory=list)
    id: Optional[int] = None

@dataclass
class RPCResponse:
    """Represents a JSON-RPC response"""
    jsonrpc: str = "2.0"
    id: Optional[int] = None
    result: Any = None
    error: Optional[Dict[str, Any]] = None

@dataclass
class BlockData:
    """Represents a blockchain block"""
    number: int
    hash: str
    timestamp: float
    transactions: List[str]
    parent_hash: str
    gas_used: int
    gas_limit: int

@dataclass
class TransactionData:
    """Represents a blockchain transaction"""
    hash: str
    from_address: str
    to_address: str
    value: int
    gas: int
    gas_price: int
    nonce: int
    data: str
    block_number: Optional[int] = None

class JSONRPCNode:
    """Complete JSON-RPC node simulation with Ethereum-compatible endpoints"""

    def __init__(self, node_name: str = "Node-1"):
        self.node_name = node_name
        self.chain: List[BlockData] = []
        self.accounts: Dict[str, int] = {}
        self.transactions: Dict[str, TransactionData] = {}
        self.pending_transactions: List[TransactionData] = []
        self._initialize_genesis()
        self._initialize_gas_prices()
        print(f" 🖥️  JSON-RPC Node '{node_name}' initialized")

    def _initialize_genesis(self) -> None:
        """Create genesis block"""
        genesis = BlockData(
            number=0,
            hash=hashlib.sha256(b"genesis").hexdigest(),
            timestamp=time.time(),
            transactions=[],
            parent_hash="0" * 64,
            gas_used=0,
            gas_limit=30000000
        )
        self.chain.append(genesis)

    def _initialize_gas_prices(self) -> None:
        """Initialize gas price data"""
        self.gas_price_oracle = {
            "low": 10,
            "medium": 30,
            "high": 50,
            "base_fee": 20
        }

    def _create_block(self, transactions: List[TransactionData]) -> BlockData:
        """Create a new block from transactions"""
        block = BlockData(
            number=len(self.chain),
            hash=hashlib.sha256(f"{len(self.chain)}{time.time()}".encode()).hexdigest(),
            timestamp=time.time(),
            transactions=[tx.hash for tx in transactions],
            parent_hash=self.chain[-1].hash,
            gas_used=sum(tx.gas for tx in transactions),
            gas_limit=30000000
        )
        self.chain.append(block)
        return block

    def _validate_transaction(self, tx: TransactionData) -> bool:
        """Validate a transaction"""
        if tx.from_address not in self.accounts:
            return False
        if self.accounts[tx.from_address] < tx.value + (tx.gas * tx.gas_price):
            return False
        return True

    # ===============================
    # JSON-RPC METHODS
    # ===============================

    def eth_blockNumber(self) -> RPCResponse:
        """Return the current block number"""
        return RPCResponse(
            id=1,
            result=hex(len(self.chain) - 1)
        )

    def eth_getBalance(self, address: str) -> RPCResponse:
        """Get balance of an address"""
        balance = self.accounts.get(address, 0)
        return RPCResponse(
            id=1,
            result=hex(balance)
        )

    def eth_getTransactionCount(self, address: str) -> RPCResponse:
        """Get transaction count (nonce) for an address"""
        count = sum(1 for tx in self.transactions.values() if tx.from_address == address)
        return RPCResponse(
            id=1,
            result=hex(count)
        )

    def eth_sendTransaction(self, tx_params: Dict) -> RPCResponse:
        """Send a transaction"""
        # Validate required fields
        required = ["from", "to", "value"]
        for field in required:
            if field not in tx_params:
                return RPCResponse(
                    id=1,
                    error={
                        "code": RPCErrorCode.INVALID_PARAMS.value,
                        "message": f"Missing required field: {field}"
                    }
                )

        # Create transaction
        tx = TransactionData(
            hash=hashlib.sha256(json.dumps(tx_params).encode()).hexdigest(),
            from_address=tx_params["from"],
            to_address=tx_params["to"],
            value=tx_params["value"],
            gas=tx_params.get("gas", 21000),
            gas_price=tx_params.get("gasPrice", 50),
            nonce=tx_params.get("nonce", 0),
            data=tx_params.get("data", "")
        )

        # Validate
        if not self._validate_transaction(tx):
            return RPCResponse(
                id=1,
                error={
                    "code": RPCErrorCode.SERVER_ERROR.value,
                    "message": "Insufficient funds or invalid transaction"
                }
            )

        # Process transaction
        self.accounts[tx.from_address] -= (tx.value + (tx.gas * tx.gas_price))
        self.accounts[tx.to_address] = self.accounts.get(tx.to_address, 0) + tx.value

        tx.block_number = len(self.chain)
        self.transactions[tx.hash] = tx
        self.pending_transactions.append(tx)

        # Mine a block (simplified)
        if len(self.pending_transactions) >= 2:
            block = self._create_block(self.pending_transactions)
            self.pending_transactions = []
            print(f"   ⛏️  Mined block {block.number} with {len(block.transactions)} transactions")

        return RPCResponse(
            id=1,
            result=tx.hash
        )

    def eth_getTransactionReceipt(self, tx_hash: str) -> RPCResponse:
        """Get transaction receipt"""
        if tx_hash not in self.transactions:
            return RPCResponse(
                id=1,
                error={
                    "code": RPCErrorCode.SERVER_ERROR.value,
                    "message": "Transaction not found"
                }
            )

        tx = self.transactions[tx_hash]
        return RPCResponse(
            id=1,
            result={
                "transactionHash": tx.hash,
                "blockNumber": hex(tx.block_number) if tx.block_number is not None else "0x0",
                "from": tx.from_address,
                "to": tx.to_address,
                "status": "0x1",
                "gasUsed": hex(tx.gas)
            }
        )

    def eth_gasPrice(self) -> RPCResponse:
        """Get current gas price"""
        return RPCResponse(
            id=1,
            result=hex(self.gas_price_oracle["medium"])
        )

    def eth_getBlockByNumber(self, block_number: Union[str, int]) -> RPCResponse:
        """Get block by number"""
        if isinstance(block_number, str) and block_number.startswith("0x"):
            block_number = int(block_number, 16)

        if block_number >= len(self.chain):
            return RPCResponse(
                id=1,
                error={
                    "code": RPCErrorCode.SERVER_ERROR.value,
                    "message": "Block not found"
                }
            )

        block = self.chain[block_number]
        return RPCResponse(
            id=1,
            result={
                "number": hex(block.number),
                "hash": block.hash,
                "parentHash": block.parent_hash,
                "timestamp": hex(int(block.timestamp)),
                "transactions": block.transactions,
                "gasUsed": hex(block.gas_used),
                "gasLimit": hex(block.gas_limit)
            }
        )

    def eth_chainId(self) -> RPCResponse:
        """Get chain ID"""
        return RPCResponse(
            id=1,
            result="0x1"
        )

    # ===============================
    # ADMIN METHODS
    # ===============================

    def create_account(self, address: str, balance: int) -> None:
        """Create an account with initial balance"""
        self.accounts[address] = balance
        print(f"   ✅ Account created: {address[:16]}... with {balance} ETH")

    def handle_request(self, request: Dict) -> RPCResponse:
        """Handle a JSON-RPC request"""
        method = request.get("method", "")
        params = request.get("params", [])
        request_id = request.get("id", 1)

        # Route to appropriate method
        if method == "eth_blockNumber":
            return self.eth_blockNumber()
        elif method == "eth_getBalance":
            return self.eth_getBalance(params[0] if params else "")
        elif method == "eth_getTransactionCount":
            return self.eth_getTransactionCount(params[0] if params else "")
        elif method == "eth_sendTransaction":
            return self.eth_sendTransaction(params[0] if params else {})
        elif method == "eth_getTransactionReceipt":
            return self.eth_getTransactionReceipt(params[0] if params else "")
        elif method == "eth_gasPrice":
            return self.eth_gasPrice()
        elif method == "eth_getBlockByNumber":
            return self.eth_getBlockByNumber(params[0] if params else 0)
        elif method == "eth_chainId":
            return self.eth_chainId()
        else:
            return RPCResponse(
                id=request_id,
                error={
                    "code": RPCErrorCode.METHOD_NOT_FOUND.value,
                    "message": f"Method not found: {method}"
                }
            )

    def handle_batch(self, requests: List[Dict]) -> List[RPCResponse]:
        """Handle multiple JSON-RPC requests"""
        return [self.handle_request(req) for req in requests]

def jsonrpc_demonstration():
    """Execute comprehensive JSON-RPC demonstration"""
    print("=" * 60)
    print(" 📡 JSON-RPC DEMONSTRATION")
    print("=" * 60)

    # Initialize node
    print("\n 🖥️  Initializing Node")
    print("-" * 40)
    node = JSONRPCNode("Ethereum-Node")

    # Create accounts
    print("\n 👤 Creating Accounts")
    print("-" * 40)
    node.create_account("0xAlice", 1000)
    node.create_account("0xBob", 500)
    node.create_account("0xCharlie", 0)

    # ===============================
    # SINGLE REQUESTS
    # ===============================

    print("\n 📨 Sending Single Requests")
    print("-" * 40)

    # 1. eth_blockNumber
    request = {"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []}
    response = node.handle_request(request)
    print(f"\n1. eth_blockNumber")
    print(f"   Request: {json.dumps(request)}")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 2. eth_getBalance
    request = {"jsonrpc": "2.0", "id": 2, "method": "eth_getBalance", "params": ["0xAlice"]}
    response = node.handle_request(request)
    print(f"\n2. eth_getBalance (Alice)")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 3. eth_sendTransaction
    tx = {"from": "0xAlice", "to": "0xBob", "value": 100, "gas": 21000, "gasPrice": 50}
    request = {"jsonrpc": "2.0", "id": 3, "method": "eth_sendTransaction", "params": [tx]}
    response = node.handle_request(request)
    print(f"\n3. eth_sendTransaction (Alice → Bob 100 ETH)")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 4. eth_getBalance (after transfer)
    request = {"jsonrpc": "2.0", "id": 4, "method": "eth_getBalance", "params": ["0xAlice"]}
    response = node.handle_request(request)
    print(f"\n4. eth_getBalance (Alice after)")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 5. eth_getBalance (Bob)
    request = {"jsonrpc": "2.0", "id": 5, "method": "eth_getBalance", "params": ["0xBob"]}
    response = node.handle_request(request)
    print(f"\n5. eth_getBalance (Bob)")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 6. eth_getTransactionReceipt
    tx_hash = response.result if response.result else ""
    request = {"jsonrpc": "2.0", "id": 6, "method": "eth_getTransactionReceipt", "params": [tx_hash]}
    response = node.handle_request(request)
    print(f"\n6. eth_getTransactionReceipt")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # 7. eth_gasPrice
    request = {"jsonrpc": "2.0", "id": 7, "method": "eth_gasPrice", "params": []}
    response = node.handle_request(request)
    print(f"\n7. eth_gasPrice")
    print(f"   Response: {json.dumps(response.__dict__)}")

    # ===============================
    # BATCH REQUESTS
    # ===============================

    print("\n 📨 Sending Batch Requests")
    print("-" * 40)

    batch_requests = [
        {"jsonrpc": "2.0", "id": 10, "method": "eth_blockNumber", "params": []},
        {"jsonrpc": "2.0", "id": 11, "method": "eth_getBalance", "params": ["0xAlice"]},
        {"jsonrpc": "2.0", "id": 12, "method": "eth_getBalance", "params": ["0xBob"]},
    ]

    responses = node.handle_batch(batch_requests)
    print(f"\n  Batch of {len(batch_requests)} requests")
    for i, (req, resp) in enumerate(zip(batch_requests, responses), 1):
        print(f"    {i}. {req['method']} → {resp.result if resp.result else resp.error}")

    # ===============================
    # ERROR HANDLING
    # ===============================

    print("\n ⚠️  Error Handling")
    print("-" * 40)

    # Invalid method
    request = {"jsonrpc": "2.0", "id": 20, "method": "eth_invalidMethod", "params": []}
    response = node.handle_request(request)
    print(f"\n  Invalid Method:")
    print(f"    Response: {json.dumps(response.__dict__)}")

    # Missing params
    request = {"jsonrpc": "2.0", "id": 21, "method": "eth_getBalance", "params": []}
    response = node.handle_request(request)
    print(f"\n  Missing Params:")
    print(f"    Response: {json.dumps(response.__dict__)}")

    print("\n" + "=" * 60)
    print(" JSON-RPC SUMMARY:")
    print("   ✓ JSON-RPC = Communication protocol for blockchain nodes")
    print("   ✓ Requests: {jsonrpc, method, params, id}")
    print("   ✓ Responses: {jsonrpc, id, result/error}")
    print("   ✓ Common Methods: eth_blockNumber, eth_getBalance, eth_sendTransaction")
    print("   ✓ Batch Requests: Multiple requests in one call")
    print("   ✓ Error Codes: Parse, Invalid, Method not found")
    print("   ✓ Used by: MetaMask, Web3.js, Ethers.js, dApps")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    jsonrpc_demonstration()

1.12 RPC Providers

What is an RPC Provider? An RPC provider is a service that provides access to blockchain nodes via JSON-RPC. Instead of running your own node, you can use an RPC provider to send requests to the blockchain.

Common RPC Providers:

ProviderDescriptionBest For
InfuraMost popular, easy to useGeneral use
AlchemyFeature-rich, analyticsAdvanced applications
QuickNodeFast, globalPerformance-critical apps
CloudflarePrivacy-focuseddApps

Example: When you build a dApp, you connect to an RPC provider like Infura to read data from the blockchain and send transactions.

Code Example – RPC Provider Simulation:

"""
RPC PROVIDER FRAMEWORK
=======================
Complete RPC provider implementation with load balancing and fallback support
"""

import time
import json
import hashlib
import random
from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass, field
from enum import Enum

class ProviderStatus(Enum):
    """Provider status states"""
    ONLINE = "Online"
    OFFLINE = "Offline"
    DEGRADED = "Degraded"
    RATE_LIMITED = "Rate Limited"

@dataclass
class ProviderMetrics:
    """Represents provider performance metrics"""
    total_requests: int = 0
    successful_requests: int = 0
    failed_requests: int = 0
    average_latency: float = 0.0
    last_latency: float = 0.0
    uptime_percentage: float = 99.9
    rate_limit_remaining: int = 100

@dataclass
class RPCResponse:
    """Represents an RPC response"""
    jsonrpc: str = "2.0"
    id: Optional[int] = None
    result: Any = None
    error: Optional[Dict[str, Any]] = None
    provider: Optional[str] = None
    latency: float = 0.0
    success: bool = True

@dataclass
class RPCRequest:
    """Represents an RPC request"""
    method: str
    params: List[Any]
    id: int = 0
    jsonrpc: str = "2.0"

class RPCProvider:
    """Complete RPC provider implementation with metrics"""

    def __init__(self, name: str, endpoint: str, api_key: Optional[str] = None):
        self.name = name
        self.endpoint = endpoint
        self.api_key = api_key
        self.metrics = ProviderMetrics()
        self.status = ProviderStatus.ONLINE
        self.supported_methods = [
            "eth_blockNumber",
            "eth_getBalance",
            "eth_sendTransaction",
            "eth_getTransactionReceipt",
            "eth_gasPrice",
            "eth_getBlockByNumber",
            "eth_chainId",
            "web3_clientVersion"
        ]
        self.rate_limit = 100
        self._simulated_data = self._initialize_simulated_data()
        print(f" 🌐 RPC Provider: {name} ({endpoint})")

    def _initialize_simulated_data(self) -> Dict:
        """Initialize simulated blockchain data"""
        return {
            "balances": {
                "0xAlice": 1000000000000000000,  # 1 ETH
                "0xBob": 500000000000000000,     # 0.5 ETH
                "0xCharlie": 200000000000000000,  # 0.2 ETH
                "0xVitalik": 10000000000000000000  # 10 ETH
            },
            "block_number": 18000000,
            "chain_id": 1,
            "gas_price": 30,
            "client_version": "Geth/v1.12.0/linux-amd64/go1.20"
        }

    def make_request(self, method: str, params: List[Any]) -> RPCResponse:
        """Make an RPC request through this provider"""
        start_time = time.time()
        request_id = self.metrics.total_requests + 1

        self.metrics.total_requests += 1

        # Check rate limit
        if self.metrics.total_requests > self.rate_limit:
            self.status = ProviderStatus.RATE_LIMITED
            return RPCResponse(
                id=request_id,
                error={"code": -32000, "message": "Rate limit exceeded"},
                provider=self.name,
                success=False
            )

        # Simulate network latency
        latency = random.uniform(0.05, 0.3)
        time.sleep(latency)

        # Process the request
        response = self._process_request(method, params, request_id, latency)

        if response.success:
            self.metrics.successful_requests += 1
        else:
            self.metrics.failed_requests += 1

        self.metrics.last_latency = latency
        self.metrics.average_latency = (
            (self.metrics.average_latency * (self.metrics.total_requests - 1) + latency) /
            self.metrics.total_requests
        )

        return response

    def _process_request(self, method: str, params: List[Any], 
                         request_id: int, latency: float) -> RPCResponse:
        """Process a specific RPC method"""
        if method not in self.supported_methods:
            return RPCResponse(
                id=request_id,
                error={"code": -32601, "message": f"Method not supported: {method}"},
                provider=self.name,
                latency=latency,
                success=False
            )

        if method == "eth_blockNumber":
            return RPCResponse(
                id=request_id,
                result=hex(self._simulated_data["block_number"]),
                provider=self.name,
                latency=latency
            )

        elif method == "eth_getBalance":
            address = params[0] if params else "0x0"
            balance = self._simulated_data["balances"].get(address, 0)
            return RPCResponse(
                id=request_id,
                result=hex(balance),
                provider=self.name,
                latency=latency
            )

        elif method == "eth_sendTransaction":
            tx_hash = hashlib.sha256(json.dumps(params).encode()).hexdigest()
            return RPCResponse(
                id=request_id,
                result=f"0x{tx_hash}",
                provider=self.name,
                latency=latency
            )

        elif method == "eth_getTransactionReceipt":
            return RPCResponse(
                id=request_id,
                result={
                    "status": "0x1",
                    "blockNumber": hex(self._simulated_data["block_number"]),
                    "gasUsed": "0x5208"
                },
                provider=self.name,
                latency=latency
            )

        elif method == "eth_gasPrice":
            return RPCResponse(
                id=request_id,
                result=hex(self._simulated_data["gas_price"]),
                provider=self.name,
                latency=latency
            )

        elif method == "eth_getBlockByNumber":
            return RPCResponse(
                id=request_id,
                result={
                    "number": hex(self._simulated_data["block_number"]),
                    "hash": "0x" + hashlib.sha256(b"block").hexdigest(),
                    "parentHash": "0x" + hashlib.sha256(b"parent").hexdigest()
                },
                provider=self.name,
                latency=latency
            )

        elif method == "eth_chainId":
            return RPCResponse(
                id=request_id,
                result=hex(self._simulated_data["chain_id"]),
                provider=self.name,
                latency=latency
            )

        elif method == "web3_clientVersion":
            return RPCResponse(
                id=request_id,
                result=self._simulated_data["client_version"],
                provider=self.name,
                latency=latency
            )

        return RPCResponse(
            id=request_id,
            result="0x",
            provider=self.name,
            latency=latency
        )

    def get_metrics(self) -> Dict:
        """Get provider metrics"""
        return {
            "name": self.name,
            "status": self.status.value,
            "total_requests": self.metrics.total_requests,
            "success_rate": (self.metrics.successful_requests / max(1, self.metrics.total_requests)) * 100,
            "avg_latency": self.metrics.average_latency,
            "uptime": self.metrics.uptime_percentage,
            "rate_limit_remaining": self.rate_limit - self.metrics.total_requests
        }

class RPCProviderPool:
    """Manage multiple RPC providers with load balancing and fallback"""

    def __init__(self, providers: List[RPCProvider]):
        self.providers = providers
        self.current_index = 0
        self.fallback_providers = providers[1:] if len(providers) > 1 else []
        print(f" 🔌 RPC Provider Pool initialized with {len(providers)} providers")

    def get_provider(self) -> RPCProvider:
        """Get the next provider (round-robin)"""
        provider = self.providers[self.current_index]
        self.current_index = (self.current_index + 1) % len(self.providers)
        return provider

    def make_request(self, method: str, params: List[Any]) -> RPCResponse:
        """Make a request with automatic failover"""
        # Try primary provider
        provider = self.get_provider()
        response = provider.make_request(method, params)

        # If failed, try fallback providers
        if not response.success and self.fallback_providers:
            for fallback in self.fallback_providers:
                print(f"   🔄 Falling back to {fallback.name}")
                response = fallback.make_request(method, params)
                if response.success:
                    break

        return response

    def get_all_metrics(self) -> List[Dict]:
        """Get metrics for all providers"""
        return [p.get_metrics() for p in self.providers]

def rpc_provider_demonstration():
    """Execute comprehensive RPC provider demonstration"""
    print("=" * 60)
    print(" 🌐 RPC PROVIDER DEMONSTRATION")
    print("=" * 60)

    # Create providers
    print("\n 📝 Creating RPC Providers")
    print("-" * 40)

    providers = [
        RPCProvider("Infura", "https://mainnet.infura.io/v3/API_KEY"),
        RPCProvider("Alchemy", "https://eth-mainnet.g.alchemy.com/v2/API_KEY"),
        RPCProvider("QuickNode", "https://quicknode.com/endpoint")
    ]

    # Create provider pool
    pool = RPCProviderPool(providers)

    # Make requests
    print("\n 📨 Making RPC Requests")
    print("-" * 40)

    # 1. eth_blockNumber
    print("\n1. eth_blockNumber")
    response = pool.make_request("eth_blockNumber", [])
    print(f"   Result: {response.result}")
    print(f"   Provider: {response.provider}")
    print(f"   Latency: {response.latency:.3f}s")

    # 2. eth_getBalance
    print("\n2. eth_getBalance (Alice)")
    response = pool.make_request("eth_getBalance", ["0xAlice"])
    balance = int(response.result, 16) / 1e18 if response.result else 0
    print(f"   Result: {balance} ETH")
    print(f"   Provider: {response.provider}")

    # 3. eth_getBalance (Bob)
    print("\n3. eth_getBalance (Bob)")
    response = pool.make_request("eth_getBalance", ["0xBob"])
    balance = int(response.result, 16) / 1e18 if response.result else 0
    print(f"   Result: {balance} ETH")
    print(f"   Provider: {response.provider}")

    # 4. eth_gasPrice
    print("\n4. eth_gasPrice")
    response = pool.make_request("eth_gasPrice", [])
    gas_price = int(response.result, 16) if response.result else 0
    print(f"   Result: {gas_price} Gwei")
    print(f"   Provider: {response.provider}")

    # 5. web3_clientVersion
    print("\n5. web3_clientVersion")
    response = pool.make_request("web3_clientVersion", [])
    print(f"   Result: {response.result}")
    print(f"   Provider: {response.provider}")

    # Provider metrics
    print("\n 📊 Provider Metrics")
    print("-" * 40)

    metrics = pool.get_all_metrics()
    print(f"\n {'Provider':>15} | {'Status':>15} | {'Requests':>12} | {'Success Rate':>15} | {'Avg Latency':>15}")
    print("-" * 80)

    for metric in metrics:
        print(f" {metric['name']:>15} | {metric['status']:>15} | "
              f"{metric['total_requests']:>12} | {metric['success_rate']:>14.1f}% | "
              f"{metric['avg_latency']:>14.3f}s")

    # Rate limiting demo
    print("\n ⚡ Rate Limiting Demo")
    print("-" * 40)

    provider = providers[0]
    print(f"\n  Sending 105 requests to {provider.name} (limit: {provider.rate_limit})...")
    for i in range(105):
        response = provider.make_request("eth_blockNumber", [])
        if i % 20 == 0:
            print(f"    Request {i+1}: {'✅' if response.success else '❌'}")

    # Provider status
    print(f"\n  Final Status: {provider.status.value}")

    print("\n" + "=" * 60)
    print(" RPC PROVIDER SUMMARY:")
    print("   ✓ RPC Providers = Access to blockchain nodes")
    print("   ✓ No need to run your own node")
    print("   ✓ Popular: Infura, Alchemy, QuickNode")
    print("   ✓ Features: Load balancing, fallback, rate limiting")
    print("   ✓ Metrics: Latency, success rate, uptime")
    print("   ✓ Used by: dApps, wallets, APIs")
    print("   ✓ Rate limits protect against abuse")
    print("=" * 60 + "\n")

if __name__ == "__main__":
    rpc_provider_demonstration()

2. Smart Contract Development

Build smart contracts, tokens, and decentralized applications.

Solidity Basics

Variables

Variables are containers that store data in smart contracts. In Solidity, variables must be explicitly typed, and their declaration determines where and how they are stored.

Types of Variables:

TypeDescriptionStorageExample
State VariablesStored permanently on the blockchainBlockchainuint256 public balance;
Local VariablesTemporary, exist only during function executionMemoryuint256 amount = 100;
Global VariablesProvide information about the blockchainSpecialblock.timestamp, msg.sender

Real-World Example – A Bank Contract:

In a decentralized bank, you need to store:

  • User balances (state variables)
  • Transaction amounts (local variables)
  • Block information (global variables)

Code Example – Variables:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityDataTypes
 * @dev Comprehensive demonstration of all Solidity variable types and their usage
 */
contract SolidityDataTypes {
    // =========================================================================
    // STATE VARIABLES - Permanently stored on the blockchain
    // =========================================================================

    // UNSIGNED INTEGERS (non-negative)
    uint8 public uint8Example = 255; // 0 to 255
    uint16 public uint16Example = 65535; // 0 to 65535
    uint32 public uint32Example = 4294967295; // 0 to 4294967295
    uint256 public uint256Example = 1000000000000000000; // 0 to 2^256-1 (1e18 = 1 ETH)

    // SIGNED INTEGERS (can be negative)
    int8 public int8Example = -128; // -128 to 127
    int256 public int256Example = -1000000000000000000; // -2^255 to 2^255-1

    // ADDRESS TYPES
    address public ethereumAddress = 0x742d35Cc6634C0532925a3b844Bc454e4438f44e;
    address payable public payableAddress = payable(0x742d35Cc6634C0532925a3b844Bc454e4438f44e);

    // BOOLEAN
    bool public booleanExample = true;

    // STRING
    string public stringExample = "Hello, Ethereum!";

    // BYTES (fixed and dynamic)
    bytes1 public bytes1Example = 0x01; // Single byte
    bytes32 public bytes32Example = "Fixed length bytes32";
    bytes public dynamicBytes = "Dynamic bytes array";

    // =========================================================================
    // COMPLEX TYPES
    // =========================================================================

    // ARRAYS (fixed and dynamic)
    uint256[3] public fixedArray = [10, 20, 30]; // Fixed size: 3 elements
    uint256[] public dynamicArray; // Dynamic size

    // MAPPINGS (key-value pairs)
    mapping(address => uint256) public balances;
    mapping(address => mapping(uint256 => bool)) public doubleMapping;

    // STRUCTS (custom data types)
    struct Person {
        string name;
        uint256 age;
        address wallet;
        bool isActive;
    }

    Person public personExample = Person("Alice", 25, 0x742d35Cc6634C0532925a3b844Bc454e4438f44e, true);

    // ENUMS (custom named constants)
    enum Status { PENDING, ACTIVE, COMPLETED, CANCELLED }
    Status public statusExample = Status.PENDING;

    // =========================================================================
    // CONSTANTS AND IMMUTABLES
    // =========================================================================

    // CONSTANT - compile-time constant, replaced at compile time
    uint256 public constant MAX_SUPPLY = 1000000000000000000; // 1e18 tokens

    // IMMUTABLE - set at construction, cannot be changed later
    address public immutable owner;
    uint256 public immutable deploymentTime;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        owner = msg.sender;
        deploymentTime = block.timestamp;

        // Initialize dynamic array
        dynamicArray.push(100);
        dynamicArray.push(200);

        // Initialize balances
        balances[msg.sender] = 1000;
    }

    // =========================================================================
    // RECEIVE AND FALLBACK FUNCTIONS
    // =========================================================================

    /// @notice Receive ETH directly sent to contract
    receive() external payable {
        require(msg.value > 0, "No ETH sent");
        // Automatically increases balance
    }

    /// @notice Fallback function for unrecognized function calls
    fallback() external payable {
        // Handle unknown function calls
    }

    // =========================================================================
    // VIEW AND PURE FUNCTIONS
    // =========================================================================

    /// @dev View function - reads state but doesn't modify it
    function getOwnerBalance() public view returns (uint256) {
        return balances[owner];
    }

    /// @dev Pure function - reads nothing from state
    function addPure(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    // =========================================================================
    // MAPPING OPERATIONS
    // =========================================================================

    /// @dev Update balance mapping
    function updateBalance(address user, uint256 amount) public {
        require(msg.sender == owner, "Only owner can update balances");
        balances[user] = amount;
    }

    /// @dev Get balance from mapping
    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    // =========================================================================
    // ARRAY OPERATIONS
    // =========================================================================

    /// @dev Add to dynamic array
    function addToArray(uint256 value) public {
        dynamicArray.push(value);
    }

    /// @dev Get array length
    function getArrayLength() public view returns (uint256) {
        return dynamicArray.length;
    }

    /// @dev Get array element
    function getArrayElement(uint256 index) public view returns (uint256) {
        require(index < dynamicArray.length, "Index out of bounds");
        return dynamicArray[index];
    }

    // =========================================================================
    // STRUCT OPERATIONS
    // =========================================================================

    /// @dev Update person struct
    function updatePerson(string memory newName, uint256 newAge, bool newStatus) public {
        require(msg.sender == owner, "Only owner can update");
        personExample.name = newName;
        personExample.age = newAge;
        personExample.isActive = newStatus;
    }

    /// @dev Create new struct
    function createPerson(
        string memory name,
        uint256 age,
        address wallet,
        bool isActive
    ) public returns (Person memory) {
        Person memory newPerson = Person({
            name: name,
            age: age,
            wallet: wallet,
            isActive: isActive
        });
        return newPerson;
    }

    // =========================================================================
    // ENUM OPERATIONS
    // =========================================================================

    /// @dev Update status enum
    function updateStatus(Status newStatus) public {
        require(msg.sender == owner, "Only owner can update");
        statusExample = newStatus;
    }

    /// @dev Get status as string
    function getStatusString() public view returns (string memory) {
        if (statusExample == Status.PENDING) return "PENDING";
        if (statusExample == Status.ACTIVE) return "ACTIVE";
        if (statusExample == Status.COMPLETED) return "COMPLETED";
        return "CANCELLED";
    }

    // =========================================================================
    // GLOBAL VARIABLES
    // =========================================================================

    /// @dev Get blockchain and transaction information
    function getGlobalInfo() public view returns (
        uint256 blockNumber,
        uint256 timestamp,
        address sender,
        address currentAddress,
        uint256 gasLeft
    ) {
        blockNumber = block.number;      // Current block number
        timestamp = block.timestamp;     // Current block timestamp
        sender = msg.sender;             // Caller address
        currentAddress = address(this);  // Contract address
        gasLeft = gasleft();             // Remaining gas
    }

    // =========================================================================
    // MODIFIERS
    // =========================================================================

    /// @dev Only owner modifier
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }

    /// @dev Only when contract is active
    modifier whenActive() {
        require(statusExample == Status.ACTIVE, "Contract is not active");
        _;
    }

    // =========================================================================
    // RESTRICTED FUNCTIONS
    // =========================================================================

    /// @dev Only owner can call this
    function ownerOnlyFunction() public onlyOwner {
        // Do something
    }

    /// @dev Only when active
    function activeOnlyFunction() public whenActive {
        // Do something
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event BalanceUpdated(address indexed user, uint256 newBalance);
    event StatusChanged(Status oldStatus, Status newStatus);

    /// @dev Emit events
    function emitBalanceUpdate(address user, uint256 newBalance) public onlyOwner {
        balances[user] = newBalance;
        emit BalanceUpdated(user, newBalance);
    }

    // =========================================================================
    // PAYABLE FUNCTIONS
    // =========================================================================

    /// @dev Receive ETH (payable function)
    function deposit() public payable {
        require(msg.value > 0, "Must send ETH");
        // Balances are automatically tracked via address(this).balance
    }

    /// @dev Withdraw ETH
    function withdraw(uint256 amount) public onlyOwner {
        require(address(this).balance >= amount, "Insufficient balance");
        payable(msg.sender).transfer(amount);
    }

    // =========================================================================
    // HELPER FUNCTIONS
    // =========================================================================

    /// @dev Get contract balance
    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }

    /// @dev Get all information
    function getAllInfo() public view returns (
        uint256 uintValue,
        int256 intValue,
        address addrValue,
        string memory strValue,
        Status statusValue,
        uint256 contractBalance
    ) {
        uintValue = uint256Example;
        intValue = int256Example;
        addrValue = ethereumAddress;
        strValue = stringExample;
        statusValue = statusExample;
        contractBalance = address(this).balance;
    }
}

Data Types

Solidity provides several data types for storing different kinds of information. Each type has specific characteristics and use cases.

Value Types vs Reference Types:

Type CategoryDescriptionExamples
Value TypesStore data directlyuint, int, bool, address
Reference TypesStore location of dataarrays, structs, mappings

Common Data Types:

TypeDescriptionExampleUse Case
uintUnsigned integeruint256 x = 100;Token balances
intSigned integerint256 y = -50;Negative values
boolBoolean (true/false)bool isActive = true;Status flags
addressEthereum addressaddress owner = 0x123...;User identity
stringUTF-8 textstring name = "Alice";Names, metadata
bytesByte arraybytes32 hash;Cryptographic data

Real-World Example – Token Contract:

When creating a token:

  • Use uint256 for balances (never negative)
  • Use address for users
  • Use string for token name and symbol
  • Use mapping to store balances by address

Code Example – Data Types:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title ComprehensiveDataTypes
 * @dev Complete demonstration of all Solidity data types with examples
 */
contract ComprehensiveDataTypes {
    // =========================================================================
    // VALUE TYPES - Store data directly (small and efficient)
    // =========================================================================

    // -------- UNSIGNED INTEGERS (non-negative) --------
    uint8 public uint8Val = 255;          // 0 to 255 (2^8 - 1)
    uint16 public uint16Val = 65535;      // 0 to 65535 (2^16 - 1)
    uint24 public uint24Val = 16777215;   // 0 to 16777215 (2^24 - 1)
    uint32 public uint32Val = 4294967295; // 0 to 4294967295 (2^32 - 1)
    uint256 public uint256Val = 2**256 - 1; // Max: 1.157920892e77

    // -------- SIGNED INTEGERS (can be negative) --------
    int8 public int8Val = -128;           // -128 to 127
    int16 public int16Val = -32768;       // -32768 to 32767
    int256 public int256Val = -2**255;    // -2^255 to 2^255-1

    // -------- BOOLEANS --------
    bool public boolTrue = true;
    bool public boolFalse = false;

    // -------- ADDRESSES --------
    address public userAddress = 0x742d35Cc6634C0532925a3b844Bc454e4438f44e;
    address payable public payableAddress = payable(0x742d35Cc6634C0532925a3b844Bc454e4438f44e);

    // -------- FIXED BYTES --------
    bytes1 public oneByte = 0x01;
    bytes2 public twoBytes = 0x1234;
    bytes4 public fourBytes = 0x12345678;
    bytes8 public eightBytes = 0x1234567890abcdef;
    bytes32 public thirtyTwoBytes = 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;

    // -------- DYNAMIC BYTES --------
    bytes public dynamicBytes = "Dynamic bytes content";

    // -------- STRING --------
    string public greeting = "Hello, Ethereum!";
    string public emptyString = "";

    // -------- ENUM (custom type with named constants) --------
    enum UserStatus { Pending, Active, Inactive, Blocked, Suspended }
    UserStatus public userStatus = UserStatus.Pending;

    // =========================================================================
    // REFERENCE TYPES - Store location of data (more complex)
    // =========================================================================

    // -------- STRUCTURES --------
    struct Person {
        address wallet;
        string name;
        uint256 age;
        bool isVerified;
        uint256 createdAt;
    }

    Person public personExample = Person({
        wallet: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e,
        name: "Alice Johnson",
        age: 28,
        isVerified: true,
        createdAt: block.timestamp
    });

    // -------- ARRAYS (fixed size) --------
    uint256[3] public fixedNumbers = [10, 20, 30];
    address[2] public fixedAddresses = [
        0x742d35Cc6634C0532925a3b844Bc454e4438f44e,
        0x9a8b7c6d5e4f3g2h1i0j9k8l7m6n5o4p3q2r1s0t
    ];
    string[2] public fixedStrings = ["Hello", "World"];

    // -------- ARRAYS (dynamic size) --------
    uint256[] public uintArray;
    address[] public addressArray;
    string[] public stringArray;
    Person[] public personArray;

    // -------- MAPPINGS --------
    mapping(address => uint256) public balanceMap;
    mapping(address => Person) public userMap;
    mapping(address => mapping(uint256 => bool)) public doubleMapping;
    mapping(uint256 => string) public idToName;

    // =========================================================================
    // FUNCTION TYPES
    // =========================================================================

    // Internal function type
    function internalAdd(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    // Function type variable
    function(uint256, uint256) internal returns (uint256) public funcRef;

    // Constructor
    constructor() {
        // Initialize mapping
        balanceMap[msg.sender] = 1000;

        // Initialize arrays
        uintArray.push(100);
        uintArray.push(200);
        uintArray.push(300);

        addressArray.push(msg.sender);

        // Set function reference
        funcRef = internalAdd;
    }

    // =========================================================================
    // DEMONSTRATION FUNCTIONS
    // =========================================================================

    // -------- UINT OPERATIONS --------
    function addUints(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    function subtractUints(uint256 a, uint256 b) public pure returns (uint256) {
        require(a >= b, "Underflow prevented");
        return a - b;
    }

    // -------- INT OPERATIONS --------
    function addInts(int256 a, int256 b) public pure returns (int256) {
        return a + b;
    }

    // -------- ADDRESS OPERATIONS --------
    function isAddress(address addr) public view returns (bool) {
        return addr != address(0);
    }

    function getBalance(address addr) public view returns (uint256) {
        return addr.balance;
    }

    // -------- BOOLEAN OPERATIONS --------
    function and(bool a, bool b) public pure returns (bool) {
        return a && b;
    }

    function or(bool a, bool b) public pure returns (bool) {
        return a || b;
    }

    function not(bool a) public pure returns (bool) {
        return !a;
    }

    // -------- BYTES OPERATIONS --------
    function getBytesLength(bytes memory data) public pure returns (uint256) {
        return data.length;
    }

    function concatBytes(bytes memory a, bytes memory b) public pure returns (bytes memory) {
        return abi.encodePacked(a, b);
    }

    // -------- STRING OPERATIONS --------
    function getStringLength(string memory str) public pure returns (uint256) {
        return bytes(str).length;
    }

    function concatStrings(string memory a, string memory b) public pure returns (string memory) {
        return string(abi.encodePacked(a, b));
    }

    // -------- ARRAY OPERATIONS --------
    function addToUintArray(uint256 value) public {
        uintArray.push(value);
    }

    function getUintArray() public view returns (uint256[] memory) {
        return uintArray;
    }

    function getUintArrayLength() public view returns (uint256) {
        return uintArray.length;
    }

    function getUintArrayElement(uint256 index) public view returns (uint256) {
        require(index < uintArray.length, "Index out of bounds");
        return uintArray[index];
    }

    // -------- STRUCT OPERATIONS --------
    function createPerson(
        address wallet,
        string memory name,
        uint256 age,
        bool isVerified
    ) public returns (Person memory) {
        Person memory newPerson = Person({
            wallet: wallet,
            name: name,
            age: age,
            isVerified: isVerified,
            createdAt: block.timestamp
        });
        personArray.push(newPerson);
        return newPerson;
    }

    function updatePerson(
        address wallet,
        string memory newName,
        uint256 newAge,
        bool newVerified
    ) public {
        require(personExample.wallet == msg.sender || msg.sender == personExample.wallet,
            "Not authorized to update this person");
        personExample.name = newName;
        personExample.age = newAge;
        personExample.isVerified = newVerified;
    }

    function getPerson() public view returns (
        address wallet,
        string memory name,
        uint256 age,
        bool isVerified,
        uint256 createdAt
    ) {
        return (
            personExample.wallet,
            personExample.name,
            personExample.age,
            personExample.isVerified,
            personExample.createdAt
        );
    }

    // -------- MAPPING OPERATIONS --------
    function setBalance(address user, uint256 amount) public {
        balanceMap[user] = amount;
    }

    function getBalanceMap(address user) public view returns (uint256) {
        return balanceMap[user];
    }

    function setUser(address wallet, string memory name, uint256 age, bool verified) public {
        userMap[wallet] = Person({
            wallet: wallet,
            name: name,
            age: age,
            isVerified: verified,
            createdAt: block.timestamp
        });
    }

    function getUser(address wallet) public view returns (
        address addr,
        string memory name,
        uint256 age,
        bool isVerified,
        uint256 createdAt
    ) {
        Person memory user = userMap[wallet];
        return (user.wallet, user.name, user.age, user.isVerified, user.createdAt);
    }

    // -------- ENUM OPERATIONS --------
    function setStatus(UserStatus newStatus) public {
        userStatus = newStatus;
    }

    function getStatus() public view returns (string memory) {
        if (userStatus == UserStatus.Pending) return "Pending";
        if (userStatus == UserStatus.Active) return "Active";
        if (userStatus == UserStatus.Inactive) return "Inactive";
        if (userStatus == UserStatus.Blocked) return "Blocked";
        return "Suspended";
    }

    function isActiveStatus() public view returns (bool) {
        return userStatus == UserStatus.Active;
    }

    // -------- FUNCTION TYPE DEMO --------
    function executeFunc(uint256 a, uint256 b) public view returns (uint256) {
        return funcRef(a, b);
    }

    // -------- GLOBAL VARIABLES --------
    function getGlobalInfo() public view returns (
        uint256 blockNumber,
        uint256 timestamp,
        address sender,
        address contractAddr,
        uint256 gasLeft
    ) {
        blockNumber = block.number;
        timestamp = block.timestamp;
        sender = msg.sender;
        contractAddr = address(this);
        gasLeft = gasleft();
    }

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == personExample.wallet, "Only owner can call this");
        _;
    }

    modifier whenActive() {
        require(userStatus == UserStatus.Active, "Contract is not active");
        _;
    }

    // -------- RESTRICTED FUNCTIONS --------
    function ownerOnlyFunction() public onlyOwner {
        // Only the owner can execute this
    }

    function activeOnlyFunction() public whenActive {
        // Only when active
    }

    // -------- EVENTS --------
    event PersonCreated(address indexed wallet, string name);
    event PersonUpdated(address indexed wallet, string newName);
    event BalanceChanged(address indexed user, uint256 newBalance);

    // -------- EVENT EMITTING FUNCTIONS --------
    function createPersonWithEvent(
        address wallet,
        string memory name,
        uint256 age,
        bool verified
    ) public {
        Person memory newPerson = Person({
            wallet: wallet,
            name: name,
            age: age,
            isVerified: verified,
            createdAt: block.timestamp
        });
        personArray.push(newPerson);
        emit PersonCreated(wallet, name);
    }

    function updateBalanceWithEvent(address user, uint256 newBalance) public {
        balanceMap[user] = newBalance;
        emit BalanceChanged(user, newBalance);
    }

    // -------- PAYABLE FUNCTIONS --------
    receive() external payable {
        // Handle incoming ETH
    }

    function deposit() public payable {
        require(msg.value > 0, "Must send ETH");
        balanceMap[msg.sender] += msg.value;
    }

    function withdraw(uint256 amount) public onlyOwner {
        require(address(this).balance >= amount, "Insufficient balance");
        payable(msg.sender).transfer(amount);
    }
}

Operators

Operators perform operations on variables and values. Solidity supports arithmetic, comparison, logical, and bitwise operators.

Types of Operators:

Operator TypeDescriptionExamples
ArithmeticMathematical operations+, -, *, /, %
ComparisonCompare values==, !=, >, <, >=, <=
LogicalBoolean logic&&, ||, !
BitwiseBit-level operations&, |, ^, ~, <<, >>
AssignmentAssign values=, +=, -=, *=, /=

Code Example – Operators:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityOperators
 * @dev Comprehensive demonstration of all Solidity operators with examples
 */
contract SolidityOperators {
    // =========================================================================
    // ARITHMETIC OPERATORS
    // =========================================================================

    /// @dev Demo arithmetic operators
    /// @param a First operand
    /// @param b Second operand
    /// @return sum Addition result
    /// @return diff Subtraction result
    /// @return product Multiplication result
    /// @return quotient Division result
    /// @return remainder Modulo result
    function arithmeticDemo(uint256 a, uint256 b) public pure returns (
        uint256 sum,
        uint256 diff,
        uint256 product,
        uint256 quotient,
        uint256 remainder,
        uint256 exponent
    ) {
        sum = a + b;           // Addition
        diff = a - b;          // Subtraction (requires a >= b)
        product = a * b;       // Multiplication
        quotient = a / b;      // Integer division
        remainder = a % b;     // Modulo (remainder)
        exponent = a ** b;     // Exponentiation (a^b) - Solidity 0.8.0+
    }

    /// @dev Arithmetic with overflow protection
    function safeArithmetic(uint256 a, uint256 b) public pure returns (uint256) {
        require(a >= b, "Underflow");
        require(a + b <= type(uint256).max, "Overflow");
        return a + b;
    }

    // =========================================================================
    // COMPARISON OPERATORS
    // =========================================================================

    /// @dev Demo comparison operators
    function comparisonDemo(uint256 a, uint256 b) public pure returns (
        bool isEqual,
        bool isNotEqual,
        bool isGreater,
        bool isLess,
        bool isGreaterOrEqual,
        bool isLessOrEqual
    ) {
        isEqual = a == b;             // Equal to
        isNotEqual = a != b;          // Not equal to
        isGreater = a > b;            // Greater than
        isLess = a < b;               // Less than
        isGreaterOrEqual = a >= b;    // Greater than or equal to
        isLessOrEqual = a <= b;       // Less than or equal to
    }

    /// @dev Compare addresses
    function compareAddresses(address a, address b) public pure returns (bool) {
        return a == b;
    }

    // =========================================================================
    // LOGICAL OPERATORS
    // =========================================================================

    /// @dev Demo logical operators
    function logicalDemo(bool a, bool b) public pure returns (
        bool andResult,
        bool orResult,
        bool notResult,
        bool xorResult
    ) {
        andResult = a && b;      // AND (both must be true)
        orResult = a || b;       // OR (at least one true)
        notResult = !a;          // NOT (invert)
        xorResult = (a && !b) || (!a && b); // XOR (exclusive or)
    }

    /// @dev Short-circuit evaluation
    function shortCircuitDemo(uint256 a) public pure returns (bool) {
        // Short-circuit: if a > 10 is false, second condition is not evaluated
        return a > 10 && a < 100;
    }

    // =========================================================================
    // BITWISE OPERATORS
    // =========================================================================

    /// @dev Demo bitwise operators
    function bitwiseDemo(uint256 a, uint256 b) public pure returns (
        uint256 andResult,
        uint256 orResult,
        uint256 xorResult,
        uint256 notResult,
        uint256 leftShift,
        uint256 rightShift
    ) {
        andResult = a & b;       // Bitwise AND
        orResult = a | b;        // Bitwise OR
        xorResult = a ^ b;       // Bitwise XOR (exclusive OR)
        notResult = ~a;          // Bitwise NOT (invert all bits)
        leftShift = a << 1;      // Left shift (multiply by 2)
        rightShift = a >> 1;     // Right shift (divide by 2)
    }

    /// @dev Bitwise with specific operations
    function bitwiseSpecific(
        uint8 value,
        uint8 mask,
        uint8 bitPosition
    ) public pure returns (
        uint8 setBit,
        uint8 clearBit,
        uint8 toggleBit,
        bool checkBit
    ) {
        // Set a specific bit
        setBit = value | (1 << bitPosition);

        // Clear a specific bit
        clearBit = value & ~(1 << bitPosition);

        // Toggle a specific bit
        toggleBit = value ^ (1 << bitPosition);

        // Check if a bit is set
        checkBit = (value & (1 << bitPosition)) != 0;
    }

    // =========================================================================
    // ASSIGNMENT OPERATORS
    // =========================================================================

    uint256 public value = 100;

    /// @dev Demo assignment operators
    function assignmentDemo(uint256 x) public {
        value = x;              // Simple assignment
        value += 10;            // value = value + 10
        value -= 5;             // value = value - 5
        value *= 2;             // value = value * 2
        value /= 3;             // value = value / 3
        value %= 4;             // value = value % 4
        value <<= 1;            // value = value << 1
        value >>= 1;            // value = value >> 1
        value &= 0xFF;          // value = value & 0xFF
        value |= 0xAA;          // value = value | 0xAA
    }

    /// @dev Get current value
    function getValue() public view returns (uint256) {
        return value;
    }

    // =========================================================================
    // CONDITIONAL (TERNARY) OPERATOR
    // =========================================================================

    /// @dev Ternary operator: condition ? true_value : false_value
    function ternaryDemo(uint256 a, uint256 b) public pure returns (uint256) {
        return a > b ? a : b;  // Returns the larger value
    }

    /// @dev Nested ternary
    function nestedTernary(uint256 a, uint256 b, uint256 c) public pure returns (uint256) {
        return a > b ? (a > c ? a : c) : (b > c ? b : c); // Returns max of three
    }

    // =========================================================================
    // OPERATOR PRECEDENCE EXAMPLES
    // =========================================================================

    /// @dev Complex expression with proper operator precedence
    function precedenceDemo(
        uint256 a,
        uint256 b,
        uint256 c,
        uint256 d
    ) public pure returns (uint256 result) {
        // Use parentheses for clarity
        // Precedence: * / % > + - > > < >= <= > == != > &&
        result = (a + b) * (c - d) / 2;
        return result;
    }

    /// @dev All operators combined
    function combinedOperators(
        uint256 a,
        uint256 b,
        uint256 c
    ) public pure returns (
        uint256 arithmetic,
        bool comparison,
        bool logical,
        uint256 bitwise,
        uint256 conditional
    ) {
        arithmetic = (a + b) * c / 2;
        comparison = a > b && c > 0;
        logical = (a > 0) && (b > 0) && (c > 0);
        bitwise = (a & b) | (c << 2);
        conditional = a > b ? a : b;
    }

    // =========================================================================
    // INCREMENT/DECREMENT OPERATORS
    // =========================================================================

    uint256 public counter = 0;

    /// @dev Increment and decrement (available in Solidity 0.8.0+)
    function incrementDecrementDemo() public {
        counter++;             // Post-increment (returns old value then increments)
        ++counter;             // Pre-increment (increments then returns new value)
        counter--;             // Post-decrement
        --counter;             // Pre-decrement
    }

    // =========================================================================
    // MEMBER ACCESS OPERATORS
    // =========================================================================

    struct Person {
        string name;
        uint256 age;
        address wallet;
    }

    Person public person;

    /// @dev Member access (dot operator)
    function setPerson(string memory name, uint256 age, address wallet) public {
        person.name = name;
        person.age = age;
        person.wallet = wallet;
    }

    /// @dev Mapping access
    mapping(address => uint256) public balances;

    function setBalance(address user, uint256 amount) public {
        balances[user] = amount;
    }

    // =========================================================================
    // ARRAY ACCESS OPERATOR
    // =========================================================================

    uint256[] public numbers;

    function arrayDemo() public {
        numbers.push(10);
        numbers.push(20);
        numbers.push(30);
    }

    function getArrayElement(uint256 index) public view returns (uint256) {
        require(index < numbers.length, "Index out of bounds");
        return numbers[index];
    }

    // =========================================================================
    // TYPE CASTING
    // =========================================================================

    /// @dev Type conversion
    function typeCastingDemo(uint256 a) public pure returns (uint32, int256) {
        // Explicit type conversion
        uint32 small = uint32(a);   // Convert to smaller type (will truncate if too large)
        int256 signed = int256(a);  // Convert to signed integer
        return (small, signed);
    }

    /// @dev Address to uint conversion
    function addressToUint(address addr) public pure returns (uint256) {
        return uint160(addr);
    }

    /// @dev uint to address conversion
    function uintToAddress(uint160 addr) public pure returns (address) {
        return address(addr);
    }

    // =========================================================================
    // PRACTICAL EXAMPLES
    // =========================================================================

    /// @dev Check if a number is even or odd
    function isEven(uint256 num) public pure returns (bool) {
        return num % 2 == 0;
    }

    /// @dev Check if a number is within a range
    function isInRange(uint256 num, uint256 min, uint256 max) public pure returns (bool) {
        return num >= min && num <= max;
    }

    /// @dev Compare and return the maximum
    function max(uint256 a, uint256 b) public pure returns (uint256) {
        return a > b ? a : b;
    }

    /// @dev Compare and return the minimum
    function min(uint256 a, uint256 b) public pure returns (uint256) {
        return a < b ? a : b;
    }

    /// @dev Clamp a value between min and max
    function clamp(uint256 value, uint256 minValue, uint256 maxValue) public pure returns (uint256) {
        require(minValue <= maxValue, "Invalid range");
        if (value < minValue) return minValue;
        if (value > maxValue) return maxValue;
        return value;
    }

    // =========================================================================
    // MODIFIER WITH OPERATORS
    // =========================================================================

    modifier validateInput(uint256 value) {
        require(value > 0 && value < 1000, "Value must be between 1 and 999");
        _;
    }

    /// @dev Function with validation modifier
    function validatedFunction(uint256 value) public validateInput(value) {
        // Function logic here
    }
}i

Functions

Functions are the executable units of code in Solidity. They define the behavior of the contract and can be called by users or other contracts.

Function Types:

TypeDescriptionGas CostUse Case
viewReads state, doesn’t modifyLowReading balances
pureNo state access, no modificationLowestMathematical calculations
payableCan receive ETHNormalDeposits, payments
defaultCan modify stateNormalUpdates, transfers

Function Properties:

PropertyDescriptionExample
VisibilityWho can call the functionpublic, private, internal, external
ModifiersAdd conditions to functionsonlyOwner, whenNotPaused
ReturnsWhat values are returnedreturns (uint256)
ParametersInput values(address _to, uint256 _amount)

Real-World Example – Token Transfer:

A transfer function:

  • Takes address _to and uint256 _amount as parameters
  • Has public visibility (anyone can call)
  • Modifies state (balances)
  • Returns a bool (success/failure)

Code Example – Functions:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityFunctions
 * @dev Comprehensive demonstration of all Solidity function types and properties
 */
contract SolidityFunctions {
    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    address public owner;
    uint256 public balance;
    mapping(address => uint256) public allowances;
    mapping(address => bool) public whitelist;
    uint256 public lastOperationTime;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    /// @notice Deploy the contract and set initial state
    constructor(uint256 initialBalance) {
        owner = msg.sender;
        balance = initialBalance;
        lastOperationTime = block.timestamp;
    }

    // =========================================================================
    // FUNCTION VISIBILITY
    // =========================================================================

    /// @notice PUBLIC - Anyone can call this function
    function publicFunction(uint256 x) public view returns (uint256) {
        return x * 2;
    }

    /// @notice PRIVATE - Only this contract can call this function
    function privateFunction(uint256 x) private view returns (uint256) {
        return x * 3;
    }

    /// @notice INTERNAL - This contract and derived contracts can call this
    function internalFunction(uint256 x) internal view returns (uint256) {
        return x * 4;
    }

    /// @notice EXTERNAL - Only external calls (not from this contract)
    function externalFunction(uint256 x) external view returns (uint256) {
        return x * 5;
    }

    // =========================================================================
    // FUNCTION TYPES
    // =========================================================================

    /// @notice VIEW - Reads state but doesn't modify it
    function getOwner() public view returns (address) {
        return owner;
    }

    /// @notice VIEW - Multiple return values
    function getContractInfo() public view returns (
        address owner_,
        uint256 balance_,
        uint256 timestamp_
    ) {
        owner_ = owner;
        balance_ = balance;
        timestamp_ = lastOperationTime;
    }

    /// @notice PURE - No state access, pure computation only
    function addNumbers(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    /// @notice PURE - Complex computation
    function fibonacci(uint256 n) public pure returns (uint256) {
        if (n <= 1) return n;
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

    /// @notice PAYABLE - Can receive ETH
    function receivePayment() public payable {
        require(msg.value > 0, "Must send ETH");
        balance += msg.value;
        lastOperationTime = block.timestamp;
    }

    /// @notice DEFAULT - Can modify state
    function setBalance(uint256 newBalance) public {
        require(msg.sender == owner, "Only owner can set balance");
        balance = newBalance;
        lastOperationTime = block.timestamp;
    }

    // =========================================================================
    // FUNCTION MODIFIERS
    // =========================================================================

    /// @notice Only owner modifier
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }

    /// @notice Non-zero value modifier
    modifier nonZero(uint256 value) {
        require(value > 0, "Value must be greater than zero");
        _;
    }

    /// @notice Whitelist check modifier
    modifier whitelisted() {
        require(whitelist[msg.sender], "Address not whitelisted");
        _;
    }

    /// @notice Time lock modifier (only after specified time)
    modifier afterTime(uint256 timestamp) {
        require(block.timestamp >= timestamp, "Time lock not expired");
        _;
    }

    /// @notice Multiple modifiers
    modifier onlyOwnerNonZero(uint256 amount) {
        require(msg.sender == owner, "Only owner");
        require(amount > 0, "Amount must be positive");
        _;
    }

    // =========================================================================
    // FUNCTIONS WITH MODIFIERS
    // =========================================================================

    /// @notice Only owner can call this
    function ownerOnlyFunction() public onlyOwner {
        balance = 9999;
        lastOperationTime = block.timestamp;
    }

    /// @notice Amount must be > 0
    function transferWithModifier(uint256 amount) public nonZero(amount) {
        require(balance >= amount, "Insufficient balance");
        balance -= amount;
        lastOperationTime = block.timestamp;
    }

    /// @notice Multiple conditions
    function secureTransfer(uint256 amount) public onlyOwnerNonZero(amount) {
        require(balance >= amount, "Insufficient balance");
        balance -= amount;
        lastOperationTime = block.timestamp;
    }

    /// @notice Whitelist protection
    function whitelistOnlyFunction() public whitelisted {
        // Only whitelisted addresses can execute
    }

    // =========================================================================
    // MULTIPLE RETURNS
    // =========================================================================

    /// @notice Function with named returns
    function getMultipleValues() public view returns (
        address ownerAddress,
        uint256 currentBalance,
        uint256 lastTime,
        uint256 currentBlock
    ) {
        ownerAddress = owner;
        currentBalance = balance;
        lastTime = lastOperationTime;
        currentBlock = block.number;
    }

    /// @notice Destructuring returns
    function getValuesDestructured() public view returns (address, uint256) {
        return (owner, balance);
    }

    // =========================================================================
    // FUNCTION OVERLOADING
    // =========================================================================

    /// @notice Process single value
    function process(uint256 x) public pure returns (uint256) {
        return x * 2;
    }

    /// @notice Process two values
    function process(uint256 x, uint256 y) public pure returns (uint256) {
        return x + y;
    }

    /// @notice Process three values
    function process(uint256 x, uint256 y, uint256 z) public pure returns (uint256) {
        return (x + y) * z;
    }

    /// @notice Process with different parameter types
    function process(uint256 x, string memory label) public pure returns (string memory) {
        return string(abi.encodePacked(label, ":", x));
    }

    // =========================================================================
    // RECEIVE AND FALLBACK FUNCTIONS
    // =========================================================================

    /// @notice Receive ETH directly (no data)
    receive() external payable {
        require(msg.value > 0, "Must send ETH");
        balance += msg.value;
        lastOperationTime = block.timestamp;
    }

    /// @notice Fallback for unrecognized function calls
    fallback() external payable {
        // Handle unknown function calls
        if (msg.value > 0) {
            balance += msg.value;
            lastOperationTime = block.timestamp;
        }
    }

    // =========================================================================
    // FUNCTION LIBRARY
    // =========================================================================

    /// @notice Library-like function
    function sqrt(uint256 x) public pure returns (uint256) {
        if (x == 0) return 0;
        uint256 result = x;
        uint256 temp = x;
        while (temp > 0) {
            result = (result + temp) / 2;
            temp = x / result;
        }
        return result;
    }

    // =========================================================================
    // VIEW VS PURE COMPARISON
    // =========================================================================

    /// @notice View: reads state
    function viewFunction() public view returns (uint256) {
        return balance;
    }

    /// @notice Pure: no state access
    function pureFunction(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    /// @notice Cannot call pure from view (but can call view from pure)
    function viewUsingPure(uint256 x) public view returns (uint256) {
        return pureFunction(x, 10) + balance;
    }

    // =========================================================================
    // PRIVATE FUNCTIONS
    // =========================================================================

    /// @notice Private helper function
    function _calculateFee(uint256 amount) private pure returns (uint256) {
        return amount * 2 / 100; // 2% fee
    }

    /// @notice Internal helper function (accessible to derived contracts)
    function _calculateDiscount(uint256 amount) internal pure returns (uint256) {
        return amount * 10 / 100; // 10% discount
    }

    // =========================================================================
    // PUBLIC FUNCTIONS WITH INTERNAL CALLS
    // =========================================================================

    function transferWithFee(address to, uint256 amount) public nonZero(amount) {
        require(balance >= amount, "Insufficient balance");
        uint256 fee = _calculateFee(amount);
        balance -= amount + fee;
        // Transfer logic...
        lastOperationTime = block.timestamp;
    }

    // =========================================================================
    // EXTERNAL FUNCTION CALLS
    // =========================================================================

    /// @notice Called externally
    function externalOnly(uint256 x) external pure returns (uint256) {
        return x * 2;
    }

    /// @notice This function calls an external function (not from this contract)
    function callExternal(address contractAddr) external {
        // This would call an external contract
        // (bool success, bytes memory data) = contractAddr.call(abi.encodeWithSignature("functionName()"));
        // require(success, "External call failed");
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event BalanceUpdated(address indexed user, uint256 newBalance);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    /// @notice Function that emits events
    function updateBalance(uint256 newBalance) public onlyOwner {
        balance = newBalance;
        emit BalanceUpdated(msg.sender, newBalance);
        lastOperationTime = block.timestamp;
    }

    function changeOwner(address newOwner) public onlyOwner {
        address oldOwner = owner;
        owner = newOwner;
        emit OwnerChanged(oldOwner, newOwner);
    }

    // =========================================================================
    // FUNCTION SELECTORS
    // =========================================================================

    /// @notice Get function selector
    function getSelector(string memory functionSignature) public pure returns (bytes4) {
        return bytes4(keccak256(bytes(functionSignature)));
    }
}

Constructors

The constructor is a special function that runs only once when the contract is deployed. It’s used to initialize state variables and set up the contract.

Constructor Characteristics:

CharacteristicDescription
Runs OnceOnly at deployment time
Cannot be CalledOnly the deployer can trigger it
Initializes StateSets initial values for state variables
Can Accept ParametersFor customizable deployment

Common Uses:

  1. Setting Owner: The deployer becomes the owner
  2. Initial Token Supply: Minting initial tokens
  3. Setting Parameters: Configuration values

Code Example – Constructors:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityConstructors
 * @dev Comprehensive demonstration of constructor patterns in Solidity
 */
contract SolidityConstructors {
    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    address public owner;
    string public name;
    string public symbol;
    uint256 public totalSupply;
    bool public isActive;
    mapping(address => uint256) public balances;
    mapping(address => bool) public isWhitelisted;
    uint256 public deploymentBlock;

    // =========================================================================
    // CONSTANTS AND IMMUTABLES
    // =========================================================================

    uint256 public constant DECIMALS = 18;
    address public immutable deployer;
    uint256 public immutable deploymentTimestamp;

    // =========================================================================
    // CONSTRUCTOR PATTERN 1: Simple Constructor
    // =========================================================================

    /// @notice Simple constructor with minimal setup
    constructor() {
        owner = msg.sender;
        deployer = msg.sender;
        deploymentTimestamp = block.timestamp;
        deploymentBlock = block.number;
        isActive = true;
        balances[msg.sender] = 1000 * 10**DECIMALS;
    }

    // =========================================================================
    // CONSTRUCTOR PATTERN 2: Parameterized Constructor
    // =========================================================================

    /// @notice Constructor with initialization parameters
    /// @param _name Token name
    /// @param _symbol Token symbol
    /// @param _initialSupply Initial token supply
    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _initialSupply
    ) {
        require(bytes(_name).length > 0, "Name cannot be empty");
        require(bytes(_symbol).length > 0, "Symbol cannot be empty");
        require(_initialSupply > 0, "Initial supply must be > 0");

        owner = msg.sender;
        deployer = msg.sender;
        deploymentTimestamp = block.timestamp;
        deploymentBlock = block.number;
        name = _name;
        symbol = _symbol;
        totalSupply = _initialSupply * 10**DECIMALS;
        balances[msg.sender] = totalSupply;
        isActive = true;
    }

    // =========================================================================
    // CONSTRUCTOR PATTERN 3: With Input Validation
    // =========================================================================

    /// @notice Constructor with comprehensive validation
    /// @param _owner Contract owner address
    /// @param _name Token name
    /// @param _symbol Token symbol
    /// @param _initialSupply Initial supply
    /// @param _active Initial active state
    constructor(
        address _owner,
        string memory _name,
        string memory _symbol,
        uint256 _initialSupply,
        bool _active
    ) {
        require(_owner != address(0), "Owner cannot be zero address");
        require(bytes(_name).length > 0, "Name cannot be empty");
        require(bytes(_symbol).length > 0, "Symbol cannot be empty");
        require(_initialSupply > 0, "Initial supply must be positive");

        owner = _owner;
        deployer = msg.sender;
        deploymentTimestamp = block.timestamp;
        deploymentBlock = block.number;
        name = _name;
        symbol = _symbol;
        totalSupply = _initialSupply * 10**DECIMALS;
        balances[_owner] = totalSupply;
        isActive = _active;
    }

    // =========================================================================
    // CONSTRUCTOR PATTERN 4: Multi-Constructor (Overloading Not Allowed)
    // =========================================================================

    // Solidity does not support constructor overloading.
    // Only one constructor can be defined per contract.

    // =========================================================================
    // CONSTRUCTOR PATTERN 5: With Modifiers
    // =========================================================================

    // Modifiers can be applied to functions but not to constructors.
    // Validation must be done directly in the constructor body.

    // =========================================================================
    // CONSTRUCTOR PATTERN 6: Initializing Arrays and Mappings
    // =========================================================================

    /// @notice Constructor with array and mapping initialization
    constructor(address[] memory initialWhitelist) {
        owner = msg.sender;
        deployer = msg.sender;
        deploymentTimestamp = block.timestamp;
        deploymentBlock = block.number;
        isActive = true;

        // Initialize whitelist
        for (uint256 i = 0; i < initialWhitelist.length; i++) {
            require(initialWhitelist[i] != address(0), "Invalid address");
            isWhitelisted[initialWhitelist[i]] = true;
        }

        // Set initial balance
        balances[msg.sender] = 1000 * 10**DECIMALS;
    }

    // =========================================================================
    // CONSTRUCTOR PATTERN 7: Only Owner Setup
    // =========================================================================

    /// @notice Constructor that only allows owner to set initial values
    constructor(
        uint256 _initialSupply,
        address[] memory _beneficiaries,
        uint256[] memory _amounts
    ) {
        require(_beneficiaries.length == _amounts.length, "Arrays length mismatch");
        require(_initialSupply > 0, "Supply must be positive");

        owner = msg.sender;
        deployer = msg.sender;
        deploymentTimestamp = block.timestamp;
        deploymentBlock = block.number;
        totalSupply = _initialSupply * 10**DECIMALS;
        isActive = true;

        // Distribute initial tokens
        uint256 totalDistributed = 0;
        for (uint256 i = 0; i < _beneficiaries.length; i++) {
            require(_beneficiaries[i] != address(0), "Invalid beneficiary");
            require(_amounts[i] > 0, "Amount must be positive");
            balances[_beneficiaries[i]] = _amounts[i] * 10**DECIMALS;
            totalDistributed += _amounts[i] * 10**DECIMALS;
        }

        require(totalDistributed <= totalSupply, "Total exceeds supply");
        // Remaining supply stays with owner
        balances[owner] += totalSupply - totalDistributed;
    }

    // =========================================================================
    // FUNCTIONS
    // =========================================================================

    /// @notice Get contract deployment info
    function getDeploymentInfo() public view returns (
        address deployer_,
        uint256 timestamp_,
        uint256 block_,
        uint256 totalSupply_
    ) {
        deployer_ = deployer;
        timestamp_ = deploymentTimestamp;
        block_ = deploymentBlock;
        totalSupply_ = totalSupply;
    }

    /// @notice Get owner info
    function getOwnerInfo() public view returns (address, uint256) {
        return (owner, balances[owner]);
    }

    /// @notice Transfer function (simplified)
    function transfer(address to, uint256 amount) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(amount > 0, "Amount must be positive");
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(isActive, "Contract is paused");

        balances[msg.sender] -= amount;
        balances[to] += amount;
        return true;
    }

    /// @notice Mint function (only owner)
    function mint(address to, uint256 amount) public {
        require(msg.sender == owner, "Only owner can mint");
        require(amount > 0, "Amount must be positive");
        totalSupply += amount * 10**DECIMALS;
        balances[to] += amount * 10**DECIMALS;
    }

    /// @notice Pause function
    function pause() public {
        require(msg.sender == owner, "Only owner can pause");
        isActive = false;
    }

    /// @notice Unpause function
    function unpause() public {
        require(msg.sender == owner, "Only owner can unpause");
        isActive = true;
    }
}

// =========================================================================
// INHERITANCE WITH CONSTRUCTORS
// =========================================================================

/**
 * @title ChildContract
 * @dev Demonstrates constructor inheritance
 */
contract ChildContract is SolidityConstructors {
    // Additional state variables
    string public version;
    address public admin;

    /// @notice Constructor with inherited parameters
    /// @param _name Token name
    /// @param _symbol Token symbol
    /// @param _initialSupply Initial supply
    /// @param _version Contract version
    /// @param _admin Admin address
    constructor(
        string memory _name,
        string memory _symbol,
        uint256 _initialSupply,
        string memory _version,
        address _admin
    )
        SolidityConstructors(_name, _symbol, _initialSupply)
    {
        require(_admin != address(0), "Admin cannot be zero");
        version = _version;
        admin = _admin;
    }

    /// @notice Admin-only function
    function adminFunction() public view returns (address) {
        return admin;
    }

    /// @notice Override version getter
    function getVersion() public view returns (string memory) {
        return version;
    }
}

// =========================================================================
// ABSTRACT CONTRACT WITH CONSTRUCTOR
// =========================================================================

/**
 * @title AbstractBase
 * @dev Abstract contract with constructor
 */
abstract contract AbstractBase {
    address public baseOwner;
    uint256 public baseValue;

    constructor(address _owner, uint256 _value) {
        require(_owner != address(0), "Invalid owner");
        baseOwner = _owner;
        baseValue = _value;
    }

    function baseFunction() public view virtual returns (uint256) {
        return baseValue;
    }
}

/**
 * @title ConcreteContract
 * @dev Implementation of abstract contract
 */
contract ConcreteContract is AbstractBase {
    constructor(address _owner, uint256 _value)
        AbstractBase(_owner, _value)
    {
        // Additional initialization
    }

    function baseFunction() public view override returns (uint256) {
        return baseValue * 2;
    }
}

Visibility

Visibility determines who can access and call functions and variables in a Solidity contract. It’s a critical security feature.

Visibility Levels:

VisibilityAccessDescriptionUse Case
publicAnyoneAccessible from anywhereUser-facing functions
privateOnly this contractNot accessible externallyInternal helpers
internalThis contract + childrenNot accessible externallyShared functions
externalOnly externallyNot accessible internallyInterface functions

Real-World Example – Bank Contract:

  • deposit() – public (anyone can deposit)
  • _updateBalance() – private (internal logic)
  • _onlyOwner() – internal (inherited contracts need it)
  • withdraw() – external (users call from outside)

Code Example – Visibility:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityVisibility
 * @dev Comprehensive demonstration of all visibility levels in Solidity
 */
contract SolidityVisibilityBase {
    // =========================================================================
    // VARIABLE VISIBILITY
    // =========================================================================

    // -------- PUBLIC --------
    /// @notice PUBLIC - Anyone can read this variable
    /// @dev Solidity automatically creates a getter function
    uint256 public publicVariable = 100;
    string public publicString = "Hello Public";
    address public publicAddress = 0x742d35Cc6634C0532925a3b844Bc454e4438f44e;

    // -------- PRIVATE --------
    /// @notice PRIVATE - Only this contract can read/write this variable
    /// @dev Not accessible by derived contracts or external callers
    uint256 private privateVariable = 200;
    mapping(address => uint256) private privateMapping;
    string private privateString = "Secret Data";

    // -------- INTERNAL --------
    /// @notice INTERNAL - This contract and derived contracts can read/write
    /// @dev Not accessible by external callers
    uint256 internal internalVariable = 300;
    bool internal internalFlag = true;
    bytes internal internalData = "Internal Data";

    // =========================================================================
    // FUNCTION VISIBILITY
    // =========================================================================

    // -------- PUBLIC --------
    /// @notice PUBLIC - Anyone can call this function
    /// @dev Read/write access to all variables
    function publicFunction(uint256 newValue) public returns (uint256) {
        publicVariable = newValue;
        return publicVariable + privateVariable + internalVariable;
    }

    /// @notice PUBLIC view function
    function publicViewFunction() public view returns (
        uint256 publicVar,
        uint256 privateVar,
        uint256 internalVar
    ) {
        publicVar = publicVariable;
        privateVar = privateVariable;
        internalVar = internalVariable;
    }

    // -------- PRIVATE --------
    /// @notice PRIVATE - Only this contract can call this function
    /// @dev Not accessible by derived contracts or external callers
    function privateFunction() private view returns (uint256) {
        return privateVariable * 2;
    }

    /// @notice PRIVATE helper function
    function privateHelper(uint256 a, uint256 b) private pure returns (uint256) {
        return a + b;
    }

    // -------- INTERNAL --------
    /// @notice INTERNAL - This contract and derived contracts can call this
    /// @dev Not accessible by external callers
    function internalFunction() internal view returns (uint256) {
        return internalVariable * 2;
    }

    /// @notice INTERNAL helper function
    function internalHelper(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    // -------- EXTERNAL --------
    /// @notice EXTERNAL - Only external callers (not from this contract)
    /// @dev Cannot be called from within this contract
    function externalFunction(uint256 x) external view returns (uint256) {
        return publicVariable + x;
    }

    /// @notice EXTERNAL pure function
    function externalPure(uint256 a, uint256 b) external pure returns (uint256) {
        return a + b;
    }

    // =========================================================================
    // GETTER FUNCTIONS
    // =========================================================================

    /// @notice Public variable automatically has a getter
    /// @dev You can call publicVariable() to get the value

    /// @notice Manual getter for private variable (controlled access)
    function getPrivateValue() public view returns (uint256) {
        // Only owner can access private value
        require(msg.sender == publicAddress, "Not authorized");
        return privateVariable;
    }

    /// @notice Get private mapping value (controlled access)
    function getPrivateMapping(address user) public view returns (uint256) {
        require(msg.sender == publicAddress || msg.sender == user, "Not authorized");
        return privateMapping[user];
    }

    // =========================================================================
    // INTERNAL HELPER FUNCTIONS
    // =========================================================================

    /// @notice Internal validation function
    function _validateAddress(address addr) internal pure returns (bool) {
        return addr != address(0);
    }

    /// @notice Internal calculation function
    function _calculateFee(uint256 amount) internal pure returns (uint256) {
        return amount * 2 / 100; // 2% fee
    }

    // =========================================================================
    // PRIVATE HELPER FUNCTIONS
    // =========================================================================

    /// @notice Private validation function
    function _isOwner() private view returns (bool) {
        return msg.sender == publicAddress;
    }

    /// @notice Private calculation function
    function _discount(uint256 amount) private pure returns (uint256) {
        return amount * 10 / 100; // 10% discount
    }

    // =========================================================================
    // PUBLIC FUNCTIONS USING INTERNAL/PRIVATE HELPERS
    // =========================================================================

    /// @notice Public function using internal helper
    function transferWithFee(address to, uint256 amount) public returns (bool) {
        require(_validateAddress(to), "Invalid address");
        uint256 fee = _calculateFee(amount);
        // Transfer logic...
        return true;
    }

    /// @notice Public function using private helper
    function ownerFunction() public view returns (bool) {
        return _isOwner();
    }

    // =========================================================================
    // SETTER FUNCTIONS
    // =========================================================================

    /// @notice Set private variable (controlled access)
    function setPrivateValue(uint256 newValue) public {
        require(msg.sender == publicAddress, "Only owner can set");
        privateVariable = newValue;
    }

    /// @notice Set private mapping (controlled access)
    function setPrivateMapping(address user, uint256 value) public {
        require(msg.sender == publicAddress, "Only owner can set");
        privateMapping[user] = value;
    }

    /// @notice Set internal variable (accessible to derived contracts)
    function setInternalValue(uint256 newValue) internal {
        internalVariable = newValue;
    }

    // =========================================================================
    // VISIBILITY COMPARISON FUNCTIONS
    // =========================================================================

    /// @notice Demonstrate visibility differences
    function visibilityDemo() public view returns (
        bool canReadPublic,
        bool canReadPrivate,
        bool canReadInternal,
        bool canCallPrivate,
        bool canCallInternal
    ) {
        canReadPublic = true;
        // canReadPrivate = false; // Cannot access private from public
        canReadInternal = true;
        // canCallPrivate = false; // Cannot call private from public
        canCallInternal = true;
    }
}

// =========================================================================
// CHILD CONTRACT DEMONSTRATING INHERITANCE
// =========================================================================

/**
 * @title VisibilityChild
 * @dev Inherits from SolidityVisibilityBase to demonstrate inherited visibility
 */
contract VisibilityChild is SolidityVisibilityBase {
    // =========================================================================
    // ACCESSING INHERITED VARIABLES
    // =========================================================================

    /// @notice Check access to inherited variables
    function checkInheritedAccess() public view returns (
        bool canAccessPublic,
        bool canAccessPrivate,
        bool canAccessInternal
    ) {
        // Public: Accessible
        canAccessPublic = true;
        uint256 pub = publicVariable;

        // Private: NOT accessible from derived contract
        // uint256 priv = privateVariable; // COMPILER ERROR

        // Internal: Accessible
        canAccessInternal = true;
        uint256 inter = internalVariable;

        return (canAccessPublic, false, canAccessInternal);
    }

    /// @notice Access inherited functions
    function callInheritedFunctions() public view returns (uint256) {
        // Can call public and internal functions
        uint256 result = publicViewFunction().internalVar;
        result += internalFunction();
        // Cannot call private functions: privateFunction()
        return result;
    }

    /// @notice Override internal function
    function internalFunction() internal view override returns (uint256) {
        return internalVariable * 3; // Custom behavior
    }
}

// =========================================================================
// ADVANCED VISIBILITY PATTERNS
// =========================================================================

/**
 * @title VisibilityAdvanced
 * @dev Advanced visibility patterns and best practices
 */
contract VisibilityAdvanced {
    // =========================================================================
    // PATTERN 1: PUBLIC WITH GETTER
    // =========================================================================

    /// @notice Public variable with automatic getter
    uint256 public data = 100;

    // =========================================================================
    // PATTERN 2: PRIVATE FOR INTERNAL LOGIC
    // =========================================================================

    uint256 private secret = 12345;

    function getSecret() private view returns (uint256) {
        return secret;
    }

    function useSecret() internal view returns (uint256) {
        return getSecret(); // Can call private from inside
    }

    // =========================================================================
    // PATTERN 3: EXTERNAL FOR USER INTERFACE
    // =========================================================================

    /// @notice External functions for users (gas efficient)
    function userAction(uint256 x) external returns (uint256) {
        // External functions can only be called externally
        // They are more gas efficient for parameter handling
        return x * 2;
    }

    /// @notice External pure function
    function calculate(uint256 a, uint256 b) external pure returns (uint256) {
        return a + b;
    }

    // =========================================================================
    // PATTERN 4: INTERNAL FOR SHARED LOGIC
    // =========================================================================

    /// @notice Internal function for reuse
    function _sharedLogic(uint256 x) internal pure returns (uint256) {
        return x * x;
    }

    // =========================================================================
    // PATTERN 5: PRIVATE FOR SENSITIVE OPERATIONS
    // =========================================================================

    /// @notice Private function for sensitive operations
    function _sensitiveOperation() private view {
        // Only called from within contract
        require(msg.sender == address(this), "Internal call only");
    }

    // =========================================================================
    // BEST PRACTICES SUMMARY
    // =========================================================================

    /// @notice Visibility best practices
    function visibilityBestPractices() public pure returns (string memory) {
        return "
            PUBLIC: User-facing functions
            PRIVATE: Internal logic, sensitive operations
            INTERNAL: Shared logic for inheritance
            EXTERNAL: Interface functions for external contracts
        ";
    }
}

Control Flow

Control flow structures determine the order in which program statements are executed. They enable conditional execution and iteration.

Control Flow Structures:

StructureDescriptionUse Case
if/elseConditional executionValidation, branching
forFixed iterationProcessing arrays
whileConditional iterationUnknown iteration count
do-whileAt least once iterationGuaranteed execution
requireInput validationSecurity checks
revertUndo transactionError handling
assertInternal invariantBug detection

Real-World Example – Transfer Function:

  • if to check balance
  • require to validate inputs
  • for to process multiple recipients

Code Example – Control Flow:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityControlFlow
 * @dev Comprehensive demonstration of all control flow structures in Solidity
 */
contract SolidityControlFlow {
    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    mapping(address => uint256) public balances;
    address[] public users;
    bool public paused;
    uint256 public totalSupply;
    uint256 public constant MIN_TRANSFER = 100;

    // =========================================================================
    // IF / ELSE
    // =========================================================================

    /// @notice Transfer funds with if/else validation
    /// @param to Recipient address
    /// @param amount Amount to transfer
    function transfer(address to, uint256 amount) public returns (bool) {
        // IF with validation
        if (paused) {
            revert("Contract is paused");
        }

        if (balances[msg.sender] < amount) {
            return false; // Insufficient balance
        }

        // ELSE IF for validation
        if (to == address(0)) {
            revert("Cannot send to zero address");
        } else if (amount == 0) {
            revert("Amount must be > 0");
        } else if (amount < MIN_TRANSFER) {
            revert("Amount below minimum");
        }

        // Nested IF
        if (amount > 1000) {
            // Large transfer: require additional validation
            if (block.timestamp > 0) {
                // Check logic
            }
        }

        // ELSE (default case)
        balances[msg.sender] -= amount;
        balances[to] += amount;
        return true;
    }

    /// @notice IF/ELSE with return values
    function getStatus(address user) public view returns (string memory) {
        if (balances[user] == 0) {
            return "No balance";
        } else if (balances[user] < 100) {
            return "Low balance";
        } else if (balances[user] < 1000) {
            return "Medium balance";
        } else {
            return "High balance";
        }
    }

    // =========================================================================
    // FOR LOOPS
    // =========================================================================

    /// @notice Batch transfer using FOR loop
    function batchTransfer(
        address[] memory recipients,
        uint256[] memory amounts
    ) public returns (bool) {
        require(recipients.length == amounts.length, "Arrays must match");
        require(!paused, "Contract is paused");

        // FOR loop with validation
        for (uint256 i = 0; i < recipients.length; i++) {
            require(recipients[i] != address(0), "Invalid recipient");
            require(balances[msg.sender] >= amounts[i], "Insufficient balance");

            balances[msg.sender] -= amounts[i];
            balances[recipients[i]] += amounts[i];
        }
        return true;
    }

    /// @notice Get total supply using FOR loop
    function getTotalSupply() public view returns (uint256) {
        uint256 total = 0;

        // FOR loop through all users
        for (uint256 i = 0; i < users.length; i++) {
            total += balances[users[i]];
        }
        return total;
    }

    /// @notice Find user with highest balance
    function getHighestBalanceUser() public view returns (address, uint256) {
        require(users.length > 0, "No users");

        address highestUser = users[0];
        uint256 highestBalance = balances[highestUser];

        for (uint256 i = 1; i < users.length; i++) {
            if (balances[users[i]] > highestBalance) {
                highestBalance = balances[users[i]];
                highestUser = users[i];
            }
        }
        return (highestUser, highestBalance);
    }

    /// @notice FOR loop with break
    function findUser(address user) public view returns (bool) {
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == user) {
                return true; // Break when found
            }
        }
        return false;
    }

    /// @notice FOR loop with continue
    function getActiveUsers() public view returns (address[] memory) {
        uint256 activeCount = 0;

        // First pass: count active users
        for (uint256 i = 0; i < users.length; i++) {
            if (balances[users[i]] > 0) {
                activeCount++;
            }
        }

        // Second pass: collect active users
        address[] memory active = new address[](activeCount);
        uint256 index = 0;
        for (uint256 i = 0; i < users.length; i++) {
            if (balances[users[i]] == 0) {
                continue; // Skip inactive users
            }
            active[index] = users[i];
            index++;
        }
        return active;
    }

    // =========================================================================
    // WHILE LOOPS
    // =========================================================================

    /// @notice Sum first N numbers using WHILE loop
    function sumFirstN(uint256 n) public pure returns (uint256) {
        uint256 sum = 0;
        uint256 i = 0;

        while (i < n) {
            sum += i;
            i++;
        }
        return sum;
    }

    /// @notice Factorial using WHILE loop
    function factorial(uint256 n) public pure returns (uint256) {
        require(n <= 20, "Input too large");
        uint256 result = 1;
        uint256 i = 1;

        while (i <= n) {
            result *= i;
            i++;
        }
        return result;
    }

    /// @notice Exponential growth (compound interest)
    function compound(uint256 principal, uint256 rate, uint256 periods) public pure returns (uint256) {
        uint256 result = principal;
        uint256 i = 0;

        while (i < periods) {
            result = result * (100 + rate) / 100;
            i++;
        }
        return result;
    }

    // =========================================================================
    // REQUIRE (Input Validation)
    // =========================================================================

    /// @notice Deposit with REQUIRE validation
    function deposit() public payable {
        require(msg.value > 0, "Amount must be > 0");
        require(!paused, "Contract is paused");
        require(msg.value >= MIN_TRANSFER, "Amount below minimum");

        balances[msg.sender] += msg.value;
        totalSupply += msg.value;

        // Add user if new
        bool exists = false;
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == msg.sender) {
                exists = true;
                break;
            }
        }
        if (!exists) {
            users.push(msg.sender);
        }
    }

    /// @notice Withdraw with REQUIRE validation
    function withdraw(uint256 amount) public {
        require(amount > 0, "Amount must be > 0");
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(!paused, "Contract is paused");

        balances[msg.sender] -= amount;
        totalSupply -= amount;
        payable(msg.sender).transfer(amount);
    }

    // =========================================================================
    // REVERT (Error Handling)
    // =========================================================================

    /// @notice Risky operation with REVERT
    function riskyOperation(uint256 x) public pure returns (uint256) {
        if (x == 0) {
            revert("Cannot process zero value");
        }
        if (x == 1) {
            revert("Cannot process one value");
        }
        return 100 / x;
    }

    /// @notice Complex validation with REVERT
    function complexValidation(uint256 value, address recipient) public view {
        if (value == 0) {
            revert("Value cannot be zero");
        }
        if (recipient == address(0)) {
            revert("Recipient cannot be zero address");
        }
        if (balances[msg.sender] < value) {
            revert("Insufficient balance");
        }
        if (paused) {
            revert("Contract is paused");
        }
    }

    // =========================================================================
    // ASSERT (Internal Invariants)
    // =========================================================================

    /// @notice Check invariants using ASSERT
    function checkInvariants() public view {
        // Total supply should be sum of all balances
        uint256 calculatedSupply = 0;
        for (uint256 i = 0; i < users.length; i++) {
            calculatedSupply += balances[users[i]];
        }
        assert(calculatedSupply == totalSupply);

        // Non-negative balances
        assert(balances[address(this)] >= 0);

        // Owner has sufficient balance
        assert(balances[msg.sender] >= 0);

        // Additional invariants
        assert(users.length <= 1000);
    }

    /// @notice Assert in function
    function invariantCheck(uint256 a, uint256 b) public pure returns (uint256) {
        // Assert for debugging
        assert(a + b > a);
        return a + b;
    }

    // =========================================================================
    // CONTROL FLOW WITH MODIFIERS
    // =========================================================================

    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }

    modifier onlyExistingUser() {
        bool exists = false;
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == msg.sender) {
                exists = true;
                break;
            }
        }
        require(exists, "User not found");
        _;
    }

    /// @notice Function with modifiers
    function safeTransfer(address to, uint256 amount)
        public
        whenNotPaused
        onlyExistingUser
        returns (bool)
    {
        return transfer(to, amount);
    }
}

// =========================================================================
// CUSTOM ERRORS
// =========================================================================

/**
 * @title CustomErrors
 * @dev Demonstrates custom error handling in Solidity
 */
contract CustomErrors {
    // Define custom errors
    error InsufficientBalance(uint256 requested, uint256 available);
    error InvalidAddress(address addr);
    error AmountTooSmall(uint256 amount, uint256 minimum);
    error ContractPaused();
    error UserNotFound(address user);

    mapping(address => uint256) public balances;
    bool public paused;

    /// @notice Transfer using custom errors
    function transfer(address to, uint256 amount) public {
        // Use custom errors for better gas efficiency
        if (paused) {
            revert ContractPaused();
        }

        if (balances[msg.sender] < amount) {
            revert InsufficientBalance(amount, balances[msg.sender]);
        }

        if (to == address(0)) {
            revert InvalidAddress(to);
        }

        if (amount < 100) {
            revert AmountTooSmall(amount, 100);
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    /// @notice Function with custom error
    function getUserBalance(address user) public view returns (uint256) {
        if (balances[user] == 0) {
            revert UserNotFound(user);
        }
        return balances[user];
    }
}

Solidity Intermediate

Structs

Structs are custom data types that group related variables together. They allow you to create complex data structures with multiple fields.

Struct Characteristics:

CharacteristicDescription
Custom TypeDefine your own data structure
Multiple FieldsGroup related data together
NestedCan contain other structs
Stored in StateCan be stored in mappings/arrays

Real-World Example – User Profile:

A struct for a user profile:

  • address – User address
  • string – Username
  • uint256 – Age
  • bool – Is verified

Code Example – Structs:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityStructs
 * @dev Comprehensive demonstration of struct usage in Solidity
 */
contract SolidityStructs {
    // =========================================================================
    // STRUCT DEFINITIONS
    // =========================================================================

    // -------- BASIC STRUCT --------
    struct Person {
        address wallet;
        string name;
        uint256 age;
        bool isVerified;
        uint256 createdAt;
    }

    // -------- STRUCT WITH DEFAULT VALUES --------
    struct Product {
        string name;
        uint256 price;
        uint256 stock;
        bool inStock;
    }

    // -------- NESTED STRUCT --------
    struct Address {
        string street;
        string city;
        string state;
        string country;
        string postalCode;
    }

    struct PersonWithAddress {
        Person person;
        Address address;
        string[] tags;
    }

    // -------- STRUCT WITH MAPPING --------
    struct Wallet {
        uint256 balance;
        mapping(address => uint256) allowances;
        address[] transactions;
    }

    // -------- STRUCT WITH ARRAYS --------
    struct TokenHolder {
        address wallet;
        uint256[] tokenIds;
        uint256 totalBalance;
        bool isActive;
    }

    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    // -------- SIMPLE STRUCT STORAGE --------
    Person public defaultPerson = Person(
        0x742d35Cc6634C0532925a3b844Bc454e4438f44e,
        "Alice Johnson",
        28,
        true,
        block.timestamp
    );

    // -------- MAPPING OF STRUCTS --------
    mapping(address => Person) public people;
    mapping(address => PersonWithAddress) public peopleWithAddress;
    mapping(uint256 => Product) public products;

    // -------- ARRAY OF STRUCTS --------
    Person[] public personList;
    Product[] public productList;

    // -------- NESTED MAPPING --------
    mapping(address => mapping(uint256 => Wallet)) public userWallets;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        // Initialize with some data
        Person memory creator = Person(
            msg.sender,
            "Contract Creator",
            30,
            true,
            block.timestamp
        );
        people[msg.sender] = creator;
        personList.push(creator);

        // Initialize products
        products[1] = Product("Laptop", 1000, 10, true);
        products[2] = Product("Phone", 500, 20, true);
        products[3] = Product("Tablet", 300, 0, false);
    }

    // =========================================================================
    // CREATE FUNCTIONS
    // =========================================================================

    /// @notice Create a person with named fields
    function createPerson(
        string memory name,
        uint256 age,
        bool verified
    ) public {
        Person memory newPerson = Person({
            wallet: msg.sender,
            name: name,
            age: age,
            isVerified: verified,
            createdAt: block.timestamp
        });

        people[msg.sender] = newPerson;
        personList.push(newPerson);
    }

    /// @notice Create a person with positional fields
    function createPersonSimple(
        string memory name,
        uint256 age,
        bool verified
    ) public {
        Person memory newPerson = Person(msg.sender, name, age, verified, block.timestamp);
        people[msg.sender] = newPerson;
        personList.push(newPerson);
    }

    /// @notice Create a person with address
    function createPersonWithAddress(
        string memory name,
        uint256 age,
        bool verified,
        string memory street,
        string memory city,
        string memory state,
        string memory country,
        string memory postalCode
    ) public {
        Person memory person = Person(msg.sender, name, age, verified, block.timestamp);
        Address memory address = Address(street, city, state, country, postalCode);

        string[] memory tags = new string[](2);
        tags[0] = "active";
        tags[1] = "verified";

        peopleWithAddress[msg.sender] = PersonWithAddress(person, address, tags);
    }

    // =========================================================================
    // UPDATE FUNCTIONS
    // =========================================================================

    /// @notice Update person information
    function updatePerson(string memory name, uint256 age, bool verified) public {
        Person storage person = people[msg.sender];
        require(person.wallet != address(0), "Person not found");

        person.name = name;
        person.age = age;
        person.isVerified = verified;
    }

    /// @notice Update person with storage reference
    function updatePersonAge(uint256 newAge) public {
        Person storage person = people[msg.sender];
        require(person.wallet != address(0), "Person not found");
        person.age = newAge;
    }

    /// @notice Update product stock
    function updateProductStock(uint256 productId, uint256 newStock) public {
        Product storage product = products[productId];
        require(bytes(product.name).length > 0, "Product not found");

        product.stock = newStock;
        product.inStock = newStock > 0;
    }

    // =========================================================================
    // READ FUNCTIONS
    // =========================================================================

    /// @notice Get person information
    function getPerson(address wallet) public view returns (
        address addr,
        string memory name,
        uint256 age,
        bool isVerified,
        uint256 createdAt
    ) {
        Person memory person = people[wallet];
        return (person.wallet, person.name, person.age, person.isVerified, person.createdAt);
    }

    /// @notice Get person with address
    function getPersonWithAddress(address wallet) public view returns (
        Person memory person,
        Address memory address,
        string[] memory tags
    ) {
        PersonWithAddress memory data = peopleWithAddress[wallet];
        return (data.person, data.address, data.tags);
    }

    /// @notice Get product information
    function getProduct(uint256 productId) public view returns (
        string memory name,
        uint256 price,
        uint256 stock,
        bool inStock
    ) {
        Product memory product = products[productId];
        return (product.name, product.price, product.stock, product.inStock);
    }

    /// @notice Get all persons
    function getAllPersons() public view returns (Person[] memory) {
        return personList;
    }

    /// @notice Get person count
    function getPersonCount() public view returns (uint256) {
        return personList.length;
    }

    // =========================================================================
    // STRUCT WITH ARRAYS
    // =========================================================================

    mapping(address => TokenHolder) public tokenHolders;

    /// @notice Add token to holder
    function addTokenToHolder(address wallet, uint256 tokenId) public {
        TokenHolder storage holder = tokenHolders[wallet];
        holder.wallet = wallet;
        holder.tokenIds.push(tokenId);
        holder.totalBalance += 1;
        holder.isActive = true;
    }

    /// @notice Remove token from holder
    function removeTokenFromHolder(address wallet, uint256 tokenId) public {
        TokenHolder storage holder = tokenHolders[wallet];
        require(holder.wallet != address(0), "Holder not found");

        // Find and remove token
        for (uint256 i = 0; i < holder.tokenIds.length; i++) {
            if (holder.tokenIds[i] == tokenId) {
                holder.tokenIds[i] = holder.tokenIds[holder.tokenIds.length - 1];
                holder.tokenIds.pop();
                holder.totalBalance -= 1;
                break;
            }
        }
    }

    /// @notice Get token holder info
    function getTokenHolder(address wallet) public view returns (
        uint256[] memory tokenIds,
        uint256 totalBalance,
        bool isActive
    ) {
        TokenHolder memory holder = tokenHolders[wallet];
        return (holder.tokenIds, holder.totalBalance, holder.isActive);
    }

    // =========================================================================
    // COMPLEX STRUCT OPERATIONS
    // =========================================================================

    /// @notice Create product with validation
    function createProduct(
        uint256 productId,
        string memory name,
        uint256 price,
        uint256 stock
    ) public {
        require(productId > 0, "Invalid product ID");
        require(bytes(name).length > 0, "Name required");
        require(price > 0, "Price must be positive");
        require(products[productId].price == 0, "Product already exists");

        products[productId] = Product(name, price, stock, stock > 0);
        productList.push(products[productId]);
    }

    /// @notice Delete product
    function deleteProduct(uint256 productId) public {
        require(products[productId].price > 0, "Product not found");
        delete products[productId];
    }

    // =========================================================================
    // STRUCT AS RETURN VALUE
    // =========================================================================

    /// @notice Return entire struct
    function getFullPerson(address wallet) public view returns (Person memory) {
        return people[wallet];
    }

    /// @notice Return multiple structs
    function getMultiplePersons(address wallet1, address wallet2)
        public
        view
        returns (Person memory, Person memory)
    {
        return (people[wallet1], people[wallet2]);
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event PersonCreated(address indexed wallet, string name);
    event PersonUpdated(address indexed wallet, string newName);
    event ProductAdded(uint256 indexed productId, string name);

    /// @notice Create person with event
    function createPersonWithEvent(
        string memory name,
        uint256 age,
        bool verified
    ) public {
        Person memory newPerson = Person(msg.sender, name, age, verified, block.timestamp);
        people[msg.sender] = newPerson;
        personList.push(newPerson);
        emit PersonCreated(msg.sender, name);
    }

    /// @notice Create product with event
    function createProductWithEvent(
        uint256 productId,
        string memory name,
        uint256 price,
        uint256 stock
    ) public {
        require(productId > 0, "Invalid product ID");
        require(bytes(name).length > 0, "Name required");
        require(price > 0, "Price must be positive");

        products[productId] = Product(name, price, stock, stock > 0);
        productList.push(products[productId]);
        emit ProductAdded(productId, name);
    }
}

// =========================================================================
// INHERITANCE WITH STRUCTS
// =========================================================================

/**
 * @title StructInheritance
 * @dev Demonstrates struct inheritance
 */
contract StructInheritance is SolidityStructs {
    // Additional structs
    struct SpecialUser {
        Person person;
        uint256 specialRank;
        bool isVIP;
    }

    mapping(address => SpecialUser) public specialUsers;

    /// @notice Create special user
    function createSpecialUser(
        string memory name,
        uint256 age,
        uint256 rank,
        bool isVIP
    ) public {
        Person memory person = Person(msg.sender, name, age, true, block.timestamp);
        specialUsers[msg.sender] = SpecialUser(person, rank, isVIP);
    }

    /// @notice Get all persons (overrides parent)
    function getAllPersons() public view override returns (Person[] memory) {
        // Can add custom logic before returning
        return super.getAllPersons();
    }
}

Enums

Enums are user-defined types that restrict a variable to a set of predefined values. They make code more readable and type-safe.

Enum Characteristics:

CharacteristicDescription
Predefined ValuesSet of allowed values
Type-SafeOnly defined values allowed
ReadableNames instead of numbers
ConvertibleCan convert to/from uint

Real-World Example – Order Status:

An enum for order status:

  • Pending
  • Processing
  • Shipped
  • Delivered
  • Cancelled

Code Example – Enums:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityEnums
 * @dev Comprehensive demonstration of enum usage in Solidity
 */
contract SolidityEnums {
    // =========================================================================
    // ENUM DEFINITIONS
    // =========================================================================

    // -------- BASIC ENUM --------
    enum Status {
        Pending,
        Active,
        Inactive,
        Blocked,
        Suspended
    }

    // -------- ENUM FOR ORDER STATES --------
    enum OrderState {
        Created,
        Processing,
        Shipped,
        Delivered,
        Cancelled,
        Refunded,
        Returned
    }

    // -------- ENUM FOR USER ROLES --------
    enum Role {
        User,
        Moderator,
        Admin,
        SuperAdmin
    }

    // -------- ENUM FOR PRIORITY LEVELS --------
    enum Priority {
        Low,
        Medium,
        High,
        Critical
    }

    // -------- ENUM FOR TOKEN TYPES --------
    enum TokenType {
        ERC20,
        ERC721,
        ERC1155
    }

    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    // -------- SIMPLE ENUM STORAGE --------
    Status public currentStatus = Status.Pending;
    Priority public currentPriority = Priority.Medium;

    // -------- MAPPINGS WITH ENUMS --------
    mapping(address => Status) public userStatus;
    mapping(address => Role) public userRoles;
    mapping(uint256 => OrderState) public orderStates;
    mapping(address => TokenType) public supportedTokens;

    // -------- ARRAY OF ENUMS --------
    Status[] public statusHistory;
    Priority[] public priorityHistory;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        // Initialize with some data
        userRoles[msg.sender] = Role.SuperAdmin;
        userStatus[msg.sender] = Status.Active;
        statusHistory.push(Status.Active);
    }

    // =========================================================================
    // STATUS FUNCTIONS
    // =========================================================================

    /// @notice Set current status
    function setStatus(Status newStatus) public {
        require(msg.sender == address(this) || userRoles[msg.sender] >= Role.Admin, 
            "Only admin can change status");
        currentStatus = newStatus;
        statusHistory.push(newStatus);
    }

    /// @notice Get current status as string
    function getStatusString() public view returns (string memory) {
        return _statusToString(currentStatus);
    }

    /// @notice Get status as uint
    function getStatusValue() public view returns (uint256) {
        return uint256(currentStatus);
    }

    /// @notice Check if status is active
    function isActive() public view returns (bool) {
        return currentStatus == Status.Active;
    }

    // =========================================================================
    // USER STATUS FUNCTIONS
    // =========================================================================

    /// @notice Set user status
    function setUserStatus(address user, Status status) public {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can set user status");
        userStatus[user] = status;
    }

    /// @notice Get user status
    function getUserStatus(address user) public view returns (Status) {
        return userStatus[user];
    }

    /// @notice Check if user is active
    function isUserActive(address user) public view returns (bool) {
        return userStatus[user] == Status.Active;
    }

    /// @notice Get user status as string
    function getUserStatusString(address user) public view returns (string memory) {
        return _statusToString(userStatus[user]);
    }

    // =========================================================================
    // ROLE FUNCTIONS
    // =========================================================================

    /// @notice Set user role
    function setUserRole(address user, Role role) public {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can set roles");
        userRoles[user] = role;
    }

    /// @notice Get user role
    function getUserRole(address user) public view returns (Role) {
        return userRoles[user];
    }

    /// @notice Check if user is admin
    function isAdmin(address user) public view returns (bool) {
        Role role = userRoles[user];
        return role == Role.Admin || role == Role.SuperAdmin;
    }

    /// @notice Check if user is super admin
    function isSuperAdmin(address user) public view returns (bool) {
        return userRoles[user] == Role.SuperAdmin;
    }

    /// @notice Get role name as string
    function getRoleName(Role role) public pure returns (string memory) {
        if (role == Role.User) return "User";
        if (role == Role.Moderator) return "Moderator";
        if (role == Role.Admin) return "Admin";
        if (role == Role.SuperAdmin) return "SuperAdmin";
        return "Unknown";
    }

    /// @notice Get user role name
    function getUserRoleName(address user) public view returns (string memory) {
        return getRoleName(userRoles[user]);
    }

    // =========================================================================
    // ORDER FUNCTIONS
    // =========================================================================

    /// @notice Create new order
    function createOrder(uint256 orderId) public {
        require(orderStates[orderId] == OrderState(0), "Order already exists");
        orderStates[orderId] = OrderState.Created;
    }

    /// @notice Update order state (forward only)
    function updateOrderState(uint256 orderId, OrderState newState) public {
        OrderState currentState = orderStates[orderId];
        require(currentState != OrderState.Cancelled, "Order already cancelled");
        require(currentState != OrderState.Delivered, "Order already delivered");
        require(newState > currentState, "Cannot go backward");
        orderStates[orderId] = newState;
    }

    /// @notice Cancel order
    function cancelOrder(uint256 orderId) public {
        OrderState state = orderStates[orderId];
        require(state != OrderState.Cancelled, "Already cancelled");
        require(state != OrderState.Delivered, "Cannot cancel delivered");
        require(state != OrderState.Refunded, "Already refunded");
        orderStates[orderId] = OrderState.Cancelled;
    }

    /// @notice Refund order
    function refundOrder(uint256 orderId) public {
        OrderState state = orderStates[orderId];
        require(state == OrderState.Created || state == OrderState.Processing, 
            "Cannot refund at this stage");
        orderStates[orderId] = OrderState.Refunded;
    }

    /// @notice Get order state as string
    function getOrderStateString(uint256 orderId) public view returns (string memory) {
        OrderState state = orderStates[orderId];
        if (state == OrderState.Created) return "Created";
        if (state == OrderState.Processing) return "Processing";
        if (state == OrderState.Shipped) return "Shipped";
        if (state == OrderState.Delivered) return "Delivered";
        if (state == OrderState.Cancelled) return "Cancelled";
        if (state == OrderState.Refunded) return "Refunded";
        if (state == OrderState.Returned) return "Returned";
        return "Unknown";
    }

    /// @notice Check if order is completed
    function isOrderCompleted(uint256 orderId) public view returns (bool) {
        OrderState state = orderStates[orderId];
        return state == OrderState.Delivered || state == OrderState.Refunded;
    }

    // =========================================================================
    // PRIORITY FUNCTIONS
    // =========================================================================

    /// @notice Set priority
    function setPriority(Priority priority) public {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can set priority");
        currentPriority = priority;
        priorityHistory.push(priority);
    }

    /// @notice Get priority name
    function getPriorityName(Priority priority) public pure returns (string memory) {
        if (priority == Priority.Low) return "Low";
        if (priority == Priority.Medium) return "Medium";
        if (priority == Priority.High) return "High";
        if (priority == Priority.Critical) return "Critical";
        return "Unknown";
    }

    // =========================================================================
    // TOKEN TYPE FUNCTIONS
    // =========================================================================

    /// @notice Set supported token type
    function setSupportedToken(address token, TokenType tokenType) public {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can set token types");
        supportedTokens[token] = tokenType;
    }

    /// @notice Get token type name
    function getTokenTypeName(TokenType tokenType) public pure returns (string memory) {
        if (tokenType == TokenType.ERC20) return "ERC20";
        if (tokenType == TokenType.ERC721) return "ERC721";
        if (tokenType == TokenType.ERC1155) return "ERC1155";
        return "Unknown";
    }

    // =========================================================================
    // HELPER FUNCTIONS
    // =========================================================================

    /// @notice Convert Status to string
    function _statusToString(Status status) internal pure returns (string memory) {
        if (status == Status.Pending) return "Pending";
        if (status == Status.Active) return "Active";
        if (status == Status.Inactive) return "Inactive";
        if (status == Status.Blocked) return "Blocked";
        if (status == Status.Suspended) return "Suspended";
        return "Unknown";
    }

    /// @notice Get all status history
    function getStatusHistory() public view returns (Status[] memory) {
        return statusHistory;
    }

    /// @notice Get priority history
    function getPriorityHistory() public view returns (Priority[] memory) {
        return priorityHistory;
    }

    /// @notice Convert enum to uint
    function enumToUint(Status status) public pure returns (uint256) {
        return uint256(status);
    }

    /// @notice Convert uint to enum (with validation)
    function uintToStatus(uint256 value) public pure returns (Status) {
        require(value <= 4, "Invalid status value");
        return Status(value);
    }

    // =========================================================================
    // MODIFIERS
    // =========================================================================

    modifier onlyAdmin() {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can call this");
        _;
    }

    modifier onlySuperAdmin() {
        require(userRoles[msg.sender] == Role.SuperAdmin, "Only super admin can call this");
        _;
    }

    modifier onlyActive() {
        require(currentStatus == Status.Active, "Contract is not active");
        _;
    }

    /// @notice Function with modifiers
    function adminOnlyFunction() public onlyAdmin {
        // Admin only logic
    }

    /// @notice Function with multiple modifiers
    function superAdminOnlyFunction() public onlySuperAdmin onlyActive {
        // Super admin only, active contract only
    }
}

// =========================================================================
// ENUM IN INHERITANCE
// =========================================================================

/**
 * @title EnumInheritance
 * @dev Demonstrates enum inheritance
 */
contract EnumInheritance is SolidityEnums {
    // Additional enum
    enum ExtraStatus {
        Archived,
        Deleted
    }

    mapping(address => ExtraStatus) public extraStatus;

    /// @notice Set extra status
    function setExtraStatus(address user, ExtraStatus status) public {
        require(userRoles[msg.sender] >= Role.Admin, "Only admin can set");
        extraStatus[user] = status;
    }

    /// @notice Combine enums
    function getCombinedStatus(address user) public view returns (string memory) {
        Status primary = userStatus[user];
        ExtraStatus extra = extraStatus[user];
        return string(abi.encodePacked(
            _statusToString(primary),
            " - ",
            extra == ExtraStatus.Archived ? "Archived" : "Deleted"
        ));
    }
}

Arrays

Arrays are data structures that store multiple values of the same type. They can be fixed-size or dynamic.

Array Types:

TypeDescriptionGas CostUse Case
FixedFixed length, known at compile timeLowerKnown data size
DynamicVariable length, can grow/shrinkHigherUnknown data size
MemoryTemporary array in functionLowerTemporary data
StoragePersistent array in stateHigherStored data

Real-World Example – Token Holders:

  • Fixed array: 10 allowed admins
  • Dynamic array: All token holders
  • Memory array: Processing multiple transfers

Code Example – Arrays:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityArrays
 * @dev Comprehensive demonstration of array usage in Solidity
 */
contract SolidityArrays {
    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    // -------- FIXED-SIZE ARRAYS --------
    uint256[5] public fixedArray;              // Fixed array of 5 uint256
    uint256[3] public fixedNumbers = [10, 20, 30];
    address[2] public fixedAddresses;
    bytes32[4] public fixedBytes;

    // -------- DYNAMIC ARRAYS --------
    uint256[] public dynamicArray;
    address[] public users;
    string[] public messages;
    bool[] public flags;

    // -------- 2D ARRAYS --------
    uint256[3][4] public matrix;  // 4 rows, 3 columns
    uint256[][] public dynamicMatrix;

    // -------- ARRAY OF STRUCTS --------
    struct Person {
        address wallet;
        string name;
        uint256 age;
    }
    Person[] public personList;

    // -------- ARRAY OF MAPPINGS --------
    mapping(address => uint256)[] public userMappings;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        // Initialize fixed arrays
        fixedArray = [100, 200, 300, 400, 500];
        fixedAddresses = [msg.sender, address(0)];

        // Initialize dynamic arrays
        dynamicArray.push(1);
        dynamicArray.push(2);
        dynamicArray.push(3);

        users.push(msg.sender);
    }

    // =========================================================================
    // FIXED ARRAY OPERATIONS
    // =========================================================================

    /// @notice Set value in fixed array
    function setFixedArray(uint256 index, uint256 value) public {
        require(index < fixedArray.length, "Index out of bounds");
        fixedArray[index] = value;
    }

    /// @notice Get fixed array value
    function getFixedArray(uint256 index) public view returns (uint256) {
        require(index < fixedArray.length, "Index out of bounds");
        return fixedArray[index];
    }

    /// @notice Get entire fixed array
    function getFixedArrayAll() public view returns (uint256[5] memory) {
        return fixedArray;
    }

    // =========================================================================
    // DYNAMIC ARRAY OPERATIONS
    // =========================================================================

    /// @notice Add value to dynamic array
    function addToArray(uint256 value) public {
        dynamicArray.push(value);
    }

    /// @notice Remove last element
    function popFromArray() public {
        require(dynamicArray.length > 0, "Array is empty");
        dynamicArray.pop();
    }

    /// @notice Remove element at index (swaps with last)
    function removeFromArray(uint256 index) public {
        require(index < dynamicArray.length, "Index out of bounds");
        dynamicArray[index] = dynamicArray[dynamicArray.length - 1];
        dynamicArray.pop();
    }

    /// @notice Get array length
    function getArrayLength() public view returns (uint256) {
        return dynamicArray.length;
    }

    /// @notice Get array element
    function getArrayElement(uint256 index) public view returns (uint256) {
        require(index < dynamicArray.length, "Index out of bounds");
        return dynamicArray[index];
    }

    /// @notice Get full array
    function getFullArray() public view returns (uint256[] memory) {
        return dynamicArray;
    }

    // =========================================================================
    // ADDRESS ARRAY OPERATIONS
    // =========================================================================

    /// @notice Add user
    function addUser(address user) public {
        require(user != address(0), "Invalid address");
        require(!_isUserExists(user), "User already exists");
        users.push(user);
    }

    /// @notice Remove user
    function removeUser(address user) public {
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == user) {
                users[i] = users[users.length - 1];
                users.pop();
                return;
            }
        }
        revert("User not found");
    }

    /// @notice Check if user exists
    function isUserExists(address user) public view returns (bool) {
        return _isUserExists(user);
    }

    /// @notice Get all users
    function getUsers() public view returns (address[] memory) {
        return users;
    }

    /// @notice Get user count
    function getUserCount() public view returns (uint256) {
        return users.length;
    }

    // =========================================================================
    // 2D ARRAY OPERATIONS
    // =========================================================================

    /// @notice Set matrix value
    function setMatrix(uint256 row, uint256 col, uint256 value) public {
        require(row < matrix.length, "Row out of bounds");
        require(col < matrix[row].length, "Col out of bounds");
        matrix[row][col] = value;
    }

    /// @notice Get matrix value
    function getMatrix(uint256 row, uint256 col) public view returns (uint256) {
        require(row < matrix.length, "Row out of bounds");
        require(col < matrix[row].length, "Col out of bounds");
        return matrix[row][col];
    }

    /// @notice Get entire matrix
    function getMatrixAll() public view returns (uint256[3][4] memory) {
        return matrix;
    }

    /// @notice Add row to dynamic matrix
    function addToDynamicMatrix(uint256[] memory row) public {
        dynamicMatrix.push(row);
    }

    /// @notice Get row from dynamic matrix
    function getDynamicMatrixRow(uint256 row) public view returns (uint256[] memory) {
        require(row < dynamicMatrix.length, "Row out of bounds");
        return dynamicMatrix[row];
    }

    /// @notice Get dynamic matrix
    function getDynamicMatrix() public view returns (uint256[][] memory) {
        return dynamicMatrix;
    }

    // =========================================================================
    // ARRAY OF STRUCTS
    // =========================================================================

    /// @notice Add person
    function addPerson(address wallet, string memory name, uint256 age) public {
        personList.push(Person(wallet, name, age));
    }

    /// @notice Get person
    function getPerson(uint256 index) public view returns (address, string memory, uint256) {
        require(index < personList.length, "Index out of bounds");
        Person memory person = personList[index];
        return (person.wallet, person.name, person.age);
    }

    /// @notice Update person
    function updatePerson(uint256 index, string memory name, uint256 age) public {
        require(index < personList.length, "Index out of bounds");
        personList[index].name = name;
        personList[index].age = age;
    }

    /// @notice Get person count
    function getPersonCount() public view returns (uint256) {
        return personList.length;
    }

    /// @notice Get all persons
    function getAllPersons() public view returns (Person[] memory) {
        return personList;
    }

    // =========================================================================
    // ARRAY HELPER FUNCTIONS
    // =========================================================================

    /// @notice Sum array elements
    function sumArray(uint256[] memory arr) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    /// @notice Find maximum value
    function findMax(uint256[] memory arr) public pure returns (uint256) {
        require(arr.length > 0, "Array is empty");
        uint256 max = arr[0];
        for (uint256 i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        return max;
    }

    /// @notice Find minimum value
    function findMin(uint256[] memory arr) public pure returns (uint256) {
        require(arr.length > 0, "Array is empty");
        uint256 min = arr[0];
        for (uint256 i = 1; i < arr.length; i++) {
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        return min;
    }

    /// @notice Slice array
    function sliceArray(uint256[] memory arr, uint256 start, uint256 end)
        public
        pure
        returns (uint256[] memory)
    {
        require(start <= end, "Invalid range");
        require(end <= arr.length, "End out of bounds");

        uint256[] memory result = new uint256[](end - start);
        for (uint256 i = start; i < end; i++) {
            result[i - start] = arr[i];
        }
        return result;
    }

    /// @notice Reverse array
    function reverseArray(uint256[] memory arr) public pure returns (uint256[] memory) {
        uint256[] memory result = new uint256[](arr.length);
        for (uint256 i = 0; i < arr.length; i++) {
            result[i] = arr[arr.length - 1 - i];
        }
        return result;
    }

    /// @notice Check if array contains element
    function contains(uint256[] memory arr, uint256 value) public pure returns (bool) {
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] == value) {
                return true;
            }
        }
        return false;
    }

    // =========================================================================
    // ADVANCED ARRAY OPERATIONS
    // =========================================================================

    /// @notice Merge two arrays
    function mergeArrays(uint256[] memory a, uint256[] memory b)
        public
        pure
        returns (uint256[] memory)
    {
        uint256[] memory result = new uint256[](a.length + b.length);
        for (uint256 i = 0; i < a.length; i++) {
            result[i] = a[i];
        }
        for (uint256 i = 0; i < b.length; i++) {
            result[a.length + i] = b[i];
        }
        return result;
    }

    /// @notice Unique elements from array
    function uniqueElements(uint256[] memory arr) public pure returns (uint256[] memory) {
        uint256[] memory temp = new uint256[](arr.length);
        uint256 uniqueCount = 0;

        for (uint256 i = 0; i < arr.length; i++) {
            bool isDuplicate = false;
            for (uint256 j = 0; j < uniqueCount; j++) {
                if (temp[j] == arr[i]) {
                    isDuplicate = true;
                    break;
                }
            }
            if (!isDuplicate) {
                temp[uniqueCount] = arr[i];
                uniqueCount++;
            }
        }

        uint256[] memory result = new uint256[](uniqueCount);
        for (uint256 i = 0; i < uniqueCount; i++) {
            result[i] = temp[i];
        }
        return result;
    }

    // =========================================================================
    // PRIVATE HELPERS
    // =========================================================================

    /// @dev Check if user exists
    function _isUserExists(address user) private view returns (bool) {
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == user) {
                return true;
            }
        }
        return false;
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event ArrayUpdated(uint256 index, uint256 value);
    event UserAdded(address indexed user);
    event UserRemoved(address indexed user);

    /// @notice Add user with event
    function addUserWithEvent(address user) public {
        require(user != address(0), "Invalid address");
        require(!_isUserExists(user), "User already exists");
        users.push(user);
        emit UserAdded(user);
    }

    /// @notice Remove user with event
    function removeUserWithEvent(address user) public {
        for (uint256 i = 0; i < users.length; i++) {
            if (users[i] == user) {
                users[i] = users[users.length - 1];
                users.pop();
                emit UserRemoved(user);
                return;
            }
        }
        revert("User not found");
    }
}

Mappings

Mappings are key-value stores that allow you to look up values by keys. They are like dictionaries or hash maps in other languages.

Mapping Characteristics:

CharacteristicDescription
Key-ValueStore values by key
EfficientO(1) lookup time
All Keys ExistReturns default for missing keys
No IterationCannot iterate over all keys

Real-World Example – Token Balances:

mapping(address => uint256) public balances;

  • Key: User’s address
  • Value: Token balance

Code Example – Mappings:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityMappings
 * @dev Comprehensive demonstration of mapping usage in Solidity
 */
contract SolidityMappings {
    // =========================================================================
    // BASIC MAPPINGS
    // =========================================================================

    // -------- SIMPLE MAPPINGS --------
    mapping(address => uint256) public balances;
    mapping(address => string) public usernames;
    mapping(address => bool) public isActive;
    mapping(address => uint256) public nonces;
    mapping(address => uint256) public lastActivity;

    // =========================================================================
    // NESTED MAPPINGS (Mapping of Mappings)
    // =========================================================================

    // -------- TWO-LEVEL MAPPING --------
    mapping(address => mapping(address => uint256)) public allowances;
    mapping(address => mapping(string => uint256)) public tokenBalances;
    mapping(address => mapping(uint256 => bool)) public userFlags;

    // -------- THREE-LEVEL MAPPING --------
    mapping(address => mapping(address => mapping(uint256 => bool))) public complexData;

    // =========================================================================
    // MAPPING WITH STRUCTS
    // =========================================================================

    struct User {
        string name;
        uint256 age;
        bool verified;
        uint256 createdAt;
        address[] friends;
    }

    mapping(address => User) public users;

    struct Product {
        string name;
        uint256 price;
        uint256 stock;
        bool available;
    }

    mapping(uint256 => Product) public products;

    // =========================================================================
    // MAPPING WITH ARRAYS
    // =========================================================================

    mapping(address => uint256[]) public userTransactions;
    mapping(address => address[]) public following;
    mapping(address => string[]) public userMessages;

    // =========================================================================
    // MAPPING WITH ENUMS
    // =========================================================================

    enum Status { Pending, Active, Inactive, Blocked }
    mapping(address => Status) public userStatus;

    // =========================================================================
    // MAPPING WITH CUSTOM KEYS
    // =========================================================================

    mapping(address => mapping(bytes32 => uint256)) public customData;
    mapping(uint256 => mapping(string => address)) public idToAddress;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        // Initialize with some data
        balances[msg.sender] = 1000;
        usernames[msg.sender] = "admin";
        isActive[msg.sender] = true;
        nonces[msg.sender] = 0;
        userStatus[msg.sender] = Status.Active;

        // Create a sample user
        users[msg.sender] = User({
            name: "Admin",
            age: 30,
            verified: true,
            createdAt: block.timestamp,
            friends: new address[](0)
        });

        // Initialize products
        products[1] = Product("Laptop", 1000, 10, true);
        products[2] = Product("Phone", 500, 20, true);
        products[3] = Product("Tablet", 300, 0, false);
    }

    // =========================================================================
    // BASIC MAPPING OPERATIONS
    // =========================================================================

    /// @notice Set balance
    function setBalance(address user, uint256 amount) public {
        require(msg.sender == user || msg.sender == address(this), "Not authorized");
        balances[user] = amount;
    }

    /// @notice Get balance (returns 0 if not set)
    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    /// @notice Increment balance
    function incrementBalance(address user, uint256 amount) public {
        balances[user] += amount;
    }

    /// @notice Decrement balance
    function decrementBalance(address user, uint256 amount) public {
        require(balances[user] >= amount, "Insufficient balance");
        balances[user] -= amount;
    }

    /// @notice Set username
    function setUsername(string memory name) public {
        usernames[msg.sender] = name;
    }

    /// @notice Get username
    function getUsername(address user) public view returns (string memory) {
        return usernames[user];
    }

    /// @notice Set active status
    function setActive(address user, bool active) public {
        require(msg.sender == user || userStatus[msg.sender] == Status.Active, 
            "Not authorized");
        isActive[user] = active;
    }

    /// @notice Check if user is active
    function isActiveUser(address user) public view returns (bool) {
        return isActive[user];
    }

    // =========================================================================
    // NESTED MAPPING OPERATIONS
    // =========================================================================

    /// @notice Approve spending allowance
    function approve(address spender, uint256 amount) public {
        allowances[msg.sender][spender] = amount;
    }

    /// @notice Get allowance
    function getAllowance(address owner, address spender) public view returns (uint256) {
        return allowances[owner][spender];
    }

    /// @notice Transfer from (using allowance)
    function transferFrom(address from, address to, uint256 amount) public {
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");
        require(balances[from] >= amount, "Insufficient balance");

        allowances[from][msg.sender] -= amount;
        balances[from] -= amount;
        balances[to] += amount;
    }

    /// @notice Set token balance
    function setTokenBalance(address user, string memory token, uint256 amount) public {
        tokenBalances[user][token] = amount;
    }

    /// @notice Get token balance
    function getTokenBalance(address user, string memory token) public view returns (uint256) {
        return tokenBalances[user][token];
    }

    // =========================================================================
    // MAPPING WITH STRUCTS
    // =========================================================================

    /// @notice Create user
    function createUser(string memory name, uint256 age) public {
        require(bytes(usernames[msg.sender]).length == 0, "User already exists");

        users[msg.sender] = User({
            name: name,
            age: age,
            verified: false,
            createdAt: block.timestamp,
            friends: new address[](0)
        });
        usernames[msg.sender] = name;
        isActive[msg.sender] = true;
    }

    /// @notice Get user info
    function getUser(address user) public view returns (
        string memory name,
        uint256 age,
        bool verified,
        uint256 createdAt,
        address[] memory friends
    ) {
        User memory userData = users[user];
        return (userData.name, userData.age, userData.verified, userData.createdAt, userData.friends);
    }

    /// @notice Update user
    function updateUser(string memory name, uint256 age) public {
        require(bytes(usernames[msg.sender]).length > 0, "User not found");
        users[msg.sender].name = name;
        users[msg.sender].age = age;
        usernames[msg.sender] = name;
    }

    /// @notice Verify user
    function verifyUser(address user) public {
        require(msg.sender == address(this) || userStatus[msg.sender] == Status.Active, 
            "Not authorized");
        users[user].verified = true;
    }

    /// @notice Add friend
    function addFriend(address friend) public {
        require(friend != address(0), "Invalid address");
        require(friend != msg.sender, "Cannot add self");

        bool exists = false;
        for (uint256 i = 0; i < users[msg.sender].friends.length; i++) {
            if (users[msg.sender].friends[i] == friend) {
                exists = true;
                break;
            }
        }
        require(!exists, "Already friends");

        users[msg.sender].friends.push(friend);
    }

    /// @notice Get friends
    function getFriends(address user) public view returns (address[] memory) {
        return users[user].friends;
    }

    // =========================================================================
    // MAPPING WITH ARRAYS
    // =========================================================================

    /// @notice Add transaction
    function addTransaction(uint256 amount) public {
        userTransactions[msg.sender].push(amount);
    }

    /// @notice Get transactions
    function getTransactions(address user) public view returns (uint256[] memory) {
        return userTransactions[user];
    }

    /// @notice Get transaction count
    function getTransactionCount(address user) public view returns (uint256) {
        return userTransactions[user].length;
    }

    /// @notice Follow user
    function follow(address user) public {
        require(user != address(0), "Invalid address");
        require(user != msg.sender, "Cannot follow self");

        bool exists = false;
        for (uint256 i = 0; i < following[msg.sender].length; i++) {
            if (following[msg.sender][i] == user) {
                exists = true;
                break;
            }
        }
        require(!exists, "Already following");

        following[msg.sender].push(user);
    }

    /// @notice Unfollow user
    function unfollow(address user) public {
        for (uint256 i = 0; i < following[msg.sender].length; i++) {
            if (following[msg.sender][i] == user) {
                following[msg.sender][i] = following[msg.sender][following[msg.sender].length - 1];
                following[msg.sender].pop();
                return;
            }
        }
        revert("Not following");
    }

    /// @notice Get following
    function getFollowing(address user) public view returns (address[] memory) {
        return following[user];
    }

    // =========================================================================
    // MAPPING WITH ENUMS
    // =========================================================================

    /// @notice Set user status
    function setUserStatus(address user, Status status) public {
        require(msg.sender == user || userStatus[msg.sender] == Status.Active, 
            "Not authorized");
        userStatus[user] = status;
    }

    /// @notice Get user status
    function getUserStatus(address user) public view returns (Status) {
        return userStatus[user];
    }

    /// @notice Check if user is active
    function isUserActive(address user) public view returns (bool) {
        return userStatus[user] == Status.Active;
    }

    // =========================================================================
    // ADVANCED MAPPING PATTERNS
    // =========================================================================

    /// @notice Increment nonce (replay protection)
    function incrementNonce() public {
        nonces[msg.sender]++;
    }

    /// @notice Update last activity
    function updateActivity() public {
        lastActivity[msg.sender] = block.timestamp;
    }

    /// @notice Get last activity
    function getLastActivity(address user) public view returns (uint256) {
        return lastActivity[user];
    }

    /// @notice Set custom data
    function setCustomData(address user, bytes32 key, uint256 value) public {
        require(msg.sender == user || userStatus[msg.sender] == Status.Active, 
            "Not authorized");
        customData[user][key] = value;
    }

    /// @notice Get custom data
    function getCustomData(address user, bytes32 key) public view returns (uint256) {
        return customData[user][key];
    }

    /// @notice Set product
    function setProduct(uint256 id, string memory name, uint256 price, uint256 stock) public {
        require(id > 0, "Invalid ID");
        products[id] = Product(name, price, stock, stock > 0);
    }

    /// @notice Get product
    function getProduct(uint256 id) public view returns (
        string memory name,
        uint256 price,
        uint256 stock,
        bool available
    ) {
        Product memory product = products[id];
        return (product.name, product.price, product.stock, product.available);
    }

    // =========================================================================
    // MAPPING GOTCHAS AND BEST PRACTICES
    // =========================================================================

    /// @dev Demonstrate mapping default values
    function checkMappingDefaults() public view returns (
        uint256 balance,
        bool active,
        address userAddr,
        string memory username
    ) {
        // Default values for missing keys
        address testAddr = address(0x123);
        balance = balances[testAddr];        // Returns 0
        active = isActive[testAddr];         // Returns false
        userAddr = users[testAddr].addr;     // Returns address(0)
        username = usernames[testAddr];      // Returns empty string
    }

    /// @dev Cannot iterate over mappings directly
    /// @dev Need to maintain separate array for keys

    // Mapping with key tracking
    address[] public allUsers;
    mapping(address => bool) public isRegistered;

    /// @notice Register user with tracking
    function registerUser() public {
        require(!isRegistered[msg.sender], "Already registered");
        isRegistered[msg.sender] = true;
        allUsers.push(msg.sender);
    }

    /// @notice Get all registered users
    function getAllUsers() public view returns (address[] memory) {
        return allUsers;
    }

    /// @notice Get total user count
    function getUserCount() public view returns (uint256) {
        return allUsers.length;
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event BalanceUpdated(address indexed user, uint256 newBalance);
    event UserCreated(address indexed user, string name);
    event UserVerified(address indexed user);

    /// @notice Create user with event
    function createUserWithEvent(string memory name, uint256 age) public {
        require(bytes(usernames[msg.sender]).length == 0, "User already exists");

        users[msg.sender] = User({
            name: name,
            age: age,
            verified: false,
            createdAt: block.timestamp,
            friends: new address[](0)
        });
        usernames[msg.sender] = name;
        isActive[msg.sender] = true;
        isRegistered[msg.sender] = true;
        allUsers.push(msg.sender);

        emit UserCreated(msg.sender, name);
    }

    /// @notice Verify user with event
    function verifyUserWithEvent(address user) public {
        require(userStatus[msg.sender] == Status.Active, "Not authorized");
        users[user].verified = true;
        emit UserVerified(user);
    }
}

Events

Events are used to log information about contract actions. They are stored in the blockchain and can be listened to by external applications.

Event Characteristics:

CharacteristicDescription
Log DataRecord information on blockchain
IndexableCan search by indexed parameters
Gas EfficientCheaper than storing data
External AccessAccessible by off-chain apps

Real-World Example – Token Transfer:

event Transfer(address indexed from, address indexed to, uint256 value);
  • Logs token transfers
  • Indexed fields allow filtering
  • Applications can listen to events

Code Example – Events:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityEvents
 * @dev Comprehensive demonstration of event usage in Solidity
 */
contract SolidityEvents {
    // =========================================================================
    // EVENT DEFINITIONS
    // =========================================================================

    // -------- BASIC EVENTS (No Indexed Parameters) --------
    event Log(string message);
    event LogUint(uint256 value);
    event LogAddress(address addr);
    event LogBytes(bytes data);
    event LogBool(bool value);

    // -------- EVENTS WITH INDEXED PARAMETERS --------
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
    event TokenMinted(address indexed to, uint256 amount);
    event TokenBurned(address indexed from, uint256 amount);

    // -------- EVENTS WITH MIXED INDEXED/NON-INDEXED --------
    event UserRegistered(
        address indexed user,
        string name,
        uint256 age,
        uint256 timestamp
    );

    event OrderCreated(
        uint256 indexed orderId,
        address indexed buyer,
        address indexed seller,
        uint256 amount,
        string status
    );

    // -------- EVENTS WITH ALL INDEXED PARAMETERS --------
    event FullIndexedEvent(
        address indexed addr1,
        address indexed addr2,
        uint256 indexed value
    );

    // -------- ANONYMOUS EVENT --------
    event AnonymousEvent(address indexed user) anonymous;

    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    mapping(address => uint256) public balances;
    mapping(address => mapping(address => uint256)) public allowances;
    mapping(address => bool) public registeredUsers;
    mapping(uint256 => bool) public processedOrders;

    uint256 public totalSupply;
    uint256 public orderCounter;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        // Emit event on deployment
        emit Log("Contract deployed successfully");
        emit LogAddress(msg.sender);
    }

    // =========================================================================
    // TRANSFER FUNCTIONS
    // =========================================================================

    /// @notice Transfer tokens with event
    function transfer(address to, uint256 amount) public returns (bool) {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(to != address(0), "Invalid address");

        balances[msg.sender] -= amount;
        balances[to] += amount;

        emit Transfer(msg.sender, to, amount);
        emit Log("Transfer completed successfully");

        return true;
    }

    /// @notice Transfer with additional logging
    function transferWithLogs(address to, uint256 amount) public returns (bool) {
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;

        emit Transfer(msg.sender, to, amount);
        emit LogUint(amount);
        emit LogAddress(to);

        return true;
    }

    // =========================================================================
    // APPROVAL FUNCTIONS
    // =========================================================================

    /// @notice Approve spending with event
    function approve(address spender, uint256 amount) public {
        allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
    }

    /// @notice Transfer from with event
    function transferFrom(address from, address to, uint256 amount) public {
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");
        require(balances[from] >= amount, "Insufficient balance");

        allowances[from][msg.sender] -= amount;
        balances[from] -= amount;
        balances[to] += amount;

        emit Transfer(from, to, amount);
    }

    // =========================================================================
    // MINT AND BURN FUNCTIONS
    // =========================================================================

    /// @notice Mint tokens with event
    function mint(address to, uint256 amount) public {
        require(to != address(0), "Invalid address");
        require(amount > 0, "Amount must be positive");

        totalSupply += amount;
        balances[to] += amount;

        emit TokenMinted(to, amount);
        emit LogUint(totalSupply);
    }

    /// @notice Burn tokens with event
    function burn(uint256 amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(amount > 0, "Amount must be positive");

        balances[msg.sender] -= amount;
        totalSupply -= amount;

        emit TokenBurned(msg.sender, amount);
        emit LogUint(totalSupply);
    }

    // =========================================================================
    // USER REGISTRATION
    // =========================================================================

    /// @notice Register user with event
    function registerUser(string memory name, uint256 age) public {
        require(!registeredUsers[msg.sender], "Already registered");
        require(bytes(name).length > 0, "Name cannot be empty");
        require(age > 0, "Invalid age");

        registeredUsers[msg.sender] = true;

        emit UserRegistered(msg.sender, name, age, block.timestamp);
        emit Log(string(abi.encodePacked("User registered: ", name)));
    }

    // =========================================================================
    // ORDER FUNCTIONS
    // =========================================================================

    struct Order {
        uint256 id;
        address buyer;
        address seller;
        uint256 amount;
        string status;
        uint256 createdAt;
    }

    mapping(uint256 => Order) public orders;

    /// @notice Create order with event
    function createOrder(address seller, uint256 amount) public {
        require(seller != address(0), "Invalid seller");
        require(amount > 0, "Amount must be positive");

        orderCounter++;
        uint256 orderId = orderCounter;

        orders[orderId] = Order({
            id: orderId,
            buyer: msg.sender,
            seller: seller,
            amount: amount,
            status: "Created",
            createdAt: block.timestamp
        });

        emit OrderCreated(orderId, msg.sender, seller, amount, "Created");
        emit LogUint(orderId);
    }

    /// @notice Update order status with event
    function updateOrderStatus(uint256 orderId, string memory status) public {
        require(orders[orderId].buyer == msg.sender || orders[orderId].seller == msg.sender,
            "Not authorized");
        require(bytes(status).length > 0, "Invalid status");

        orders[orderId].status = status;

        emit Log(string(abi.encodePacked("Order ", orderId, " updated to: ", status)));
    }

    // =========================================================================
    // LOGGING FUNCTIONS
    // =========================================================================

    /// @notice Log various data types
    function logData(string memory message, uint256 value, address addr, bool flag) public {
        emit Log(message);
        emit LogUint(value);
        emit LogAddress(addr);
        emit LogBool(flag);
    }

    /// @notice Log with bytes data
    function logBytesData(bytes memory data) public {
        emit LogBytes(data);
    }

    // =========================================================================
    // EVENT INDEXING EXPLANATION
    // =========================================================================

    /// @dev Explain event indexing
    function explainIndexing() public pure returns (string memory) {
        return "Indexed parameters (with 'indexed') can be searched in event logs";
    }

    // =========================================================================
    // RECEIVE AND FALLBACK WITH EVENTS
    // =========================================================================

    event ReceivedEth(address indexed sender, uint256 amount);
    event FallbackCalled(address indexed sender, uint256 amount, bytes data);

    /// @notice Handle incoming ETH with event
    receive() external payable {
        require(msg.value > 0, "Must send ETH");
        emit ReceivedEth(msg.sender, msg.value);
        emit LogUint(msg.value);
    }

    /// @notice Fallback function with event
    fallback() external payable {
        if (msg.value > 0) {
            emit ReceivedEth(msg.sender, msg.value);
        }
        emit FallbackCalled(msg.sender, msg.value, msg.data);
    }

    // =========================================================================
    // EVENT EXAMPLES
    // =========================================================================

    /// @notice Demonstrate different event types
    function demonstrateEvents() public {
        // Simple logging
        emit Log("Demonstration started");

        // Log with values
        emit LogUint(block.timestamp);
        emit LogAddress(msg.sender);

        // Transfer event
        emit Transfer(address(0), msg.sender, 100);

        // Approval event
        emit Approval(msg.sender, address(0x123), 50);

        // User registration event
        emit UserRegistered(msg.sender, "Demo User", 25, block.timestamp);

        // Full indexed event
        emit FullIndexedEvent(msg.sender, address(0x123), 42);

        // Anonymous event
        emit AnonymousEvent(msg.sender);

        emit Log("Demonstration completed");
    }

    // =========================================================================
    // MODIFIER WITH EVENTS
    // =========================================================================

    modifier onlyRegistered() {
        require(registeredUsers[msg.sender], "User not registered");
        _;
    }

    /// @notice Function with modifier and event
    function registeredOnlyFunction() public onlyRegistered {
        emit Log("Registered user called function");
    }

    // =========================================================================
    // REVERT WITH EVENTS
    // =========================================================================

    /// @notice Function that reverts but emits event before
    function functionWithRevert() public pure {
        emit Log("About to revert");
        revert("Intentional revert");
    }

    // =========================================================================
    // EVENT BEST PRACTICES
    // =========================================================================

    /// @dev Best practices for events
    function eventBestPractices() public pure returns (string memory) {
        return "
            BEST PRACTICES:
            1. Use indexed for searchable parameters (max 3)
            2. Keep event names descriptive
            3. Include relevant data
            4. Emit events before state changes
            5. Use events for off-chain monitoring
            6. Consider gas costs for indexed parameters
        ";
    }
}

// =========================================================================
// EVENT INHERITANCE
// =========================================================================

/**
 * @title EventInheritance
 * @dev Demonstrates event inheritance
 */
contract EventInheritance is SolidityEvents {
    // Additional events
    event NewEvent(string data);

    /// @notice Inherited event usage
    function useInheritedEvent() public {
        emit NewEvent("From inherited contract");
        emit Log("Inherited contract called");
    }

    /// @notice Override event
    function demonstrateEvents() public override {
        emit Log("Overridden event demonstration");
        emit NewEvent("Custom event from override");
        super.demonstrateEvents();
    }
}

Errors

Errors in Solidity are used to handle exceptional conditions and revert transactions. They can be defined as custom errors for better gas efficiency and readability.

Error Types:

TypeDescriptionGas CostUse Case
requireCheck condition, revert if falseMediumInput validation
revertExplicit revertMediumComplex conditions
assertCheck internal invariantHighBug detection
CustomUser-defined errorsLowFrequent errors

Real-World Example – Token Transfer:

  • require for balance check
  • require for address validation
  • require for amount check

Code Example – Errors:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityErrors
 * @dev Comprehensive demonstration of error handling in Solidity
 */
contract SolidityErrors {
    // =========================================================================
    // CUSTOM ERROR DEFINITIONS
    // =========================================================================

    // -------- ERRORS WITH NO PARAMETERS --------
    error InsufficientBalance();
    error InvalidAddress();
    error ZeroAmount();
    error NotAuthorized();
    error ContractPaused();

    // -------- ERRORS WITH PARAMETERS --------
    error BalanceTooLow(uint256 requested, uint256 available);
    error AddressInvalid(address addr);
    error AmountTooSmall(uint256 minAmount, uint256 provided);
    error AmountTooLarge(uint256 maxAmount, uint256 provided);

    // -------- COMPLEX ERRORS --------
    error TransferFailed(address from, address to, uint256 amount, string reason);
    error Unauthorized(address caller, address expected);
    error OrderNotFound(uint256 orderId);
    error OrderAlreadyProcessed(uint256 orderId);

    // -------- NESTED ERROR --------
    error ValidationFailed(string[] reasons);

    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    mapping(address => uint256) public balances;
    address public owner;
    bool public paused;
    mapping(uint256 => bool) public processedOrders;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        owner = msg.sender;
        paused = false;
    }

    // =========================================================================
    // REQUIRE STATEMENTS (String error messages)
    // =========================================================================

    /// @notice Deposit with require
    function deposit() public payable {
        // Traditional require with error message
        require(msg.value > 0, "Amount must be greater than zero");
        require(msg.value >= 100, "Minimum deposit is 100 wei");
        require(!paused, "Contract is paused");

        balances[msg.sender] += msg.value;
    }

    /// @notice Withdraw with require
    function withdraw(uint256 amount) public {
        require(amount > 0, "Amount must be > 0");
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(amount <= address(this).balance, "Contract has insufficient funds");
        require(!paused, "Contract is paused");

        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }

    // =========================================================================
    // CUSTOM ERRORS (Gas efficient)
    // =========================================================================

    /// @notice Transfer with custom errors
    function transfer(address to, uint256 amount) public {
        // Using custom errors (no string storage, cheaper gas)
        if (balances[msg.sender] < amount) {
            revert BalanceTooLow(amount, balances[msg.sender]);
        }

        if (to == address(0)) {
            revert AddressInvalid(to);
        }

        if (amount == 0) {
            revert ZeroAmount();
        }

        if (paused) {
            revert ContractPaused();
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    /// @notice Transfer with custom error checking
    function transferWithValidation(address to, uint256 amount) public {
        if (balances[msg.sender] < amount) {
            revert BalanceTooLow(amount, balances[msg.sender]);
        }

        if (to == address(0)) {
            revert AddressInvalid(to);
        }

        if (amount < 100) {
            revert AmountTooSmall(100, amount);
        }

        if (amount > 100000) {
            revert AmountTooLarge(100000, amount);
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // ERROR WITH REASON
    // =========================================================================

    /// @notice Safe transfer with detailed error
    function safeTransfer(address to, uint256 amount) public {
        if (balances[msg.sender] < amount) {
            revert TransferFailed({
                from: msg.sender,
                to: to,
                amount: amount,
                reason: "Insufficient balance"
            });
        }

        if (to == address(0)) {
            revert TransferFailed({
                from: msg.sender,
                to: to,
                amount: amount,
                reason: "Invalid recipient address"
            });
        }

        if (paused) {
            revert TransferFailed({
                from: msg.sender,
                to: to,
                amount: amount,
                reason: "Contract is paused"
            });
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // AUTHORIZATION ERRORS
    // =========================================================================

    /// @notice Only owner modifier with custom error
    modifier onlyOwner() {
        if (msg.sender != owner) {
            revert Unauthorized(msg.sender, owner);
        }
        _;
    }

    /// @notice Only when not paused
    modifier whenNotPaused() {
        if (paused) {
            revert ContractPaused();
        }
        _;
    }

    /// @notice Owner only function
    function ownerOnlyFunction() public onlyOwner {
        balances[owner] += 100;
    }

    /// @notice Owner only with pause check
    function ownerOnlyWhenActive() public onlyOwner whenNotPaused {
        // Only owner and contract not paused
    }

    // =========================================================================
    // ASSERT (Internal invariants)
    // =========================================================================

    /// @notice Check invariants with assert
    function invariantCheck() public view {
        // Assert for internal invariants (should never fail)
        assert(balances[address(this)] >= 0);
        assert(balances[owner] <= address(this).balance);
        assert(owner != address(0));
    }

    /// @notice Function with assert
    function processValue(uint256 value) public pure returns (uint256) {
        // Assert for debugging
        assert(value > 0);
        assert(value < 1000);
        return value * 2;
    }

    // =========================================================================
    // COMPLEX VALIDATION
    // =========================================================================

    /// @notice Transfer with multiple conditions
    function transferWithConditions(
        address to,
        uint256 amount,
        bool requireApproval,
        address approver
    ) public {
        // Complex validation with multiple checks
        if (balances[msg.sender] < amount) {
            revert BalanceTooLow(amount, balances[msg.sender]);
        }

        if (to == address(0)) {
            revert AddressInvalid(to);
        }

        if (amount < 100) {
            revert AmountTooSmall(100, amount);
        }

        if (amount > 100000) {
            revert AmountTooLarge(100000, amount);
        }

        if (paused) {
            revert ContractPaused();
        }

        if (requireApproval && approver != owner) {
            revert Unauthorized(approver, owner);
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // ORDER ERRORS
    // =========================================================================

    struct Order {
        uint256 id;
        address buyer;
        uint256 amount;
        bool processed;
    }

    mapping(uint256 => Order) public orders;
    uint256 public orderCounter;

    /// @notice Create order
    function createOrder(uint256 amount) public {
        require(amount > 0, "Amount must be positive");
        require(!paused, "Contract is paused");

        orderCounter++;
        orders[orderCounter] = Order(orderCounter, msg.sender, amount, false);
    }

    /// @notice Process order with error handling
    function processOrder(uint256 orderId) public {
        Order storage order = orders[orderId];

        if (order.id == 0) {
            revert OrderNotFound(orderId);
        }

        if (order.processed) {
            revert OrderAlreadyProcessed(orderId);
        }

        if (order.buyer != msg.sender && msg.sender != owner) {
            revert Unauthorized(msg.sender, order.buyer);
        }

        if (balances[order.buyer] < order.amount) {
            revert BalanceTooLow(order.amount, balances[order.buyer]);
        }

        // Process order
        order.processed = true;
        balances[order.buyer] -= order.amount;
    }

    // =========================================================================
    // TRY/CATCH (Solidity 0.8.0+)
    // =========================================================================

    /// @dev Example of try/catch with external calls
    function tryExternalCall(address contractAddr, bytes memory data) public {
        // Try external call with catch
        (bool success, bytes memory returnData) = contractAddr.call(data);
        if (!success) {
            // Handle failure
            require(false, "External call failed");
        }
    }

    // =========================================================================
    // NESTED ERROR
    // =========================================================================

    /// @notice Validate with multiple conditions
    function validateMultiple(
        address user,
        uint256 amount,
        bool isVerified
    ) public pure {
        string[] memory reasons = new string[](3);
        uint256 reasonCount = 0;

        if (user == address(0)) {
            reasons[reasonCount] = "Invalid user address";
            reasonCount++;
        }

        if (amount == 0) {
            reasons[reasonCount] = "Amount cannot be zero";
            reasonCount++;
        }

        if (!isVerified) {
            reasons[reasonCount] = "User not verified";
            reasonCount++;
        }

        if (reasonCount > 0) {
            // Truncate array to actual length
            string[] memory actualReasons = new string[](reasonCount);
            for (uint256 i = 0; i < reasonCount; i++) {
                actualReasons[i] = reasons[i];
            }
            revert ValidationFailed(actualReasons);
        }
    }

    // =========================================================================
    // EVENTS FOR ERROR TRACKING
    // =========================================================================

    event ErrorOccurred(string errorType, string message);
    event TransferFailedEvent(address indexed from, address indexed to, uint256 amount);

    /// @notice Function with error events
    function transferWithErrorLogging(address to, uint256 amount) public {
        if (balances[msg.sender] < amount) {
            emit TransferFailedEvent(msg.sender, to, amount);
            emit ErrorOccurred("TransferFailed", "Insufficient balance");
            revert BalanceTooLow(amount, balances[msg.sender]);
        }

        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // MODIFIER WITH ERRORS
    // =========================================================================

    modifier validateAddress(address addr) {
        if (addr == address(0)) {
            revert AddressInvalid(addr);
        }
        _;
    }

    modifier validateAmount(uint256 amount, uint256 min, uint256 max) {
        if (amount < min) {
            revert AmountTooSmall(min, amount);
        }
        if (amount > max) {
            revert AmountTooLarge(max, amount);
        }
        _;
    }

    /// @notice Function with validation modifiers
    function transferWithModifiers(
        address to,
        uint256 amount
    )
        public
        validateAddress(to)
        validateAmount(amount, 100, 100000)
        whenNotPaused
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // SETTERS FOR STATE
    // =========================================================================

    function setPaused(bool paused_) public onlyOwner {
        paused = paused_;
    }

    function changeOwner(address newOwner) public onlyOwner {
        if (newOwner == address(0)) {
            revert AddressInvalid(newOwner);
        }
        owner = newOwner;
    }
}

// =========================================================================
// INHERITANCE WITH ERRORS
// =========================================================================

/**
 * @title ErrorInheritance
 * @dev Error handling in inherited contracts
 */
contract ErrorInheritance is SolidityErrors {
    // Inherited error definitions are available

    /// @notice Child function using parent errors
    function childFunction(uint256 amount) public view {
        if (balances[msg.sender] < amount) {
            revert BalanceTooLow(amount, balances[msg.sender]);
        }
    }

    /// @notice Child custom error
    error ChildError(string message);

    function childErrorFunction() public pure {
        revert ChildError("Child contract error");
    }
}

Modifiers

Modifiers are reusable conditions that can be applied to functions. They are used to add pre-conditions, post-conditions, and security checks.

Modifier Characteristics:

CharacteristicDescription
ReusableApply to multiple functions
ComposableCan be combined
ReadableClean and clear code
SecurityEnforce access control

Real-World Example – Only Owner:

modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
}
  • Applied to admin functions
  • Only owner can call
  • _; represents the function body

Code Example – Modifiers:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title SolidityModifiers
 * @dev Comprehensive demonstration of modifier usage in Solidity
 */
contract SolidityModifiers {
    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    address public owner;
    bool public paused;
    uint256 public minAmount = 100;
    uint256 public maxAmount = 10000;
    mapping(address => uint256) public balances;
    mapping(address => bool) public whitelist;
    mapping(address => bool) public blacklist;
    mapping(address => uint256) public userNonces;
    uint256 public transactionCount;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor() {
        owner = msg.sender;
        paused = false;
        whitelist[msg.sender] = true;
    }

    // =========================================================================
    // BASIC MODIFIERS
    // =========================================================================

    /// @dev Only owner can call
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }

    /// @dev Contract must not be paused
    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }

    /// @dev Contract must be paused
    modifier whenPaused() {
        require(paused, "Contract is not paused");
        _;
    }

    /// @dev Address must be whitelisted
    modifier onlyWhitelisted() {
        require(whitelist[msg.sender], "Address not whitelisted");
        _;
    }

    /// @dev Address must not be blacklisted
    modifier notBlacklisted() {
        require(!blacklist[msg.sender], "Address is blacklisted");
        _;
    }

    // =========================================================================
    // MODIFIERS WITH PARAMETERS
    // =========================================================================

    /// @dev Validate amount range
    modifier validAmount(uint256 amount) {
        require(amount > 0, "Amount must be > 0");
        require(amount >= minAmount, "Amount below minimum");
        require(amount <= maxAmount, "Amount above maximum");
        _;
    }

    /// @dev Validate address
    modifier validAddress(address addr) {
        require(addr != address(0), "Zero address not allowed");
        require(addr != address(this), "Cannot be contract address");
        _;
    }

    /// @dev Validate with custom min/max
    modifier validAmountRange(uint256 amount, uint256 min, uint256 max) {
        require(amount >= min, "Amount below minimum");
        require(amount <= max, "Amount above maximum");
        _;
    }

    /// @dev Validate timestamp (time lock)
    modifier onlyAfter(uint256 timestamp) {
        require(block.timestamp >= timestamp, "Time lock not expired");
        _;
    }

    /// @dev Validate caller is contract
    modifier onlyContract() {
        require(msg.sender == address(this), "Only contract can call");
        _;
    }

    // =========================================================================
    // COMBINED MODIFIERS
    // =========================================================================

    /// @dev Combined owner and paused check
    modifier onlyOwnerAndNotPaused() {
        require(msg.sender == owner, "Not owner");
        require(!paused, "Contract paused");
        _;
    }

    /// @dev Multiple validations
    modifier validCaller() {
        require(msg.sender != address(0), "Invalid caller");
        require(whitelist[msg.sender], "Not whitelisted");
        require(!blacklist[msg.sender], "Blacklisted");
        _;
    }

    // =========================================================================
    // MODIFIER INHERITANCE
    // =========================================================================

    /// @dev Modifier that can be overridden
    modifier virtualModifier() virtual {
        require(msg.sender != address(0), "Invalid caller");
        _;
    }

    // =========================================================================
    // ADMIN FUNCTIONS
    // =========================================================================

    function pauseContract() public onlyOwner {
        paused = true;
    }

    function unpauseContract() public onlyOwner {
        paused = false;
    }

    function setMinAmount(uint256 newMin) public onlyOwner {
        require(newMin > 0, "Minimum must be > 0");
        require(newMin < maxAmount, "Minimum must be less than maximum");
        minAmount = newMin;
    }

    function setMaxAmount(uint256 newMax) public onlyOwner {
        require(newMax > minAmount, "Maximum must be greater than minimum");
        maxAmount = newMax;
    }

    function addToWhitelist(address addr) public onlyOwner {
        require(addr != address(0), "Invalid address");
        whitelist[addr] = true;
    }

    function removeFromWhitelist(address addr) public onlyOwner {
        whitelist[addr] = false;
    }

    function addToBlacklist(address addr) public onlyOwner {
        require(addr != address(0), "Invalid address");
        blacklist[addr] = true;
    }

    function removeFromBlacklist(address addr) public onlyOwner {
        blacklist[addr] = false;
    }

    function changeOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        owner = newOwner;
    }

    // =========================================================================
    // USER FUNCTIONS
    // =========================================================================

    /// @notice Deposit with modifiers
    function deposit() public payable whenNotPaused notBlacklisted {
        require(msg.value > 0, "Amount must be > 0");
        require(msg.value >= minAmount, "Amount below minimum");
        balances[msg.sender] += msg.value;
        transactionCount++;
    }

    /// @notice Withdraw with modifiers
    function withdraw(uint256 amount)
        public
        whenNotPaused
        notBlacklisted
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
        transactionCount++;
    }

    /// @notice Transfer with multiple modifiers
    function transfer(address to, uint256 amount)
        public
        whenNotPaused
        notBlacklisted
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;
    }

    /// @notice Transfer with whitelist
    function transferWhitelisted(address to, uint256 amount)
        public
        whenNotPaused
        onlyWhitelisted
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;
    }

    // =========================================================================
    // MODIFIER WITH LOGIC BEFORE AND AFTER
    // =========================================================================

    /// @dev Modifier with pre and post execution
    modifier beforeAndAfter() {
        // Before function execution
        require(whitelist[msg.sender], "Not whitelisted");
        uint256 beforeBalance = balances[msg.sender];

        _; // Execute function

        // After function execution
        require(balances[msg.sender] >= 0, "Balance error");
        require(balances[msg.sender] <= beforeBalance, "Balance should not increase");
    }

    /// @dev Function using before/after modifier
    function specialTransfer(address to, uint256 amount)
        public
        beforeAndAfter
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // MODIFIER WITH PARAMETER PASSING
    // =========================================================================

    /// @dev Modifier that passes parameter to function
    modifier withNonce(uint256 nonce) {
        require(nonce == userNonces[msg.sender], "Invalid nonce");
        userNonces[msg.sender]++;
        _;
    }

    /// @dev Function with nonce modifier
    function transferWithNonce(address to, uint256 amount, uint256 nonce)
        public
        withNonce(nonce)
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // MODIFIER REUSE
    // =========================================================================

    /// @dev Combined validation modifier
    modifier validateTransaction(address to, uint256 amount) {
        require(to != address(0), "Invalid address");
        require(amount > 0, "Invalid amount");
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(!paused, "Contract paused");
        require(!blacklist[msg.sender], "Blacklisted");
        _;
    }

    /// @dev Function with combined modifier
    function validatedTransfer(address to, uint256 amount)
        public
        validateTransaction(to, amount)
    {
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;
    }

    // =========================================================================
    // MODIFIER STACKING
    // =========================================================================

    /// @dev Function with stacked modifiers
    function stackedTransfer(address to, uint256 amount)
        public
        whenNotPaused
        onlyWhitelisted
        notBlacklisted
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;
    }

    // =========================================================================
    // EVENTS
    // =========================================================================

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event BalanceUpdated(address indexed user, uint256 newBalance);

    /// @dev Transfer with events
    function transferWithEvents(address to, uint256 amount)
        public
        whenNotPaused
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;

        emit Transfer(msg.sender, to, amount);
        emit BalanceUpdated(msg.sender, balances[msg.sender]);
        emit BalanceUpdated(to, balances[to]);
    }

    // =========================================================================
    // MODIFIER WITH INHERITANCE
    // =========================================================================

    /// @dev Virtual modifier for inheritance
    modifier virtualModifier() virtual {
        require(msg.sender != address(0), "Invalid caller");
        _;
    }
}

// =========================================================================
// INHERITANCE WITH MODIFIERS
// =========================================================================

/**
 * @title ModifierInheritance
 * @dev Inherits modifiers from parent
 */
contract ModifierInheritance is SolidityModifiers {
    // Inherited modifiers are available

    /// @dev Override virtual modifier
    modifier virtualModifier() override {
        require(whitelist[msg.sender], "Not whitelisted");
        _;
    }

    /// @dev Child function with inherited modifiers
    function childAdminAction() public onlyOwner {
        // Can use parent's modifiers
        balances[owner] += 100;
    }

    /// @dev Child function with custom modifier
    modifier childOnly() {
        require(msg.sender != address(0), "Invalid caller");
        _;
    }

    function childFunction() public childOnly {
        // Custom modifier logic
    }

    /// @dev Override parent function
    function transfer(address to, uint256 amount)
        public
        override
        whenNotPaused
        validAddress(to)
        validAmount(amount)
    {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        transactionCount++;

        emit Transfer(msg.sender, to, amount);
    }

    /// @dev Additional child function
    function childTransfer(address to, uint256 amount)
        public
        onlyWhitelisted
        validAddress(to)
        validAmount(amount)
    {
        // Uses inherited modifiers
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    // =========================================================================
    // MULTIPLE INHERITANCE WITH MODIFIERS
    // =========================================================================

    /// @dev Get all balances
    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    /// @dev Get transaction count
    function getTransactionCount() public view returns (uint256) {
        return transactionCount;
    }
}

Libraries

Libraries are contracts that contain reusable code. They are deployed once and can be used by multiple contracts.

Library Characteristics:

CharacteristicDescription
ReusableShare code across contracts
StatelessCannot hold state variables
View/PureFunctions are view or pure
Gas EfficientReduces code duplication

Real-World Example – Math Library:

library Math {
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }
}
  • Reusable mathematical functions
  • Pure functions (no state access)
  • Used via using Math for uint256

Code Example – Libraries:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// LIBRARY: SafeMath
// ============================================================================

/**
 * @title SafeMath
 * @dev Safe mathematical operations (Solidity 0.8.0+ has built-in overflow checks)
 * This is for demonstration of library patterns
 */
library SafeMath {
    // -------- ADDITION --------
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    // -------- SUBTRACTION --------
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction underflow");
        return a - b;
    }

    // -------- MULTIPLICATION --------
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    // -------- DIVISION --------
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    // -------- MODULO --------
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }

    // -------- POWER --------
    function pow(uint256 base, uint256 exponent) internal pure returns (uint256) {
        uint256 result = 1;
        for (uint256 i = 0; i < exponent; i++) {
            result = mul(result, base);
        }
        return result;
    }
}

// ============================================================================
// LIBRARY: MathUtils
// ============================================================================

/**
 * @title MathUtils
 * @dev Additional mathematical utilities
 */
library MathUtils {
    // -------- MAXIMUM --------
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    function max(uint256 a, uint256 b, uint256 c) internal pure returns (uint256) {
        uint256 maxVal = a > b ? a : b;
        return maxVal > c ? maxVal : c;
    }

    // -------- MINIMUM --------
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    function min(uint256 a, uint256 b, uint256 c) internal pure returns (uint256) {
        uint256 minVal = a < b ? a : b;
        return minVal < c ? minVal : c;
    }

    // -------- AVERAGE --------
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        return (a + b) / 2;
    }

    // -------- IS EVEN --------
    function isEven(uint256 value) internal pure returns (bool) {
        return value % 2 == 0;
    }

    // -------- IS ODD --------
    function isOdd(uint256 value) internal pure returns (bool) {
        return value % 2 != 0;
    }

    // -------- ABSOLUTE DIFFERENCE --------
    function absDiff(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a - b : b - a;
    }

    // -------- FACTORIAL --------
    function factorial(uint256 n) internal pure returns (uint256) {
        if (n <= 1) return 1;
        return mul(n, factorial(n - 1));
    }
}

// ============================================================================
// LIBRARY: StringUtils
// ============================================================================

/**
 * @title StringUtils
 * @dev String utilities
 */
library StringUtils {
    // -------- COMPARE --------
    function compare(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
    }

    // -------- IS EMPTY --------
    function isEmpty(string memory str) internal pure returns (bool) {
        return bytes(str).length == 0;
    }

    // -------- LENGTH --------
    function length(string memory str) internal pure returns (uint256) {
        return bytes(str).length;
    }

    // -------- CONCATENATE --------
    function concat(string memory a, string memory b) internal pure returns (string memory) {
        return string(abi.encodePacked(a, b));
    }

    // -------- SUBSTRING --------
    function substring(string memory str, uint256 start, uint256 end) internal pure returns (string memory) {
        bytes memory strBytes = bytes(str);
        require(start <= end, "Invalid range");
        require(end <= strBytes.length, "End out of bounds");

        bytes memory result = new bytes(end - start);
        for (uint256 i = start; i < end; i++) {
            result[i - start] = strBytes[i];
        }
        return string(result);
    }

    // -------- TO UPPER --------
    function toUpper(string memory str) internal pure returns (string memory) {
        bytes memory b = bytes(str);
        for (uint256 i = 0; i < b.length; i++) {
            if (b[i] >= 0x61 && b[i] <= 0x7A) {
                b[i] = bytes1(uint8(b[i]) - 32);
            }
        }
        return string(b);
    }

    // -------- TO LOWER --------
    function toLower(string memory str) internal pure returns (string memory) {
        bytes memory b = bytes(str);
        for (uint256 i = 0; i < b.length; i++) {
            if (b[i] >= 0x41 && b[i] <= 0x5A) {
                b[i] = bytes1(uint8(b[i]) + 32);
            }
        }
        return string(b);
    }
}

// ============================================================================
// LIBRARY: ArrayUtils
// ============================================================================

/**
 * @title ArrayUtils
 * @dev Array utilities
 */
library ArrayUtils {
    // -------- SUM --------
    function sum(uint256[] memory arr) internal pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    // -------- SUM WITH SAFEMATH --------
    function sumSafe(uint256[] memory arr) internal pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            total = SafeMath.add(total, arr[i]);
        }
        return total;
    }

    // -------- CONTAINS --------
    function contains(uint256[] memory arr, uint256 value) internal pure returns (bool) {
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] == value) return true;
        }
        return false;
    }

    // -------- CONTAINS (address) --------
    function contains(address[] memory arr, address value) internal pure returns (bool) {
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] == value) return true;
        }
        return false;
    }

    // -------- INDEX OF --------
    function indexOf(uint256[] memory arr, uint256 value) internal pure returns (int256) {
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] == value) return int256(i);
        }
        return -1;
    }

    // -------- UNIQUE --------
    function unique(uint256[] memory arr) internal pure returns (uint256[] memory) {
        uint256[] memory temp = new uint256[](arr.length);
        uint256 count = 0;

        for (uint256 i = 0; i < arr.length; i++) {
            bool duplicate = false;
            for (uint256 j = 0; j < count; j++) {
                if (temp[j] == arr[i]) {
                    duplicate = true;
                    break;
                }
            }
            if (!duplicate) {
                temp[count] = arr[i];
                count++;
            }
        }

        uint256[] memory result = new uint256[](count);
        for (uint256 i = 0; i < count; i++) {
            result[i] = temp[i];
        }
        return result;
    }

    // -------- REVERSE --------
    function reverse(uint256[] memory arr) internal pure returns (uint256[] memory) {
        uint256[] memory result = new uint256[](arr.length);
        for (uint256 i = 0; i < arr.length; i++) {
            result[i] = arr[arr.length - 1 - i];
        }
        return result;
    }

    // -------- SLICE --------
    function slice(uint256[] memory arr, uint256 start, uint256 end) internal pure returns (uint256[] memory) {
        require(start <= end, "Invalid range");
        require(end <= arr.length, "End out of bounds");

        uint256[] memory result = new uint256[](end - start);
        for (uint256 i = start; i < end; i++) {
            result[i - start] = arr[i];
        }
        return result;
    }
}

// ============================================================================
// LIBRARY: AddressUtils
// ============================================================================

/**
 * @title AddressUtils
 * @dev Address utilities
 */
library AddressUtils {
    // -------- IS CONTRACT --------
    function isContract(address addr) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(addr)
        }
        return size > 0;
    }

    // -------- IS ZERO --------
    function isZero(address addr) internal pure returns (bool) {
        return addr == address(0);
    }

    // -------- SEND VALUE --------
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Insufficient balance");
        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value");
    }

    // -------- FUNCTION CALL --------
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");
        (bool success, bytes memory returndata) = target.call(data);
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// ============================================================================
// CONTRACT: LibraryUsage
// ============================================================================

/**
 * @title LibraryUsage
 * @dev Demonstrates library usage in a contract
 */
contract LibraryUsage {
    // Using library functions
    using SafeMath for uint256;
    using MathUtils for uint256;
    using StringUtils for string;
    using ArrayUtils for uint256[];
    using AddressUtils for address;

    // =========================================================================
    // STATE VARIABLES
    // =========================================================================

    uint256 public totalSupply;
    mapping(address => uint256) public balances;
    string public name;
    string public symbol;
    uint256[] public numbers;
    address[] public users;

    // =========================================================================
    // CONSTRUCTOR
    // =========================================================================

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
        users.push(msg.sender);
    }

    // =========================================================================
    // FUNCTIONS USING SAFEMATH
    // =========================================================================

    /// @notice Mint with SafeMath
    function mint(address to, uint256 amount) public {
        totalSupply = totalSupply.add(amount);
        balances[to] = balances[to].add(amount);
    }

    /// @notice Burn with SafeMath
    function burn(address from, uint256 amount) public {
        require(balances[from] >= amount, "Insufficient balance");
        balances[from] = balances[from].sub(amount);
        totalSupply = totalSupply.sub(amount);
    }

    // =========================================================================
    // FUNCTIONS USING MATHUTILS
    // =========================================================================

    /// @notice Get max of two numbers
    function getMax(uint256 a, uint256 b) public pure returns (uint256) {
        return a.max(b);
    }

    /// @notice Get min of two numbers
    function getMin(uint256 a, uint256 b) public pure returns (uint256) {
        return a.min(b);
    }

    /// @notice Get average
    function getAverage(uint256 a, uint256 b) public pure returns (uint256) {
        return a.average(b);
    }

    /// @notice Check if number is even
    function isEvenNumber(uint256 value) public pure returns (bool) {
        return value.isEven();
    }

    // =========================================================================
    // FUNCTIONS USING STRINGUTILS
    // =========================================================================

    /// @notice Set name with validation
    function setName(string memory _name) public {
        require(!_name.isEmpty(), "Name cannot be empty");
        require(_name.length() <= 32, "Name too long");
        name = _name;
    }

    /// @notice Compare names
    function compareName(string memory _test) public view returns (bool) {
        return name.compare(_test);
    }

    /// @notice Concatenate strings
    function concatStrings(string memory a, string memory b) public pure returns (string memory) {
        return a.concat(b);
    }

    // =========================================================================
    // FUNCTIONS USING ARRAYUTILS
    // =========================================================================

    /// @notice Add number to array
    function addNumber(uint256 num) public {
        numbers.push(num);
    }

    /// @notice Get array sum
    function getSum() public view returns (uint256) {
        return numbers.sum();
    }

    /// @notice Check if number exists
    function checkNumber(uint256 num) public view returns (bool) {
        return numbers.contains(num);
    }

    /// @notice Get unique numbers
    function getUniqueNumbers() public view returns (uint256[] memory) {
        return numbers.unique();
    }

    /// @notice Add user
    function addUser(address user) public {
        require(!users.contains(user), "User already exists");
        users.push(user);
    }

    // =========================================================================
    // FUNCTIONS USING ADDRESSUTILS
    // =========================================================================

    /// @notice Check if address is contract
    function isContractAddress(address addr) public view returns (bool) {
        return addr.isContract();
    }

    /// @notice Check if address is zero
    function isZeroAddress(address addr) public pure returns (bool) {
        return addr.isZero();
    }

    // =========================================================================
    // LIBRARY WITH STRUCTS
    // =========================================================================

    struct User {
        address addr;
        string name;
        uint256 age;
        bool verified;
    }

    /// @notice Create user (library-style)
    function createUser(string memory _name, uint256 _age) public returns (User memory) {
        User memory user = User({
            addr: msg.sender,
            name: _name,
            age: _age,
            verified: false
        });
        return user;
    }

    /// @notice Verify user (library-style)
    function verifyUser(User memory user) public returns (User memory) {
        user.verified = true;
        return user;
    }
}

// ============================================================================
// LIBRARY WITH CUSTOM ERRORS
// ============================================================================

/**
 * @title ErrorLibrary
 * @dev Library with custom errors
 */
library ErrorLibrary {
    error InsufficientBalance(uint256 requested, uint256 available);
    error InvalidAddress(address addr);

    function checkBalance(uint256 requested, uint256 available) internal pure {
        if (available < requested) {
            revert InsufficientBalance(requested, available);
        }
    }

    function checkAddress(address addr) internal pure {
        if (addr == address(0)) {
            revert InvalidAddress(addr);
        }
    }
}

contract LibraryWithErrors {
    using ErrorLibrary for uint256;
    using ErrorLibrary for address;

    mapping(address => uint256) public balances;

    function transfer(address to, uint256 amount) public {
        balances[msg.sender].checkBalance(amount);
        to.checkAddress();
        // Transfer logic
    }
}

Interfaces

Interfaces define the function signatures that a contract must implement. They allow contracts to interact with each other without knowing the implementation.

Interface Characteristics:

CharacteristicDescription
Function SignaturesOnly function declarations
No ImplementationNo function bodies
No StateNo state variables
InheritanceContracts can inherit interfaces

Real-World Example – ERC-20 Interface:

interface IERC20 {
    // Returns the total number of tokens in circulation.
    function totalSupply() external view returns (uint256);

    // Returns the token balance of a specific address.
    function balanceOf(address owner) external view returns (uint256);

    // Transfers tokens from the caller to another address.
    function transfer(address to, uint256 amount) external returns (bool);
}
  • Defines required functions
  • Any token contract must implement these
  • Other contracts can interact with any ERC-20 token

Code Example – Interfaces:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC20
// ============================================================================

/**
 * @title IERC20
 * @dev ERC-20 token interface
 */
interface IERC20 {
    // -------- VIEW FUNCTIONS --------
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);

    // -------- STATE-CHANGING FUNCTIONS --------
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// ============================================================================
// INTERFACE: IERC721
// ============================================================================

/**
 * @title IERC721
 * @dev NFT interface
 */
interface IERC721 {
    // -------- VIEW FUNCTIONS --------
    function balanceOf(address owner) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function getApproved(uint256 tokenId) external view returns (address);
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    // -------- STATE-CHANGING FUNCTIONS --------
    function transferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function setApprovalForAll(address operator, bool approved) external;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
}

// ============================================================================
// INTERFACE: IERC1155
// ============================================================================

/**
 * @title IERC1155
 * @dev Multi-token interface
 */
interface IERC1155 {
    // -------- VIEW FUNCTIONS --------
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

    // -------- STATE-CHANGING FUNCTIONS --------
    function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;
    function setApprovalForAll(address operator, bool approved) external;

    // -------- EVENTS --------
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
    event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);
    event URI(string value, uint256 indexed id);
}

// ============================================================================
// INTERFACE: IUniswapV2Router
// ============================================================================

/**
 * @title IUniswapV2Router
 * @dev Uniswap V2 router interface
 */
interface IUniswapV2Router {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

// ============================================================================
// INTERFACE: IUniswapV3Router
// ============================================================================

/**
 * @title IUniswapV3Router
 * @dev Uniswap V3 router interface
 */
interface IUniswapV3Router {
    function exactInputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        address recipient,
        uint256 deadline,
        uint256 amountIn,
        uint256 amountOutMinimum,
        uint160 sqrtPriceLimitX96
    ) external payable returns (uint256 amountOut);

    function exactOutputSingle(
        address tokenIn,
        address tokenOut,
        uint24 fee,
        address recipient,
        uint256 deadline,
        uint256 amountOut,
        uint256 amountInMaximum,
        uint160 sqrtPriceLimitX96
    ) external payable returns (uint256 amountIn);
}

// ============================================================================
// INTERFACE: IERC20Metadata
// ============================================================================

/**
 * @title IERC20Metadata
 * @dev Extended ERC-20 interface with metadata
 */
interface IERC20Metadata is IERC20 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view returns (uint8);
}

// ============================================================================
// INTERFACE: IERC20Permit
// ============================================================================

/**
 * @title IERC20Permit
 * @dev ERC-20 permit interface (gasless approvals)
 */
interface IERC20Permit {
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    function nonces(address owner) external view returns (uint256);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// ============================================================================
// INTERFACE: IAccessControl
// ============================================================================

/**
 * @title IAccessControl
 * @dev Access control interface
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function renounceRole(bytes32 role, address account) external;

    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
}

// ============================================================================
// INTERFACE: IERC721Receiver
// ============================================================================

/**
 * @title IERC721Receiver
 * @dev NFT receiver interface
 */
interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// ============================================================================
// INTERFACE: IERC1155Receiver
// ============================================================================

/**
 * @title IERC1155Receiver
 * @dev ERC-1155 receiver interface
 */
interface IERC1155Receiver {
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// ============================================================================
// CONTRACT: InterfaceUsage
// ============================================================================

/**
 * @title InterfaceUsage
 * @dev Demonstrates interface usage in a contract
 */
contract InterfaceUsage {
    // -------- STATE VARIABLES --------
    IERC20 public token;
    IERC721 public nft;
    IUniswapV2Router public router;
    IAccessControl public accessControl;

    // -------- CONSTRUCTOR --------
    constructor(address _token, address _nft, address _router) {
        token = IERC20(_token);
        nft = IERC721(_nft);
        router = IUniswapV2Router(_router);
    }

    // =========================================================================
    // ERC-20 FUNCTIONS
    // =========================================================================

    function getTokenBalance(address owner) public view returns (uint256) {
        return token.balanceOf(owner);
    }

    function getTokenTotalSupply() public view returns (uint256) {
        return token.totalSupply();
    }

    function transferTokens(address to, uint256 amount) public returns (bool) {
        return token.transfer(to, amount);
    }

    function approveTokens(address spender, uint256 amount) public returns (bool) {
        return token.approve(spender, amount);
    }

    function transferFromTokens(address from, address to, uint256 amount) public returns (bool) {
        return token.transferFrom(from, to, amount);
    }

    // =========================================================================
    // ERC-721 FUNCTIONS
    // =========================================================================

    function getNFTBalance(address owner) public view returns (uint256) {
        return nft.balanceOf(owner);
    }

    function getNFTOwner(uint256 tokenId) public view returns (address) {
        return nft.ownerOf(tokenId);
    }

    function transferNFT(address from, address to, uint256 tokenId) public {
        nft.transferFrom(from, to, tokenId);
    }

    function approveNFT(address to, uint256 tokenId) public {
        nft.approve(to, tokenId);
    }

    // =========================================================================
    // UNISWAP FUNCTIONS
    // =========================================================================

    function swapETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        uint256 deadline
    ) public payable returns (uint256[] memory) {
        return router.swapExactETHForTokens{value: msg.value}(
            amountOutMin,
            path,
            msg.sender,
            deadline
        );
    }

    function swapTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        uint256 deadline
    ) public returns (uint256[] memory) {
        return router.swapExactTokensForETH(
            amountIn,
            amountOutMin,
            path,
            msg.sender,
            deadline
        );
    }

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        uint256 deadline
    ) public returns (uint256, uint256, uint256) {
        return router.addLiquidity(
            tokenA,
            tokenB,
            amountADesired,
            amountBDesired,
            amountAMin,
            amountBMin,
            msg.sender,
            deadline
        );
    }

    // =========================================================================
    // ACCESS CONTROL FUNCTIONS
    // =========================================================================

    function setAccessControl(address _accessControl) public {
        accessControl = IAccessControl(_accessControl);
    }

    function checkRole(bytes32 role, address account) public view returns (bool) {
        return accessControl.hasRole(role, account);
    }

    // =========================================================================
    // INTERFACE INHERITANCE
    // =========================================================================

    // Multiple interfaces can be inherited
    interface IAdvancedToken is IERC20, IERC721 {
        function advancedFunction() external returns (bool);
    }
}

// ============================================================================
// CONTRACT: InterfaceImplementation
// ============================================================================

/**
 * @title InterfaceImplementation
 * @dev Implements the IERC20 interface
 */
contract InterfaceImplementation is IERC20 {
    // -------- STATE VARIABLES --------
    string public override name = "My Token";
    string public override symbol = "MTK";
    uint8 public override decimals = 18;
    uint256 public override totalSupply;

    mapping(address => uint256) public balances;
    mapping(address => mapping(address => uint256)) public allowances;

    // -------- CONSTRUCTOR --------
    constructor(uint256 initialSupply) {
        totalSupply = initialSupply * 10**decimals;
        balances[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    // -------- VIEW FUNCTIONS --------
    function balanceOf(address owner) public view override returns (uint256) {
        return balances[owner];
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return allowances[owner][spender];
    }

    // -------- STATE-CHANGING FUNCTIONS --------
    function transfer(address to, uint256 amount) public override returns (bool) {
        require(to != address(0), "Invalid recipient");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;

        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        require(spender != address(0), "Invalid spender");
        allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
        require(from != address(0), "Invalid sender");
        require(to != address(0), "Invalid recipient");
        require(balances[from] >= amount, "Insufficient balance");
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");

        balances[from] -= amount;
        balances[to] += amount;
        allowances[from][msg.sender] -= amount;

        emit Transfer(from, to, amount);
        return true;
    }
}

// ============================================================================
// CONTRACT: MultiInterfaceImplementation
// ============================================================================

/**
 * @title MultiInterfaceImplementation
 * @dev Implements multiple interfaces
 */
contract MultiInterfaceImplementation is IERC20, IERC721Receiver, IERC1155Receiver {
    // IERC721Receiver implementation
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external override returns (bytes4) {
        return this.onERC721Received.selector;
    }

    // IERC1155Receiver implementation
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }

    // IERC20 implementation
    string public override name = "Multi Token";
    string public override symbol = "MTK";
    uint8 public override decimals = 18;
    uint256 public override totalSupply;

    mapping(address => uint256) public balances;
    mapping(address => mapping(address => uint256)) public allowances;

    // IERC20 functions...
    function balanceOf(address owner) public view override returns (uint256) {
        return balances[owner];
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return allowances[owner][spender];
    }

    function transfer(address to, uint256 amount) public override returns (bool) {
        // Implementation
        return true;
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        // Implementation
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public override returns (bool) {
        // Implementation
        return true;
    }
}

Abstract Contracts

Abstract contracts are contracts that contain at least one function without an implementation. They can’t be deployed directly but can be inherited by other contracts.

Abstract Contract Characteristics:

CharacteristicDescription
Unimplemented FunctionsContains abstract functions
Cannot DeployCannot be deployed directly
Inheritance BaseMeant to be inherited
Partial ImplementationCan implement some functions

Real-World Example – ERC-20 Base:

abstract contract ERC20Base {
    function transfer(
        address to,
        uint256 amount
    ) public virtual returns (bool);
    // Unimplemented — must be implemented by a child contract.
}

Code Example – Abstract Contracts:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// ABSTRACT CONTRACT: AbstractToken
// ============================================================================

/**
 * @title AbstractToken
 * @dev Abstract contract for tokens with common functionality
 */
abstract contract AbstractToken {
    // -------- ABSTRACT FUNCTIONS (No implementation) --------
    function totalSupply() public virtual view returns (uint256);
    function balanceOf(address owner) public virtual view returns (uint256);
    function transfer(address to, uint256 amount) public virtual returns (bool);

    // -------- IMPLEMENTED FUNCTIONS (Can be used by children) --------
    string public name;
    string public symbol;
    uint8 public decimals;

    constructor(string memory _name, string memory _symbol, uint8 _decimals) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    // -------- COMMON UTILITY FUNCTIONS --------
    function _validateAddress(address addr) internal pure {
        require(addr != address(0), "Invalid address");
    }

    function _validateAmount(uint256 amount) internal pure {
        require(amount > 0, "Amount must be > 0");
    }

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
}

// ============================================================================
// ABSTRACT CONTRACT: AbstractAccessControl
// ============================================================================

/**
 * @title AbstractAccessControl
 * @dev Abstract contract for access control
 */
abstract contract AbstractAccessControl {
    address public owner;
    mapping(address => bool) public admins;

    constructor() {
        owner = msg.sender;
        admins[msg.sender] = true;
    }

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier onlyAdmin() {
        require(admins[msg.sender], "Not admin");
        _;
    }

    modifier onlyOwnerOrAdmin() {
        require(msg.sender == owner || admins[msg.sender], "Not authorized");
        _;
    }

    // -------- FUNCTIONS --------
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Invalid owner");
        owner = newOwner;
    }

    function addAdmin(address admin) public onlyOwner {
        require(admin != address(0), "Invalid address");
        admins[admin] = true;
    }

    function removeAdmin(address admin) public onlyOwner {
        admins[admin] = false;
    }

    function isAdmin(address account) public view returns (bool) {
        return admins[account];
    }
}

// ============================================================================
// ABSTRACT CONTRACT: AbstractPausable
// ============================================================================

/**
 * @title AbstractPausable
 * @dev Abstract contract for pausable functionality
 */
abstract contract AbstractPausable {
    bool public paused;

    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }

    modifier whenPaused() {
        require(paused, "Contract is not paused");
        _;
    }

    function pause() public virtual;
    function unpause() public virtual;

    event Paused(address indexed account);
    event Unpaused(address indexed account);
}

// ============================================================================
// ABSTRACT CONTRACT: AbstractTokenWithMint
// ============================================================================

/**
 * @title AbstractTokenWithMint
 * @dev Abstract token with minting and burning capabilities
 */
abstract contract AbstractTokenWithMint is AbstractToken, AbstractAccessControl {
    function mint(address to, uint256 amount) public virtual onlyOwner;
    function burn(address from, uint256 amount) public virtual onlyOwner;

    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed from, uint256 amount);
}

// ============================================================================
// ABSTRACT CONTRACT: AbstractTokenWithPause
// ============================================================================

/**
 * @title AbstractTokenWithPause
 * @dev Abstract token with pause functionality
 */
abstract contract AbstractTokenWithPause is AbstractToken, AbstractPausable {
    function transfer(address to, uint256 amount) public virtual override whenNotPaused returns (bool);
}

// ============================================================================
// ABSTRACT CONTRACT: AbstractERC20
// ============================================================================

/**
 * @title AbstractERC20
 * @dev Complete ERC-20 abstract implementation
 */
abstract contract AbstractERC20 is AbstractToken {
    mapping(address => mapping(address => uint256)) internal _allowances;

    function allowance(address owner, address spender) public virtual view returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        _validateAddress(spender);
        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
        _validateAddress(to);
        require(balanceOf(from) >= amount, "Insufficient balance");
        require(_allowances[from][msg.sender] >= amount, "Insufficient allowance");

        _allowances[from][msg.sender] -= amount;
        // Transfer logic in child contract
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _validateAddress(spender);
        _allowances[msg.sender][spender] += addedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _validateAddress(spender);
        require(_allowances[msg.sender][spender] >= subtractedValue, "Decreased allowance below zero");
        _allowances[msg.sender][spender] -= subtractedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }
}

// ============================================================================
// CONTRACT: MyToken
// ============================================================================

/**
 * @title MyToken
 * @dev Implements abstract contracts
 */
contract MyToken is AbstractTokenWithMint, AbstractERC20, AbstractPausable {
    // -------- STATE VARIABLES --------
    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) AbstractToken(_name, _symbol, _decimals) {
        _totalSupply = _initialSupply * 10**decimals;
        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    // -------- IMPLEMENT ABSTRACT FUNCTIONS --------
    function totalSupply() public override view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address owner) public override view returns (uint256) {
        return _balances[owner];
    }

    function transfer(address to, uint256 amount) public override(AbstractToken, AbstractTokenWithPause) whenNotPaused returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[msg.sender] >= amount, "Insufficient balance");

        _balances[msg.sender] -= amount;
        _balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public override whenNotPaused returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[from] >= amount, "Insufficient balance");
        require(_allowances[from][msg.sender] >= amount, "Insufficient allowance");

        _balances[from] -= amount;
        _balances[to] += amount;
        _allowances[from][msg.sender] -= amount;

        emit Transfer(from, to, amount);
        return true;
    }

    // -------- MINT AND BURN --------
    function mint(address to, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(to);
        _validateAmount(amount);

        _balances[to] += amount;
        _totalSupply += amount;
        emit Mint(to, amount);
        emit Transfer(address(0), to, amount);
    }

    function burn(address from, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(from);
        _validateAmount(amount);
        require(_balances[from] >= amount, "Insufficient balance");

        _balances[from] -= amount;
        _totalSupply -= amount;
        emit Burn(from, amount);
        emit Transfer(from, address(0), amount);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public override onlyOwner {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public override onlyOwner {
        paused = false;
        emit Unpaused(msg.sender);
    }

    // -------- HELPER FUNCTIONS --------
    function getBalances(address[] calldata addresses) public view returns (uint256[] memory) {
        uint256[] memory result = new uint256[](addresses.length);
        for (uint256 i = 0; i < addresses.length; i++) {
            result[i] = _balances[addresses[i]];
        }
        return result;
    }
}

// ============================================================================
// CONTRACT: AnotherToken
// ============================================================================

/**
 * @title AnotherToken
 * @dev Alternative implementation of abstract token
 */
contract AnotherToken is AbstractTokenWithMint, AbstractERC20, AbstractPausable {
    // -------- STATE VARIABLES --------
    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) AbstractToken(_name, _symbol, _decimals) {
        _totalSupply = _initialSupply * 10**decimals;
        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    // -------- IMPLEMENT ABSTRACT FUNCTIONS --------
    function totalSupply() public override view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address owner) public override view returns (uint256) {
        return _balances[owner];
    }

    function transfer(address to, uint256 amount) public override(AbstractToken, AbstractTokenWithPause) whenNotPaused returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[msg.sender] >= amount, "Insufficient balance");

        _balances[msg.sender] -= amount;
        _balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public override whenNotPaused returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[from] >= amount, "Insufficient balance");
        require(_allowances[from][msg.sender] >= amount, "Insufficient allowance");

        _balances[from] -= amount;
        _balances[to] += amount;
        _allowances[from][msg.sender] -= amount;

        emit Transfer(from, to, amount);
        return true;
    }

    // -------- MINT AND BURN --------
    function mint(address to, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(to);
        _validateAmount(amount);

        _balances[to] += amount;
        _totalSupply += amount;
        emit Mint(to, amount);
        emit Transfer(address(0), to, amount);
    }

    function burn(address from, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(from);
        _validateAmount(amount);
        require(_balances[from] >= amount, "Insufficient balance");

        _balances[from] -= amount;
        _totalSupply -= amount;
        emit Burn(from, amount);
        emit Transfer(from, address(0), amount);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public override onlyOwner {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public override onlyOwner {
        paused = false;
        emit Unpaused(msg.sender);
    }
}

// ============================================================================
// CONTRACT: DelegatedToken
// ============================================================================

/**
 * @title DelegatedToken
 * @dev Token with delegation of abstract functions
 */
contract DelegatedToken is AbstractToken {
    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) AbstractToken(_name, _symbol, _decimals) {}

    function totalSupply() public override view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address owner) public override view returns (uint256) {
        return _balances[owner];
    }

    function transfer(address to, uint256 amount) public override returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[msg.sender] >= amount, "Insufficient balance");

        _balances[msg.sender] -= amount;
        _balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    // Additional custom functions
    function setInitialSupply(uint256 supply) public {
        require(_totalSupply == 0, "Already initialized");
        _totalSupply = supply * 10**decimals;
        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    function getBalance(address owner) public view returns (uint256) {
        return _balances[owner];
    }
}

// ============================================================================
// CONTRACT: MultiAbstractInheritance
// ============================================================================

/**
 * @title MultiAbstractInheritance
 * @dev Demonstrates multiple abstract inheritance
 */
contract MultiAbstractInheritance is
    AbstractTokenWithMint,
    AbstractPausable,
    AbstractERC20
{
    uint256 private _totalSupply;
    mapping(address => uint256) private _balances;

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) AbstractToken(_name, _symbol, _decimals) {
        _totalSupply = _initialSupply * 10**decimals;
        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    function totalSupply() public override view returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address owner) public override view returns (uint256) {
        return _balances[owner];
    }

    function transfer(address to, uint256 amount) public override(AbstractToken, AbstractTokenWithPause) whenNotPaused returns (bool) {
        _validateAddress(to);
        _validateAmount(amount);
        require(_balances[msg.sender] >= amount, "Insufficient balance");

        _balances[msg.sender] -= amount;
        _balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function mint(address to, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(to);
        _validateAmount(amount);

        _balances[to] += amount;
        _totalSupply += amount;
        emit Mint(to, amount);
        emit Transfer(address(0), to, amount);
    }

    function burn(address from, uint256 amount) public override onlyOwner whenNotPaused {
        _validateAddress(from);
        _validateAmount(amount);
        require(_balances[from] >= amount, "Insufficient balance");

        _balances[from] -= amount;
        _totalSupply -= amount;
        emit Burn(from, amount);
        emit Transfer(from, address(0), amount);
    }

    function pause() public override onlyOwner {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public override onlyOwner {
        paused = false;
        emit Unpaused(msg.sender);
    }
}

Inheritance

Inheritance allows contracts to extend and reuse code from other contracts. It enables code reuse and building complex systems from simpler components.

Inheritance Characteristics:

CharacteristicDescription
Code ReuseInherit functions and state
ModularityBuild from smaller components
OverrideOverride inherited functions
MultipleInherit from multiple contracts

Real-World Example – Token Standard:

contract MyToken is ERC20, Ownable, Pausable {
    // Inherits from multiple standards
}

Code Example – Inheritance:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: Ownable
// ============================================================================

/**
 * @title Ownable
 * @dev Ownership management with two-step transfer
 */
contract Ownable {
    address public owner;
    address public pendingOwner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event OwnershipTransferRequested(address indexed from, address indexed to);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        pendingOwner = newOwner;
        emit OwnershipTransferRequested(msg.sender, newOwner);
    }

    function acceptOwnership() public {
        require(msg.sender == pendingOwner, "Not pending owner");
        address oldOwner = owner;
        owner = pendingOwner;
        pendingOwner = address(0);
        emit OwnershipTransferred(oldOwner, owner);
    }

    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(owner, address(0));
        owner = address(0);
    }

    function getOwner() public view returns (address) {
        return owner;
    }
}

// ============================================================================
// CONTRACT: Pausable
// ============================================================================

/**
 * @title Pausable
 * @dev Contract pause functionality
 */
contract Pausable {
    bool public paused;
    address public pauser;

    event Paused(address indexed account);
    event Unpaused(address indexed account);

    constructor() {
        pauser = msg.sender;
    }

    modifier whenNotPaused() {
        require(!paused, "Contract paused");
        _;
    }

    modifier whenPaused() {
        require(paused, "Contract not paused");
        _;
    }

    modifier onlyPauser() {
        require(msg.sender == pauser, "Not pauser");
        _;
    }

    function pause() public virtual onlyPauser {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public virtual onlyPauser {
        paused = false;
        emit Unpaused(msg.sender);
    }

    function setPauser(address newPauser) public onlyPauser {
        require(newPauser != address(0), "Invalid address");
        pauser = newPauser;
    }
}

// ============================================================================
// CONTRACT: Whitelist
// ============================================================================

/**
 * @title Whitelist
 * @dev Whitelist management
 */
contract Whitelist {
    mapping(address => bool) public isWhitelisted;
    address[] public whitelistedAddresses;
    uint256 public whitelistCount;

    event Whitelisted(address indexed account);
    event RemovedFromWhitelist(address indexed account);

    modifier onlyWhitelisted() {
        require(isWhitelisted[msg.sender], "Not whitelisted");
        _;
    }

    function addToWhitelist(address account) public virtual {
        require(account != address(0), "Invalid address");
        require(!isWhitelisted[account], "Already whitelisted");
        isWhitelisted[account] = true;
        whitelistedAddresses.push(account);
        whitelistCount++;
        emit Whitelisted(account);
    }

    function removeFromWhitelist(address account) public virtual {
        require(isWhitelisted[account], "Not whitelisted");
        isWhitelisted[account] = false;
        whitelistCount--;
        emit RemovedFromWhitelist(account);
    }

    function isWhitelistedAddress(address account) public view returns (bool) {
        return isWhitelisted[account];
    }

    function getWhitelistedAddresses() public view returns (address[] memory) {
        return whitelistedAddresses;
    }
}

// ============================================================================
// CONTRACT: Blacklist
// ============================================================================

/**
 * @title Blacklist
 * @dev Blacklist management
 */
contract Blacklist {
    mapping(address => bool) public isBlacklisted;

    event Blacklisted(address indexed account);
    event RemovedFromBlacklist(address indexed account);

    modifier notBlacklisted() {
        require(!isBlacklisted[msg.sender], "Address blacklisted");
        _;
    }

    function addToBlacklist(address account) public virtual {
        require(account != address(0), "Invalid address");
        require(!isBlacklisted[account], "Already blacklisted");
        isBlacklisted[account] = true;
        emit Blacklisted(account);
    }

    function removeFromBlacklist(address account) public virtual {
        require(isBlacklisted[account], "Not blacklisted");
        isBlacklisted[account] = false;
        emit RemovedFromBlacklist(account);
    }

    function isBlacklistedAddress(address account) public view returns (bool) {
        return isBlacklisted[account];
    }
}

// ============================================================================
// CONTRACT: SimpleToken
// ============================================================================

/**
 * @title SimpleToken
 * @dev Basic ERC-20 token implementation
 */
contract SimpleToken {
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    mapping(address => uint256) public balances;

    event Transfer(address indexed from, address indexed to, uint256 amount);

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _initialSupply * 10**decimals;
        balances[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        require(to != address(0), "Invalid address");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function balanceOf(address account) public view returns (uint256) {
        return balances[account];
    }

    function getBalance(address account) public view returns (uint256) {
        return balances[account];
    }
}

// ============================================================================
// CONTRACT: AdvancedToken
// ============================================================================

/**
 * @title AdvancedToken
 * @dev Inherits from multiple contracts
 */
contract AdvancedToken is SimpleToken, Ownable, Pausable, Whitelist, Blacklist {
    mapping(address => mapping(address => uint256)) public allowances;

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) SimpleToken(_name, _symbol, _decimals, _initialSupply) {
        // Ownable constructor runs automatically
        // Add deployer to whitelist
        isWhitelisted[msg.sender] = true;
        whitelistedAddresses.push(msg.sender);
        whitelistCount = 1;
    }

    // -------- OVERRIDDEN FUNCTIONS --------
    function transfer(address to, uint256 amount)
        public
        override
        whenNotPaused
        onlyWhitelisted
        notBlacklisted
        returns (bool)
    {
        return super.transfer(to, amount);
    }

    function pause() public override onlyOwner {
        super.pause();
    }

    function unpause() public override onlyOwner {
        super.unpause();
    }

    function addToWhitelist(address account) public override onlyOwner {
        super.addToWhitelist(account);
    }

    function removeFromWhitelist(address account) public override onlyOwner {
        super.removeFromWhitelist(account);
    }

    function addToBlacklist(address account) public override onlyOwner {
        super.addToBlacklist(account);
    }

    function removeFromBlacklist(address account) public override onlyOwner {
        super.removeFromBlacklist(account);
    }

    // -------- APPROVAL FUNCTIONS --------
    function approve(address spender, uint256 amount) public returns (bool) {
        require(spender != address(0), "Invalid spender");
        allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function allowance(address owner, address spender) public view returns (uint256) {
        return allowances[owner][spender];
    }

    function transferFrom(address from, address to, uint256 amount) public returns (bool) {
        require(from != address(0), "Invalid sender");
        require(to != address(0), "Invalid recipient");
        require(balances[from] >= amount, "Insufficient balance");
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");

        balances[from] -= amount;
        balances[to] += amount;
        allowances[from][msg.sender] -= amount;

        emit Transfer(from, to, amount);
        return true;
    }

    // -------- MINT AND BURN --------
    function mint(address to, uint256 amount) public onlyOwner {
        require(to != address(0), "Invalid address");
        require(amount > 0, "Amount must be > 0");

        totalSupply += amount;
        balances[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    function burn(address from, uint256 amount) public onlyOwner {
        require(from != address(0), "Invalid address");
        require(balances[from] >= amount, "Insufficient balance");

        balances[from] -= amount;
        totalSupply -= amount;
        emit Transfer(from, address(0), amount);
    }

    // -------- BATCH OPERATIONS --------
    function batchTransfer(address[] memory recipients, uint256[] memory amounts)
        public
        returns (bool)
    {
        require(recipients.length == amounts.length, "Arrays length mismatch");
        require(recipients.length > 0, "Empty arrays");

        for (uint256 i = 0; i < recipients.length; i++) {
            require(recipients[i] != address(0), "Invalid recipient");
            require(balances[msg.sender] >= amounts[i], "Insufficient balance");

            balances[msg.sender] -= amounts[i];
            balances[recipients[i]] += amounts[i];
            emit Transfer(msg.sender, recipients[i], amounts[i]);
        }
        return true;
    }

    // -------- VIEW FUNCTIONS --------
    function getTokenInfo() public view returns (
        string memory,
        string memory,
        uint8,
        uint256,
        address,
        bool
    ) {
        return (name, symbol, decimals, totalSupply, owner, paused);
    }

    function getBalances(address[] memory accounts) public view returns (uint256[] memory) {
        uint256[] memory result = new uint256[](accounts.length);
        for (uint256 i = 0; i < accounts.length; i++) {
            result[i] = balances[accounts[i]];
        }
        return result;
    }
}

// ============================================================================
// CONTRACT: MultiInheritance
// ============================================================================

/**
 * @title MultiInheritance
 * @dev Demonstrates multiple inheritance with complex hierarchy
 */
contract MultiInheritance is Ownable, Pausable, Whitelist, Blacklist {
    uint256 public version;

    // -------- CONSTRUCTOR --------
    constructor(uint256 _version) {
        version = _version;
        // Add deployer to whitelist
        isWhitelisted[msg.sender] = true;
        whitelistedAddresses.push(msg.sender);
        whitelistCount = 1;
    }

    // -------- COMBINED FUNCTIONS --------
    function combinedAction() public onlyOwner whenNotPaused onlyWhitelisted notBlacklisted {
        // Can combine all modifiers
        // This function can only be called by:
        // 1. Owner
        // 2. When contract is not paused
        // 3. Address is whitelisted
        // 4. Address is not blacklisted
    }

    function adminAction() public onlyOwner {
        // Owner only action
    }

    function userAction() public whenNotPaused onlyWhitelisted notBlacklisted {
        // User action with multiple checks
    }

    // -------- OVERRIDE PAUSE --------
    function pause() public override onlyOwner {
        super.pause();
    }

    function unpause() public override onlyOwner {
        super.unpause();
    }

    // -------- OVERRIDE WHITELIST --------
    function addToWhitelist(address account) public override onlyOwner {
        super.addToWhitelist(account);
    }

    function removeFromWhitelist(address account) public override onlyOwner {
        super.removeFromWhitelist(account);
    }

    // -------- OVERRIDE BLACKLIST --------
    function addToBlacklist(address account) public override onlyOwner {
        super.addToBlacklist(account);
    }

    function removeFromBlacklist(address account) public override onlyOwner {
        super.removeFromBlacklist(account);
    }

    // -------- VERSION --------
    function getVersion() public view returns (uint256) {
        return version;
    }

    function setVersion(uint256 newVersion) public onlyOwner {
        version = newVersion;
    }
}

// ============================================================================
// CONTRACT: MultiInheritanceToken
// ============================================================================

/**
 * @title MultiInheritanceToken
 * @dev Demonstrates multiple inheritance with token
 */
contract MultiInheritanceToken is
    SimpleToken,
    Ownable,
    Pausable,
    Whitelist,
    Blacklist
{
    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) SimpleToken(_name, _symbol, _decimals, _initialSupply) {
        // Add deployer to whitelist
        isWhitelisted[msg.sender] = true;
        whitelistedAddresses.push(msg.sender);
        whitelistCount = 1;
    }

    // -------- OVERRIDE TRANSFER --------
    function transfer(address to, uint256 amount)
        public
        override
        whenNotPaused
        onlyWhitelisted
        notBlacklisted
        returns (bool)
    {
        require(to != address(0), "Invalid address");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    // -------- ADMIN FUNCTIONS --------
    function pause() public override onlyOwner {
        super.pause();
    }

    function unpause() public override onlyOwner {
        super.unpause();
    }

    function addToWhitelist(address account) public override onlyOwner {
        super.addToWhitelist(account);
    }

    function removeFromWhitelist(address account) public override onlyOwner {
        super.removeFromWhitelist(account);
    }

    function addToBlacklist(address account) public override onlyOwner {
        super.addToBlacklist(account);
    }

    function removeFromBlacklist(address account) public override onlyOwner {
        super.removeFromBlacklist(account);
    }

    // -------- MINT AND BURN --------
    function mint(address to, uint256 amount) public onlyOwner {
        require(to != address(0), "Invalid address");
        require(amount > 0, "Amount must be > 0");

        totalSupply += amount;
        balances[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    function burn(address from, uint256 amount) public onlyOwner {
        require(from != address(0), "Invalid address");
        require(balances[from] >= amount, "Insufficient balance");

        balances[from] -= amount;
        totalSupply -= amount;
        emit Transfer(from, address(0), amount);
    }
}

Solidity Advanced

Storage

Storage is the persistent data of a smart contract. It’s stored on the blockchain and is expensive to use. Understanding storage is crucial for gas optimization.

Storage Characteristics:

CharacteristicDescription
PermanentStored on blockchain
ExpensiveHigh gas cost
PersistentRemains between function calls
Key-ValueStored as key-value pairs

Storage Layout:

Variables are stored in 32-byte slots:

  • Slot 0: First variable
  • Slot 1: Second variable
  • etc.

Real-World Example – Balance Mapping:

mapping(address => uint256) public balances;
// Stored using hashed keys

Code Example – Storage:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: StorageLayout
// ============================================================================

/**
 * @title StorageLayout
 * @dev Comprehensive demonstration of EVM storage patterns
 */
contract StorageLayout {
    // =========================================================================
    // BASIC STORAGE LAYOUT
    // =========================================================================

    // -------- SLOT 0 --------
    uint256 public a = 100;

    // -------- SLOT 1 --------
    uint256 public b = 200;

    // -------- SLOT 2 (Packed) --------
    // address (20 bytes) + bool (1 byte) + uint8 (1 byte) + uint16 (2 bytes) = 24 bytes
    address public addr;
    bool public isActive;
    uint8 public count;
    uint16 public smallNumber;

    // -------- SLOTS 3-5 (Fixed Array) --------
    uint256[3] public fixedArray = [10, 20, 30];

    // -------- SLOT 6 (Constant) --------
    uint256 public constant MAX_SUPPLY = 1000000;

    // =========================================================================
    // DYNAMIC STORAGE
    // =========================================================================

    // -------- DYNAMIC ARRAY --------
    // Slot 7: Stores array length
    // Elements stored at keccak256(7) + index
    uint256[] public dynamicArray;

    // -------- MAPPING --------
    // Slot 8: Stores nothing directly
    // Values stored at keccak256(key, slot)
    mapping(address => uint256) public balances;

    // -------- NESTED MAPPING --------
    // Slot 9: Stores nothing directly
    // Values stored at keccak256(key, keccak256(key2, slot))
    mapping(address => mapping(address => uint256)) public allowances;

    // -------- BYTES --------
    // Short bytes (<=31 bytes): stored in single slot
    // Long bytes (>31 bytes): stored with length at slot, data in keccak256(slot)
    bytes public shortBytes = "Hello";
    bytes public longBytes = "This is a very long bytes string that will be stored in multiple slots";

    // -------- STRING --------
    // Similar to bytes
    string public shortString = "Short";
    string public longString = "This is a very long string that will be stored in multiple slots";

    // =========================================================================
    // STORAGE WITH STRUCTS
    // =========================================================================

    struct User {
        address wallet;
        uint256 balance;
        bool active;
        string name;
    }

    // -------- SLOT 10: Mapping to struct --------
    mapping(address => User) public users;

    // -------- SLOT 11: Array of structs --------
    User[] public userList;

    // =========================================================================
    // STORAGE REFERENCE FUNCTIONS
    // =========================================================================

    /// @dev Demonstrate storage vs memory references
    function storageReference() public {
        // Storage reference (can modify state)
        uint256 storage localRef = a;
        localRef = 999; // Modifies a!
    }

    /// @dev Memory reference (cannot modify state)
    function memoryReference() public view {
        // Memory reference (local copy)
        uint256 memory memRef = a;
        // memRef = 999; // Only modifies local copy
    }

    /// @dev Modify storage directly
    function modifyStorage() public {
        a = 500;

        // Through reference
        uint256 storage ref = b;
        ref = 600;
    }

    // =========================================================================
    // STRUCT OPERATIONS
    // =========================================================================

    /// @dev Create user with storage reference
    function createUser(string memory name) public {
        // Storage reference for struct
        User storage user = users[msg.sender];
        user.wallet = msg.sender;
        user.balance = 0;
        user.active = true;
        user.name = name;
        userList.push(user);
    }

    /// @dev Update user balance
    function updateUser(uint256 amount) public {
        User storage user = users[msg.sender];
        user.balance = amount;
    }

    /// @dev Get user info
    function getUser(address wallet) public view returns (
        address addr,
        uint256 balance,
        bool active,
        string memory name
    ) {
        User memory user = users[wallet];
        return (user.wallet, user.balance, user.active, user.name);
    }

    // =========================================================================
    // DYNAMIC ARRAY OPERATIONS
    // =========================================================================

    /// @dev Add to dynamic array
    function addToArray(uint256 value) public {
        dynamicArray.push(value);
    }

    /// @dev Get array length
    function getArrayLength() public view returns (uint256) {
        return dynamicArray.length;
    }

    /// @dev Get array element
    function getArrayElement(uint256 index) public view returns (uint256) {
        require(index < dynamicArray.length, "Index out of bounds");
        return dynamicArray[index];
    }

    // =========================================================================
    // MAPPING OPERATIONS
    // =========================================================================

    /// @dev Set balance
    function setBalance(address user, uint256 amount) public {
        balances[user] = amount;
    }

    /// @dev Get balance
    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    /// @dev Approve allowance
    function approve(address spender, uint256 amount) public {
        allowances[msg.sender][spender] = amount;
    }

    /// @dev Get allowance
    function getAllowance(address owner, address spender) public view returns (uint256) {
        return allowances[owner][spender];
    }

    // =========================================================================
    // BYTES AND STRING OPERATIONS
    // =========================================================================

    /// @dev Set short bytes
    function setShortBytes(bytes memory data) public {
        require(data.length <= 31, "Too long for short bytes");
        shortBytes = data;
    }

    /// @dev Set long bytes
    function setLongBytes(bytes memory data) public {
        longBytes = data;
    }

    /// @dev Set string
    function setString(string memory data) public {
        shortString = data;
    }

    // =========================================================================
    // STORAGE GOTCHAS
    // =========================================================================

    /// @dev Demonstrate storage gotchas
    function storageGotchas() public pure {
        // CANNOT assign to storage variable directly
        // uint256 storage x = 100; // COMPILER ERROR

        // Memory for temporary data
        uint256 memory temp = 100;

        // CANNOT return storage reference
        // User storage bad = users[msg.sender]; return bad; // COMPILER ERROR
    }

    // =========================================================================
    // STORAGE SLOT ACCESS
    // =========================================================================

    /// @dev Get storage slot value (for debugging)
    function getStorageSlot(uint256 slot) public view returns (bytes32) {
        bytes32 value;
        assembly {
            value := sload(slot)
        }
        return value;
    }

    /// @dev Get storage slot for dynamic array element
    function getArraySlot(uint256 index) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(uint256(7))) ^ bytes32(index);
    }

    /// @dev Get storage slot for mapping
    function getMappingSlot(address key) public pure returns (bytes32) {
        return keccak256(abi.encodePacked(key, uint256(8)));
    }
}

// ============================================================================
// CONTRACT: StorageOptimization
// ============================================================================

/**
 * @title StorageOptimization
 * @dev Storage optimization techniques
 */
contract StorageOptimization {
    // =========================================================================
    // UNOPTIMIZED (Uses more slots)
    // =========================================================================

    /*
    uint256 a;
    uint256 b;
    uint256 c;
    // This uses 3 slots (96 bytes)
    */

    // =========================================================================
    // OPTIMIZED (Packs variables)
    // =========================================================================

    // Packing variables saves gas
    // -------- SLOT 0 --------
    uint128 public a;  // 16 bytes
    uint128 public b;  // 16 bytes
    // Both fit in one 32-byte slot!

    // -------- SLOT 1 --------
    uint64 public c;   // 8 bytes
    uint64 public d;   // 8 bytes
    uint64 public e;   // 8 bytes
    uint64 public f;   // 8 bytes
    // All four fit in one slot!

    // -------- SLOT 2 --------
    uint32 public g;   // 4 bytes
    uint32 public h;   // 4 bytes
    uint32 public i;   // 4 bytes
    uint32 public j;   // 4 bytes
    uint32 public k;   // 4 bytes
    uint32 public l;   // 4 bytes
    uint32 public m;   // 4 bytes
    uint32 public n;   // 4 bytes
    // All eight fit in one slot!

    // =========================================================================
    // STRUCT OPTIMIZATION
    // =========================================================================

    // Unoptimized struct (uses 3 slots)
    struct UnoptimizedUser {
        uint256 a;   // slot 0
        uint256 b;   // slot 1
        uint256 c;   // slot 2
    }

    // Optimized struct (uses 1 slot)
    struct OptimizedUser {
        uint128 a;   // 16 bytes
        uint128 b;   // 16 bytes
        // Both fit in one slot
    }

    // =========================================================================
    // OPTIMIZATION TIPS
    // =========================================================================

    /// @dev Storage optimization tips
    function optimizationTips() public pure returns (string memory) {
        return "
            TIPS:
            1. Use smaller types when possible (uint8, uint16, uint32)
            2. Pack variables together (address + bool + uint8)
            3. Use mappings for large data (no iteration)
            4. Avoid storing large strings/arrays on-chain
            5. Use bytes32 instead of string for fixed-size data
            6. Delete data when no longer needed (refund gas)
            7. Use structs carefully (order matters)
            8. Use uint256 for calculations (gas efficient)
        ";
    }

    // =========================================================================
    // GAS REFUNDS
    // =========================================================================

    uint256 public deletableValue;

    /// @dev Delete value to get gas refund
    function deleteValue() public {
        delete deletableValue; // Gets gas refund
    }

    /// @dev Delete array element
    function deleteArrayElement(uint256 index) public {
        delete dynamicArray[index];
    }

    uint256[] public dynamicArray;

    function addToArray(uint256 value) public {
        dynamicArray.push(value);
    }
}

// ============================================================================
// CONTRACT: StorageInheritance
// ============================================================================

/**
 * @title StorageInheritance
 * @dev Storage layout with inheritance
 */
contract StorageInheritance {
    // -------- SLOT 0 --------
    uint256 public parentValue = 100;

    // -------- SLOT 1 --------
    address public parentAddress;
}

/**
 * @title StorageChild
 * @dev Child contract storage layout
 */
contract StorageChild is StorageInheritance {
    // -------- SLOT 2 --------
    uint256 public childValue = 200;

    // -------- SLOT 3 --------
    mapping(address => uint256) public childBalances;

    // Storage layout:
    // Parent variables occupy slots 0-1
    // Child variables occupy slots 2-3
    // Parent and child slots don't overlap

    function getParentValue() public view returns (uint256) {
        return parentValue; // Slot 0
    }

    function getChildValue() public view returns (uint256) {
        return childValue; // Slot 2
    }
}

Memory

Memory is a temporary storage area in a function. It’s cheaper than storage but not persistent.

Memory Characteristics:

CharacteristicDescription
TemporaryCleared after function
CheaperLess gas than storage
LimitedCannot store large data
MutableCan be modified

Real-World Example – Function Parameters:

function process(string memory _data) public {
    // _data is in memory
    string memory temp = _data;  // Also in memory
}

Code Example – Memory:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: MemoryFundamentals
// ============================================================================

/**
 * @title MemoryFundamentals
 * @dev Comprehensive demonstration of memory usage in Solidity
 */
contract MemoryFundamentals {
    // =========================================================================
    // STORAGE VARIABLES (State)
    // =========================================================================

    uint256 public storageVar = 100;
    string public storageString = "Storage String";
    mapping(address => uint256) public storageMapping;

    // =========================================================================
    // BASIC MEMORY USAGE
    // =========================================================================

    /// @dev Simple memory allocation
    function memoryExample(uint256 input) public pure returns (uint256) {
        // Memory allocation (temporary)
        uint256 memory temp = input;
        uint256 memory result = temp * 2;
        return result;
    }

    /// @dev Multiple memory variables
    function multipleMemory(uint256 a, uint256 b) public pure returns (uint256, uint256, uint256) {
        uint256 memory x = a + b;
        uint256 memory y = a * b;
        uint256 memory z = x + y;
        return (x, y, z);
    }

    // =========================================================================
    // MEMORY ARRAYS
    // =========================================================================

    /// @dev Create fixed-size memory array
    function createFixedMemoryArray() public pure returns (uint256[3] memory) {
        // Fixed-size memory array
        uint256[3] memory arr = [1, 2, 3];
        return arr;
    }

    /// @dev Create dynamic memory array
    function createDynamicMemoryArray(uint256 size) public pure returns (uint256[] memory) {
        require(size > 0, "Size must be positive");
        // Dynamic memory array allocation
        uint256[] memory arr = new uint256[](size);
        for (uint256 i = 0; i < arr.length; i++) {
            arr[i] = i * 2;
        }
        return arr;
    }

    /// @dev Process memory array
    function processArray(uint256[] memory arr) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    /// @dev Get array length from memory
    function getArrayLength(uint256[] memory arr) public pure returns (uint256) {
        return arr.length;
    }

    // =========================================================================
    // MEMORY STRINGS
    // =========================================================================

    /// @dev Create memory string
    function createMemoryString() public pure returns (string memory) {
        string memory str = "Hello from memory!";
        return str;
    }

    /// @dev Concatenate strings in memory
    function concatStrings(string memory a, string memory b) public pure returns (string memory) {
        return string(abi.encodePacked(a, b));
    }

    /// @dev String length in memory
    function stringLength(string memory str) public pure returns (uint256) {
        return bytes(str).length;
    }

    // =========================================================================
    // MEMORY STRUCTS
    // =========================================================================

    struct Person {
        address wallet;
        string name;
        uint256 age;
        bool active;
    }

    /// @dev Create struct in memory
    function createStructMemory(
        address wallet,
        string memory name,
        uint256 age
    ) public pure returns (Person memory) {
        // Memory struct
        Person memory person = Person({
            wallet: wallet,
            name: name,
            age: age,
            active: true
        });
        return person;
    }

    /// @dev Process struct in memory
    function processStruct(Person memory person) public pure returns (string memory) {
        return person.name;
    }

    /// @dev Update struct in memory
    function updateStruct(Person memory person, string memory newName) public pure returns (Person memory) {
        person.name = newName;
        return person;
    }

    // =========================================================================
    // MEMORY BYTES
    // =========================================================================

    /// @dev Create memory bytes
    function createMemoryBytes() public pure returns (bytes memory) {
        bytes memory data = new bytes(32);
        for (uint256 i = 0; i < data.length; i++) {
            data[i] = bytes1(uint8(i));
        }
        return data;
    }

    /// @dev Convert bytes to string
    function bytesToString(bytes memory data) public pure returns (string memory) {
        return string(data);
    }

    /// @dev Bytes length
    function bytesLength(bytes memory data) public pure returns (uint256) {
        return data.length;
    }

    // =========================================================================
    // STORAGE VS MEMORY REFERENCES
    // =========================================================================

    struct Data {
        uint256 value;
        string text;
    }

    mapping(address => Data) public dataStore;

    /// @dev Storage reference (can modify state)
    function modifyStorageReference() public {
        Data storage data = dataStore[msg.sender];
        data.value = 100;
        data.text = "Modified in storage";
    }

    /// @dev Memory reference (cannot modify state)
    function readMemoryReference() public view returns (uint256, string memory) {
        Data memory data = dataStore[msg.sender];
        return (data.value, data.text);
    }

    /// @dev Copy from storage to memory
    function copyToMemory() public view returns (Data memory) {
        Data memory data = dataStore[msg.sender];
        return data;
    }

    // =========================================================================
    // MEMORY ALLOCATION PATTERNS
    // =========================================================================

    /// @dev Various memory allocation patterns
    function memoryPatterns() public pure returns (
        uint256,
        string memory,
        uint256[] memory,
        Person memory
    ) {
        // 1. Direct initialization
        uint256 memory num = 100;

        // 2. String
        string memory text = "Memory Pattern";

        // 3. Array allocation
        uint256[] memory arr = new uint256[](5);
        for (uint256 i = 0; i < arr.length; i++) {
            arr[i] = i;
        }

        // 4. Struct allocation
        Person memory person = Person(address(0), "Pattern User", 30, true);

        return (num, text, arr, person);
    }

    // =========================================================================
    // MEMORY AND EXTERNAL CALLS
    // =========================================================================

    /// @dev Pass memory data to external call
    function externalMemoryCall(string memory data) public view returns (string memory) {
        return data;
    }

    /// @dev Return memory data from external call
    function returnMemoryData() public pure returns (string memory) {
        string memory data = "Return data";
        return data;
    }

    // =========================================================================
    // MEMORY AND EVENTS
    // =========================================================================

    event LogString(string data);
    event LogArray(uint256[] data);
    event LogPerson(address indexed wallet, string name, uint256 age);

    /// @dev Emit events with memory data
    function emitMemoryData(string memory text, uint256[] memory arr, Person memory person) public {
        emit LogString(text);
        emit LogArray(arr);
        emit LogPerson(person.wallet, person.name, person.age);
    }

    // =========================================================================
    // MEMORY MANAGEMENT BEST PRACTICES
    // =========================================================================

    /// @dev Memory efficiency tips
    function memoryTips() public pure returns (string memory) {
        return "
            MEMORY TIPS:
            1. Use memory for temporary data
            2. Avoid copying large data
            3. Use calldata for function parameters
            4. Return memory data directly
            5. Use storage for persistent data
            6. Be mindful of memory expansion costs
            7. Use structs and arrays carefully
        ";
    }
}

// ============================================================================
// CONTRACT: MemoryEfficiency
// ============================================================================

/**
 * @title MemoryEfficiency
 * @dev Efficient memory usage patterns
 */
contract MemoryEfficiency {
    // =========================================================================
    // INEFFICIENT PATTERNS
    // =========================================================================

    /// @dev Inefficient - creates multiple memory copies
    function inefficient(string memory text) public pure returns (string memory) {
        string memory copy1 = text;
        string memory copy2 = copy1;
        return copy2;
    }

    /// @dev Inefficient - copies array unnecessarily
    function inefficientArray(uint256[] memory arr) public pure returns (uint256[] memory) {
        uint256[] memory copy = new uint256[](arr.length);
        for (uint256 i = 0; i < arr.length; i++) {
            copy[i] = arr[i];
        }
        return copy;
    }

    // =========================================================================
    // EFFICIENT PATTERNS
    // =========================================================================

    /// @dev Efficient - returns directly
    function efficient(string memory text) public pure returns (string memory) {
        return text;
    }

    /// @dev Efficient - processes in place
    function efficientArray(uint256[] memory arr) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    // =========================================================================
    // CALLLATA VS MEMORY
    // =========================================================================

    /// @dev Use calldata for external parameters (cheaper)
    function useCalldata(string calldata text) external pure returns (string memory) {
        return text;
    }

    /// @dev Use memory for internal processing
    function useMemory(string memory text) public pure returns (string memory) {
        return text;
    }

    // =========================================================================
    // MEMORY EXPANSION
    // =========================================================================

    /// @dev Memory expansion costs gas
    function memoryExpansion() public pure returns (uint256[] memory) {
        // Allocating large memory array costs more gas
        uint256[] memory arr = new uint256[](1000);
        for (uint256 i = 0; i < arr.length; i++) {
            arr[i] = i;
        }
        return arr;
    }

    // =========================================================================
    // COMPARISON: STORAGE VS MEMORY VS STACK
    // =========================================================================

    /// @dev Compare gas costs (conceptual)
    function compareCosts() public pure returns (string memory) {
        return "
            GAS COSTS:
            Storage: Most expensive (SLOAD: ~800 gas, SSTORE: ~20000 gas)
            Memory: Medium (MLOAD: ~3 gas, MSTORE: ~3 gas)
            Stack: Cheapest (Free for basic operations)
            
            Use stack for local variables
            Use memory for arrays/structs
            Use storage sparingly
        ";
    }
}

// ============================================================================
// CONTRACT: MemoryAdvanced
// ============================================================================

/**
 * @title MemoryAdvanced
 * @dev Advanced memory patterns
 */
contract MemoryAdvanced {
    // =========================================================================
    // NESTED STRUCTS IN MEMORY
    // =========================================================================

    struct Address {
        string street;
        string city;
        string country;
    }

    struct PersonWithAddress {
        string name;
        uint256 age;
        Address address;
    }

    /// @dev Create nested struct in memory
    function createNestedStruct(
        string memory name,
        uint256 age,
        string memory street,
        string memory city,
        string memory country
    ) public pure returns (PersonWithAddress memory) {
        Address memory addr = Address(street, city, country);
        PersonWithAddress memory person = PersonWithAddress(name, age, addr);
        return person;
    }

    // =========================================================================
    // ARRAY OF STRUCTS IN MEMORY
    // =========================================================================

    /// @dev Create array of structs in memory
    function createStructArray(uint256 count) public pure returns (Person[] memory) {
        Person[] memory people = new Person[](count);
        for (uint256 i = 0; i < count; i++) {
            people[i] = Person(address(0), "User", 20 + i, true);
        }
        return people;
    }

    // =========================================================================
    // COMPLEX MEMORY OPERATIONS
    // =========================================================================

    /// @dev Filter array in memory
    function filterArray(uint256[] memory arr, uint256 threshold) public pure returns (uint256[] memory) {
        // Count filtered elements first
        uint256 count = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] > threshold) count++;
        }

        // Create result array
        uint256[] memory result = new uint256[](count);
        uint256 index = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            if (arr[i] > threshold) {
                result[index] = arr[i];
                index++;
            }
        }
        return result;
    }

    /// @dev Map array in memory
    function mapArray(uint256[] memory arr) public pure returns (uint256[] memory) {
        uint256[] memory result = new uint256[](arr.length);
        for (uint256 i = 0; i < arr.length; i++) {
            result[i] = arr[i] * 2;
        }
        return result;
    }

    // =========================================================================
    // MEMORY GOTCHAS
    // =========================================================================

    /// @dev Demonstrate memory gotchas
    function memoryGotchas() public pure {
        // Cannot assign memory to storage
        // uint256 storage x = 100; // COMPILER ERROR

        // Cannot return reference to memory
        // uint256[] memory arr = new uint256[](5);
        // return arr; // OK - returns copy

        // Memory arrays cannot be resized
        // arr.push(10); // COMPILER ERROR
    }
}

Calldata

Calldata is a special, read-only data location used for function parameters in Solidity, especially for external function calls. It is read-only and cheaper than memory.

Calldata Characteristics:

CharacteristicDescription
Read-OnlyCannot be modified
CheapCheaper than memory
ExternalOnly available in external functions
Non-PersistentNot stored

Real-World Example – External Function:

function processData(uint256[] calldata _data)
    external
    view
    returns (uint256)
{
    // _data is read-only and cannot be modified.
    // calldata is generally cheaper than memory for read-only parameters.
}

Code Example – Calldata:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: CalldataFundamentals
// ============================================================================

/**
 * @title CalldataFundamentals
 * @dev Comprehensive demonstration of calldata usage in Solidity
 */
contract CalldataFundamentals {
    // =========================================================================
    // BASIC CALLLDATA VS MEMORY COMPARISON
    // =========================================================================

    /// @dev Memory version (more expensive)
    function memoryFunction(string memory text) public pure returns (string memory) {
        return text;
    }

    /// @dev Calldata version (cheaper)
    function calldataFunction(string calldata text) public pure returns (string calldata) {
        return text;
    }

    /// @dev Calldata to memory conversion
    function calldataToMemory(string calldata text) public pure returns (string memory) {
        // Copy from calldata to memory (allows modification)
        string memory mutableText = text;
        return mutableText;
    }

    // =========================================================================
    // CALLLDATA WITH ARRAYS
    // =========================================================================

    /// @dev Process calldata array
    function processCalldataArray(uint256[] calldata data) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < data.length; i++) {
            sum += data[i];
        }
        return sum;
    }

    /// @dev Get first element from calldata array
    function getFirstElement(uint256[] calldata data) public pure returns (uint256) {
        require(data.length > 0, "Empty array");
        return data[0];
    }

    /// @dev Get last element from calldata array
    function getLastElement(uint256[] calldata data) public pure returns (uint256) {
        require(data.length > 0, "Empty array");
        return data[data.length - 1];
    }

    /// @dev Check if calldata array contains value
    function containsValue(uint256[] calldata data, uint256 value) public pure returns (bool) {
        for (uint256 i = 0; i < data.length; i++) {
            if (data[i] == value) return true;
        }
        return false;
    }

    // =========================================================================
    // CALLLDATA WITH STRUCTS
    // =========================================================================

    struct Person {
        address wallet;
        string name;
        uint256 age;
        bool active;
    }

    /// @dev Process calldata struct
    function processPerson(Person calldata person) public pure returns (
        address wallet,
        string memory name,
        uint256 age,
        bool active
    ) {
        // Cannot modify calldata
        // person.name = "Modified"; // COMPILER ERROR
        return (person.wallet, person.name, person.age, person.active);
    }

    /// @dev Copy calldata struct to memory
    function copyPersonToMemory(Person calldata person) public pure returns (Person memory) {
        Person memory mutablePerson = person;
        // Now we can modify
        // mutablePerson.name = "Modified";
        return mutablePerson;
    }

    /// @dev Process calldata struct array
    function processPeople(Person[] calldata people) public pure returns (uint256) {
        uint256 totalAge = 0;
        for (uint256 i = 0; i < people.length; i++) {
            totalAge += people[i].age;
        }
        return totalAge;
    }

    // =========================================================================
    // CALLLDATA WITH BYTES
    // =========================================================================

    /// @dev Process calldata bytes
    function processBytes(bytes calldata data) public pure returns (uint256) {
        return data.length;
    }

    /// @dev Get bytes slice (copies to memory)
    function getBytesSlice(bytes calldata data, uint256 start, uint256 end) public pure returns (bytes memory) {
        require(start <= end, "Invalid range");
        require(end <= data.length, "End out of bounds");
        require(end - start > 0, "Slice empty");

        bytes memory slice = new bytes(end - start);
        for (uint256 i = start; i < end; i++) {
            slice[i - start] = data[i];
        }
        return slice;
    }

    // =========================================================================
    // CALLLDATA WITH NESTED STRUCTS
    // =========================================================================

    struct Address {
        string street;
        string city;
        string country;
    }

    struct PersonWithAddress {
        Person person;
        Address address;
        string[] tags;
    }

    /// @dev Process nested calldata struct
    function processNestedStruct(PersonWithAddress calldata data) public pure returns (
        string memory name,
        string memory city,
        uint256 tagCount
    ) {
        name = data.person.name;
        city = data.address.city;
        tagCount = data.tags.length;
        return (name, city, tagCount);
    }

    // =========================================================================
    // FUNCTION VISIBILITY WITH CALLLDATA
    // =========================================================================

    /// @dev External function with calldata (most gas efficient)
    function externalCalldata(uint256[] calldata data) external pure returns (uint256) {
        return data.length;
    }

    /// @dev Public function with calldata (can be called internally)
    function publicCalldata(uint256[] calldata data) public pure returns (uint256) {
        return data.length;
    }

    /// @dev Internal function cannot use calldata (must use memory)
    function internalMemory(uint256[] memory data) internal pure returns (uint256) {
        return data.length;
    }

    /// @dev Private function cannot use calldata (must use memory)
    function privateMemory(uint256[] memory data) private pure returns (uint256) {
        return data.length;
    }

    // =========================================================================
    // CALLLDATA BEST PRACTICES
    // =========================================================================

    /// @dev Best practices for calldata
    function calldataBestPractices() public pure returns (string memory) {
        return "
            CALLLDATA BEST PRACTICES:
            1. Use calldata for external function parameters
            2. Use calldata for large arrays and strings
            3. Use calldata when you don't need to modify data
            4. Don't use calldata for internal functions
            5. Don't try to modify calldata (read-only)
            6. Copy calldata to memory only when needed
            7. Calldata is cheaper than memory
            8. Use calldata for structs when possible
        ";
    }
}

// ============================================================================
// CONTRACT: CalldataComparison
// ============================================================================

/**
 * @title CalldataComparison
 * @dev Comparing calldata and memory gas costs
 */
contract CalldataComparison {
    // =========================================================================
    // MEMORY VERSION
    // =========================================================================

    /// @dev Memory version (more expensive)
    function memorySum(uint256[] memory data) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < data.length; i++) {
            sum += data[i];
        }
        return sum;
    }

    /// @dev Memory version with string
    function memoryConcat(string memory a, string memory b) public pure returns (string memory) {
        return string(abi.encodePacked(a, b));
    }

    // =========================================================================
    // CALLLDATA VERSION
    // =========================================================================

    /// @dev Calldata version (cheaper)
    function calldataSum(uint256[] calldata data) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < data.length; i++) {
            sum += data[i];
        }
        return sum;
    }

    /// @dev Calldata version with string
    function calldataConcat(string calldata a, string calldata b) public pure returns (string memory) {
        return string(abi.encodePacked(a, b));
    }

    /// @dev Calldata version with multiple arrays
    function calldataMultiSum(
        uint256[] calldata a,
        uint256[] calldata b
    ) public pure returns (uint256) {
        require(a.length == b.length, "Arrays length mismatch");
        uint256 sum = 0;
        for (uint256 i = 0; i < a.length; i++) {
            sum += a[i] + b[i];
        }
        return sum;
    }

    // =========================================================================
    // GAS COMPARISON NOTES
    // =========================================================================

    /// @dev Gas comparison notes
    function gasComparisonNotes() public pure returns (string memory) {
        return "
            GAS COMPARISON:
            calldata: ~3 gas per word (cheaper)
            memory: ~3 gas per word + expansion costs
            storage: ~800-20000 gas (most expensive)
            
            Use calldata when:
            - Data is read-only
            - Data comes from external calls
            - Data is large (arrays, strings)
            
            Use memory when:
            - Data needs to be modified
            - Data is used internally
            - Data needs to be returned
        ";
    }
}

// ============================================================================
// CONTRACT: CalldataAdvanced
// ============================================================================

/**
 * @title CalldataAdvanced
 * @dev Advanced calldata patterns
 */
contract CalldataAdvanced {
    // =========================================================================
    // CALLLDATA WITH COMPLEX TYPES
    // =========================================================================

    struct Order {
        uint256 id;
        address buyer;
        address seller;
        uint256 amount;
        string status;
        uint256[] itemIds;
    }

    /// @dev Process complex calldata
    function processOrder(Order calldata order) public pure returns (
        uint256 id,
        address buyer,
        uint256 amount,
        string memory status,
        uint256 itemCount
    ) {
        id = order.id;
        buyer = order.buyer;
        amount = order.amount;
        status = order.status;
        itemCount = order.itemIds.length;
        return (id, buyer, amount, status, itemCount);
    }

    /// @dev Process array of complex structs
    function processOrders(Order[] calldata orders) public pure returns (uint256) {
        uint256 totalAmount = 0;
        for (uint256 i = 0; i < orders.length; i++) {
            totalAmount += orders[i].amount;
        }
        return totalAmount;
    }

    // =========================================================================
    // CALLLDATA WITH MAPPINGS (Not directly possible)
    // =========================================================================

    /// @dev Mapping cannot use calldata
    /// @dev Mappings are only available in storage

    // =========================================================================
    // CALLLDATA WITH EVENTS
    // =========================================================================

    event CalldataReceived(string data, uint256[] values);

    /// @dev Emit event with calldata
    function emitCalldata(string calldata text, uint256[] calldata values) external {
        emit CalldataReceived(text, values);
    }

    // =========================================================================
    // CALLLDATA WITH EXTERNAL CALLS
    // =========================================================================

    /// @dev Forward calldata to another contract
    function forwardCalldata(address target, bytes calldata data) external returns (bytes memory) {
        (bool success, bytes memory result) = target.call(data);
        require(success, "Call failed");
        return result;
    }

    // =========================================================================
    // CALLLDATA AND MEMORY MIX
    // =========================================================================

    /// @dev Mix calldata and memory
    function mixCalldataMemory(
        string calldata text,
        uint256[] calldata values,
        uint256 multiplier
    ) public pure returns (string memory, uint256[] memory) {
        // Process calldata
        string memory modifiedText = string(abi.encodePacked(text, " - processed"));

        // Process calldata array to memory
        uint256[] memory modifiedValues = new uint256[](values.length);
        for (uint256 i = 0; i < values.length; i++) {
            modifiedValues[i] = values[i] * multiplier;
        }

        return (modifiedText, modifiedValues);
    }
}

Delegatecall

Delegatecall is a low-level function that allows a contract to execute code from another contract in its own context (storage, msg.sender, etc.).

Delegatecall Characteristics:

CharacteristicDescription
ContextExecutes in caller’s context
StorageUses caller’s storage
msg.senderPreserves original sender
msg.valuePreserves original value

Real-World Example – Proxy Pattern:

// Proxy contract uses delegatecall to call implementation
(bool success, ) = implementation.delegatecall(data);
// Storage is modified in proxy's storage

Code Example – Delegatecall:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: LogicV1
// ============================================================================

/**
 * @title LogicV1
 * @dev First version of logic contract for upgradeable pattern
 */
contract LogicV1 {
    // -------- STORAGE (Must match proxy exactly) --------
    address public owner;
    uint256 public value;
    mapping(address => uint256) public balances;

    // -------- FUNCTIONS --------
    function setValue(uint256 newValue) public {
        require(msg.sender == owner, "Not owner");
        value = newValue;
    }

    function getValue() public view returns (uint256) {
        return value;
    }

    function setBalance(address user, uint256 amount) public {
        require(msg.sender == owner, "Not owner");
        balances[user] = amount;
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function incrementValue() public {
        require(msg.sender == owner, "Not owner");
        value++;
    }

    function getVersion() public pure returns (string memory) {
        return "V1";
    }
}

// ============================================================================
// CONTRACT: LogicV2
// ============================================================================

/**
 * @title LogicV2
 * @dev Updated version of logic contract (must preserve storage layout)
 */
contract LogicV2 {
    // -------- STORAGE (Must match proxy and V1) --------
    address public owner;
    uint256 public value;
    mapping(address => uint256) public balances;

    // -------- NEW VARIABLES (Appended) --------
    uint256 public newFeature;
    mapping(address => bool) public whitelist;

    // -------- FUNCTIONS --------
    function setValue(uint256 newValue) public {
        require(msg.sender == owner, "Not owner");
        value = newValue;
        newFeature = newValue * 2;
    }

    function getValue() public view returns (uint256) {
        return value;
    }

    function getNewFeature() public view returns (uint256) {
        return newFeature;
    }

    function setBalance(address user, uint256 amount) public {
        require(msg.sender == owner, "Not owner");
        balances[user] = amount;
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function incrementValue() public {
        require(msg.sender == owner, "Not owner");
        value++;
        newFeature = value * 3;
    }

    function addToWhitelist(address user) public {
        require(msg.sender == owner, "Not owner");
        whitelist[user] = true;
    }

    function isWhitelisted(address user) public view returns (bool) {
        return whitelist[user];
    }

    function getVersion() public pure returns (string memory) {
        return "V2";
    }
}

// ============================================================================
// CONTRACT: Proxy
// ============================================================================

/**
 * @title Proxy
 * @dev Proxy contract using delegatecall for upgradeable pattern
 */
contract Proxy {
    // -------- STORAGE (Must match logic contract) --------
    address public owner;
    uint256 public value;
    mapping(address => uint256) public balances;
    address public implementation;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event Transfer(address indexed from, address indexed to, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        owner = msg.sender;
        implementation = _implementation;
    }

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- UPGRADE FUNCTION --------
    function upgradeTo(address newImplementation) public onlyOwner {
        require(newImplementation != address(0), "Invalid implementation");
        implementation = newImplementation;
        emit Upgraded(newImplementation);
    }

    // -------- DELEGATECALL IMPLEMENTATION --------
    fallback() external payable {
        // Forward call to implementation via delegatecall
        (bool success, bytes memory data) = implementation.delegatecall(msg.data);
        require(success, "Delegatecall failed");

        // Return the data
        assembly {
            return(add(data, 0x20), mload(data))
        }
    }

    // -------- RECEIVE --------
    receive() external payable {}

    // -------- VIEW FUNCTIONS --------
    function getImplementation() public view returns (address) {
        return implementation;
    }

    function getOwner() public view returns (address) {
        return owner;
    }
}

// ============================================================================
// CONTRACT: DelegatecallExample
// ============================================================================

/**
 * @title DelegatecallExample
 * @dev Demonstrates delegatecall usage
 */
contract DelegatecallExample {
    // -------- STATE VARIABLES --------
    address public target;
    uint256 public result;
    address public sender;
    uint256 public counter;

    // -------- SETUP --------
    function setTarget(address _target) public {
        target = _target;
    }

    // -------- BASIC DELEGATECALL --------
    function callThroughDelegate(address _target, uint256 _value) public {
        (bool success, ) = _target.delegatecall(
            abi.encodeWithSignature("setValue(uint256)", _value)
        );
        require(success, "Delegatecall failed");
    }

    function callThroughDelegateData(address _target, bytes memory _data) public {
        (bool success, ) = _target.delegatecall(_data);
        require(success, "Delegatecall failed");
    }

    // -------- DELEGATECALL WITH PARAMETERS --------
    function delegateWithParams(
        address _target,
        uint256 _a,
        uint256 _b
    ) public {
        (bool success, bytes memory data) = _target.delegatecall(
            abi.encodeWithSignature("add(uint256,uint256)", _a, _b)
        );
        require(success, "Delegatecall failed");
        result = abi.decode(data, (uint256));
        sender = msg.sender;
    }

    // -------- DELEGATECALL TO INCREMENT --------
    function delegateIncrement(address _target) public {
        (bool success, ) = _target.delegatecall(
            abi.encodeWithSignature("increment()")
        );
        require(success, "Delegatecall failed");
    }

    // -------- DELEGATECALL WITH RETURN VALUE --------
    function delegateGetValue(address _target) public returns (uint256) {
        (bool success, bytes memory data) = _target.delegatecall(
            abi.encodeWithSignature("getValue()")
        );
        require(success, "Delegatecall failed");
        return abi.decode(data, (uint256));
    }

    // =========================================================================
    // DELEGATECALL WITH STORAGE CONFLICT
    // =========================================================================

    // WARNING: Storage layout must match between contracts
    // The logic contract and proxy must have identical storage layout
    // Or delegatecall will corrupt storage

    // Example of storage mismatch (DO NOT DO THIS):
    /*
    contract BadLogic {
        uint256 public value;  // Slot 0
        // If proxy has different layout, data corruption occurs
    }
    */
}

// ============================================================================
// CONTRACT: DelegatecallSecurity
// ============================================================================

/**
 * @title DelegatecallSecurity
 * @dev Delegatecall security considerations
 */
contract DelegatecallSecurity {
    // -------- STATE VARIABLES --------
    address public safeImplementation;
    address public owner;
    bool public paused;

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier whenNotPaused() {
        require(!paused, "Paused");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- SECURITY FUNCTIONS --------
    function setImplementation(address newImpl) public onlyOwner {
        require(newImpl != address(0), "Invalid address");
        safeImplementation = newImpl;
    }

    function pause() public onlyOwner {
        paused = true;
    }

    function unpause() public onlyOwner {
        paused = false;
    }

    // -------- SAFE DELEGATECALL --------
    function safeDelegate(bytes memory data) public onlyOwner whenNotPaused {
        (bool success, ) = safeImplementation.delegatecall(data);
        require(success, "Delegatecall failed");
    }

    function safeDelegateWithValue(bytes memory data) public payable onlyOwner whenNotPaused {
        (bool success, ) = safeImplementation.delegatecall{value: msg.value}(data);
        require(success, "Delegatecall failed");
    }

    // -------- VIEW FUNCTIONS --------
    function getImplementation() public view returns (address) {
        return safeImplementation;
    }
}

// ============================================================================
// CONTRACT: DelegatecallSecurityBestPractices
// ============================================================================

/**
 * @title DelegatecallSecurityBestPractices
 * @dev Security best practices for delegatecall
 */
contract DelegatecallSecurityBestPractices {
    // -------- STATE VARIABLES --------
    address public implementation;
    address public admin;
    uint256 public value;

    // -------- MODIFIERS --------
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
    }

    // -------- ADMIN FUNCTIONS --------
    function setImplementation(address newImpl) public onlyAdmin {
        require(newImpl != address(0), "Invalid address");
        implementation = newImpl;
    }

    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0), "Invalid address");
        admin = newAdmin;
    }

    // -------- DELEGATECALL WITH VALIDATION --------
    function delegatecall(bytes memory data) public onlyAdmin {
        // Validate implementation is set
        require(implementation != address(0), "No implementation");

        // Validate data
        require(data.length > 0, "Empty data");

        // Execute delegatecall
        (bool success, bytes memory result) = implementation.delegatecall(data);
        require(success, "Delegatecall failed");

        // Handle return data
        if (result.length > 0) {
            assembly {
                return(add(result, 0x20), mload(result))
            }
        }
    }

    // -------- FALLBACK --------
    fallback() external payable {
        // Only allow delegatecall through the contract
        require(msg.sender == address(this), "Direct calls not allowed");
    }

    // -------- SECURITY NOTES --------
    function getSecurityNotes() public pure returns (string memory) {
        return "
            DELEGATECALL SECURITY NOTES:
            1. Storage layout must match exactly
            2. Never delegatecall to untrusted contracts
            3. Validate implementation address
            4. Use admin/owner controls
            5. Consider using proxy patterns
            6. Test upgrades thoroughly
            7. Use timelocks for upgrades
            8. Monitor delegatecall usage
        ";
    }
}

// ============================================================================
// CONTRACT: ProxyWithTimelock
// ============================================================================

/**
 * @title ProxyWithTimelock
 * @dev Upgradeable proxy with timelock for security
 */
contract ProxyWithTimelock {
    // -------- STATE VARIABLES --------
    address public implementation;
    address public admin;
    uint256 public upgradeTime;
    uint256 public constant TIMELOCK = 2 days;

    // -------- EVENTS --------
    event UpgradeScheduled(address indexed implementation, uint256 time);
    event UpgradeExecuted(address indexed implementation);

    // -------- MODIFIERS --------
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
    }

    // -------- SCHEDULE UPGRADE --------
    function scheduleUpgrade(address newImplementation) public onlyAdmin {
        require(newImplementation != address(0), "Invalid address");
        implementation = newImplementation;
        upgradeTime = block.timestamp + TIMELOCK;
        emit UpgradeScheduled(newImplementation, upgradeTime);
    }

    // -------- EXECUTE UPGRADE --------
    function executeUpgrade() public onlyAdmin {
        require(block.timestamp >= upgradeTime, "Timelock not expired");
        // Implementation already set
        emit UpgradeExecuted(implementation);
    }

    // -------- DELEGATECALL --------
    fallback() external payable {
        require(implementation != address(0), "No implementation");
        (bool success, bytes memory data) = implementation.delegatecall(msg.data);
        require(success, "Delegatecall failed");
        assembly {
            return(add(data, 0x20), mload(data))
        }
    }

    receive() external payable {}
}

Proxy Patterns

Proxy patterns enable upgradeable smart contracts. The proxy contract delegates calls to an implementation contract, allowing the implementation to be upgraded without changing the proxy address.

Proxy Benefits:

BenefitDescription
UpgradeableCan update contract logic
Immutable AddressUsers always interact with same address
Storage PreservationStorage remains intact
EIP-1967Standard proxy pattern

Common Proxy Patterns:

PatternDescriptionUse Case
TransparentSimple upgradeable proxyGeneral use
UUPSUpgradeable with implementationGas efficient
BeaconMultiple proxies sharing implementationMany instances

Code Example – Proxy Patterns:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// LIBRARY: EIP1967
// ============================================================================

/**
 * @title EIP1967
 * @dev Storage slots for proxy pattern according to EIP-1967
 */
library EIP1967 {
    // -------- IMPLEMENTATION SLOT --------
    // bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
    bytes32 internal constant IMPLEMENTATION_SLOT =
        0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    // -------- ADMIN SLOT --------
    // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
    bytes32 internal constant ADMIN_SLOT =
        0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;

    // -------- BEACON SLOT --------
    // bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)
    bytes32 internal constant BEACON_SLOT =
        0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;

    // -------- GET IMPLEMENTATION --------
    function getImplementation() internal view returns (address) {
        bytes32 slot = IMPLEMENTATION_SLOT;
        address impl;
        assembly {
            impl := sload(slot)
        }
        return impl;
    }

    // -------- SET IMPLEMENTATION --------
    function setImplementation(address newImpl) internal {
        bytes32 slot = IMPLEMENTATION_SLOT;
        require(newImpl != address(0), "EIP1967: Invalid implementation");
        assembly {
            sstore(slot, newImpl)
        }
    }

    // -------- GET ADMIN --------
    function getAdmin() internal view returns (address) {
        bytes32 slot = ADMIN_SLOT;
        address admin;
        assembly {
            admin := sload(slot)
        }
        return admin;
    }

    // -------- SET ADMIN --------
    function setAdmin(address newAdmin) internal {
        bytes32 slot = ADMIN_SLOT;
        require(newAdmin != address(0), "EIP1967: Invalid admin");
        assembly {
            sstore(slot, newAdmin)
        }
    }

    // -------- GET BEACON --------
    function getBeacon() internal view returns (address) {
        bytes32 slot = BEACON_SLOT;
        address beacon;
        assembly {
            beacon := sload(slot)
        }
        return beacon;
    }

    // -------- SET BEACON --------
    function setBeacon(address newBeacon) internal {
        bytes32 slot = BEACON_SLOT;
        require(newBeacon != address(0), "EIP1967: Invalid beacon");
        assembly {
            sstore(slot, newBeacon)
        }
    }
}

// ============================================================================
// CONTRACT: SimpleProxy
// ============================================================================

/**
 * @title SimpleProxy
 * @dev Basic proxy implementation
 */
contract SimpleProxy {
    // -------- STORAGE --------
    address public implementation;
    address public admin;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event AdminChanged(address indexed admin);

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
        emit Upgraded(_implementation);
    }

    // -------- MODIFIERS --------
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------- UPGRADE FUNCTION --------
    function upgrade(address newImpl) public onlyAdmin {
        require(newImpl != address(0), "Invalid implementation");
        implementation = newImpl;
        emit Upgraded(newImpl);
    }

    // -------- ADMIN TRANSFER --------
    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0), "Invalid admin");
        admin = newAdmin;
        emit AdminChanged(newAdmin);
    }

    // -------- FALLBACK WITH DELEGATECALL --------
    fallback() external payable {
        address impl = implementation;
        require(impl != address(0), "No implementation");

        assembly {
            // Copy calldata
            calldatacopy(0, 0, calldatasize())

            // Delegatecall to implementation
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)

            // Copy return data
            returndatacopy(0, 0, returndatasize())

            // Return or revert
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

// ============================================================================
// CONTRACT: EIP1967Proxy
// ============================================================================

/**
 * @title EIP1967Proxy
 * @dev EIP-1967 proxy implementation
 */
contract EIP1967Proxy {
    using EIP1967 for *;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        _setImplementation(_implementation);
    }

    // -------- INTERNAL FUNCTIONS --------
    function _setImplementation(address newImpl) internal {
        EIP1967.setImplementation(newImpl);
        emit Upgraded(newImpl);
    }

    function _implementation() internal view returns (address) {
        return EIP1967.getImplementation();
    }

    // -------- FALLBACK --------
    fallback() external payable {
        address impl = _implementation();
        require(impl != address(0), "No implementation");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

// ============================================================================
// CONTRACT: LogicV1
// ============================================================================

/**
 * @title LogicV1
 * @dev Implementation contract (version 1)
 */
contract LogicV1 {
    // -------- STATE VARIABLES --------
    address public owner;
    uint256 public value;
    mapping(address => uint256) public balances;

    // -------- FUNCTIONS --------
    function initialize(address _owner) public {
        require(owner == address(0), "Already initialized");
        owner = _owner;
    }

    function setValue(uint256 _value) public {
        require(msg.sender == owner, "Not owner");
        value = _value;
    }

    function getValue() public view returns (uint256) {
        return value;
    }

    function setBalance(address user, uint256 amount) public {
        require(msg.sender == owner, "Not owner");
        balances[user] = amount;
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function getVersion() public pure returns (string memory) {
        return "V1";
    }
}

// ============================================================================
// CONTRACT: LogicV2
// ============================================================================

/**
 * @title LogicV2
 * @dev Implementation contract (version 2 - upgraded)
 */
contract LogicV2 {
    // -------- STATE VARIABLES (Must match V1) --------
    address public owner;
    uint256 public value;
    mapping(address => uint256) public balances;

    // -------- NEW VARIABLE (Safe to add at end) --------
    uint256 public newFeature;
    mapping(address => bool) public whitelist;

    // -------- FUNCTIONS (New functionality) --------
    function initialize(address _owner) public {
        require(owner == address(0), "Already initialized");
        owner = _owner;
    }

    function setValue(uint256 _value) public {
        require(msg.sender == owner, "Not owner");
        value = _value;
        newFeature = _value * 2; // New logic
    }

    function getValue() public view returns (uint256) {
        return value;
    }

    function setBalance(address user, uint256 amount) public {
        require(msg.sender == owner, "Not owner");
        balances[user] = amount;
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    // -------- NEW FUNCTIONS --------
    function getNewFeature() public view returns (uint256) {
        return newFeature;
    }

    function addToWhitelist(address user) public {
        require(msg.sender == owner, "Not owner");
        whitelist[user] = true;
    }

    function isWhitelisted(address user) public view returns (bool) {
        return whitelist[user];
    }

    function getVersion() public pure returns (string memory) {
        return "V2";
    }
}

// ============================================================================
// CONTRACT: TransparentProxy
// ============================================================================

/**
 * @title TransparentProxy
 * @dev Transparent proxy pattern (admin and users are separated)
 */
contract TransparentProxy {
    // -------- STORAGE --------
    address public implementation;
    address public admin;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event AdminChanged(address indexed admin);

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
    }

    // -------- MODIFIER --------
    modifier ifAdmin() {
        if (msg.sender == admin) {
            _;
        } else {
            _fallback();
        }
    }

    // -------- ADMIN FUNCTIONS --------
    function upgrade(address newImpl) public ifAdmin {
        require(newImpl != address(0), "Invalid implementation");
        implementation = newImpl;
        emit Upgraded(newImpl);
    }

    function transferAdmin(address newAdmin) public ifAdmin {
        require(newAdmin != address(0), "Invalid admin");
        admin = newAdmin;
        emit AdminChanged(newAdmin);
    }

    // -------- FALLBACK --------
    fallback() external payable {
        _fallback();
    }

    function _fallback() internal {
        address impl = implementation;
        require(impl != address(0), "No implementation");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

// ============================================================================
// CONTRACT: ProxyFactory
// ============================================================================

/**
 * @title ProxyFactory
 * @dev Creates proxy contracts
 */
contract ProxyFactory {
    // -------- EVENTS --------
    event ProxyCreated(address indexed proxy, address indexed implementation);
    event ProxyCreatedWithData(address indexed proxy, address indexed implementation, bytes data);

    // -------- FUNCTIONS --------
    function createProxy(address implementation) public returns (address) {
        // Deploy proxy
        SimpleProxy proxy = new SimpleProxy(implementation);
        emit ProxyCreated(address(proxy), implementation);
        return address(proxy);
    }

    function createEIP1967Proxy(address implementation) public returns (address) {
        EIP1967Proxy proxy = new EIP1967Proxy(implementation);
        emit ProxyCreated(address(proxy), implementation);
        return address(proxy);
    }

    function createTransparentProxy(address implementation) public returns (address) {
        TransparentProxy proxy = new TransparentProxy(implementation);
        emit ProxyCreated(address(proxy), implementation);
        return address(proxy);
    }

    function createProxyWithData(address implementation, bytes memory data) public returns (address) {
        // Deploy proxy with initialization data
        SimpleProxy proxy = new SimpleProxy(implementation);
        (bool success, ) = address(proxy).call(data);
        require(success, "Proxy initialization failed");
        emit ProxyCreatedWithData(address(proxy), implementation, data);
        return address(proxy);
    }

    // -------- BEACON FACTORY --------
    function createBeaconProxy(address beacon, bytes memory data) public returns (address) {
        // This would deploy a beacon proxy (simplified)
        // In practice, this would use the Beacon pattern
        return address(0);
    }
}

// ============================================================================
// CONTRACT: Beacon
// ============================================================================

/**
 * @title Beacon
 * @dev Beacon contract for beacon proxy pattern
 */
contract Beacon {
    // -------- STORAGE --------
    address public implementation;
    address public owner;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        owner = msg.sender;
        implementation = _implementation;
    }

    // -------- FUNCTIONS --------
    function upgrade(address newImpl) public onlyOwner {
        require(newImpl != address(0), "Invalid implementation");
        implementation = newImpl;
        emit Upgraded(newImpl);
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid owner");
        owner = newOwner;
    }

    function getImplementation() public view returns (address) {
        return implementation;
    }
}

// ============================================================================
// CONTRACT: BeaconProxy
// ============================================================================

/**
 * @title BeaconProxy
 * @dev Beacon proxy (uses beacon to get implementation)
 */
contract BeaconProxy {
    // -------- STORAGE --------
    address public beacon;

    // -------- CONSTRUCTOR --------
    constructor(address _beacon) {
        require(_beacon != address(0), "Invalid beacon");
        beacon = _beacon;
    }

    // -------- FALLBACK --------
    fallback() external payable {
        address beaconAddr = beacon;
        require(beaconAddr != address(0), "No beacon");

        (bool success, bytes memory data) = beaconAddr.staticcall(
            abi.encodeWithSignature("getImplementation()")
        );
        require(success, "Beacon call failed");
        address impl = abi.decode(data, (address));
        require(impl != address(0), "No implementation");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

Upgradeable Contracts

Upgradeable contracts allow the logic of a smart contract to be changed while preserving the state and address.

Upgradeable Contract Patterns:

PatternDescriptionComplexity
Proxy PatternSeparate logic from stateMedium
Diamond PatternMultiple implementation contractsHigh
Eternal StorageState in separate contractMedium

Code Example – Upgradeable Contracts:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: UpgradeableStorage
// ============================================================================

/**
 * @title UpgradeableStorage
 * @dev Storage for upgradeable contracts (uses unstructured storage pattern)
 */
contract UpgradeableStorage {
    // -------- STORAGE LAYOUT --------
    // All upgradeable contracts must share storage layout
    // Using unstructured storage to avoid collisions

    struct Storage {
        address owner;
        uint256 value;
        mapping(address => uint256) balances;
        bool initialized;
        uint256 lastUpgrade;
        mapping(address => bool) whitelist;
    }

    // -------- STORAGE POINTER --------
    // Use a specific slot for storage to avoid collisions
    bytes32 private constant STORAGE_SLOT = keccak256("upgradeable.storage");

    // -------- STORAGE ACCESS --------
    function _getStorage() internal pure returns (Storage storage ds) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            ds.slot := slot
        }
    }

    // -------- HELPERS --------
    function _getOwner() internal view returns (address) {
        Storage storage ds = _getStorage();
        return ds.owner;
    }

    function _getValue() internal view returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.value;
    }

    function _isInitialized() internal view returns (bool) {
        Storage storage ds = _getStorage();
        return ds.initialized;
    }
}

// ============================================================================
// CONTRACT: UpgradeableBase
// ============================================================================

/**
 * @title UpgradeableBase
 * @dev Base upgradeable contract with initialization and ownership
 */
contract UpgradeableBase is UpgradeableStorage {
    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event Initialized(address indexed owner);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        Storage storage ds = _getStorage();
        require(msg.sender == ds.owner, "Not owner");
        _;
    }

    modifier initialized() {
        Storage storage ds = _getStorage();
        require(ds.initialized, "Not initialized");
        _;
    }

    // -------- INITIALIZATION --------
    function initialize(address _owner) public virtual {
        Storage storage ds = _getStorage();
        require(!ds.initialized, "Already initialized");
        require(_owner != address(0), "Invalid owner");
        ds.owner = _owner;
        ds.initialized = true;
        ds.lastUpgrade = block.timestamp;
        emit Initialized(_owner);
    }

    // -------- OWNER FUNCTIONS --------
    function changeOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid owner");
        Storage storage ds = _getStorage();
        address oldOwner = ds.owner;
        ds.owner = newOwner;
        emit OwnerChanged(oldOwner, newOwner);
    }

    // -------- GETTERS --------
    function getOwner() public view returns (address) {
        Storage storage ds = _getStorage();
        return ds.owner;
    }

    function getValue() public view returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.value;
    }

    function getLastUpgrade() public view returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.lastUpgrade;
    }

    function isInitialized() public view returns (bool) {
        Storage storage ds = _getStorage();
        return ds.initialized;
    }

    function getBalance(address user) public view returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.balances[user];
    }

    function isWhitelisted(address user) public view returns (bool) {
        Storage storage ds = _getStorage();
        return ds.whitelist[user];
    }
}

// ============================================================================
// CONTRACT: UpgradeableV1
// ============================================================================

/**
 * @title UpgradeableV1
 * @dev Version 1 implementation
 */
contract UpgradeableV1 is UpgradeableBase {
    // -------- FUNCTIONS --------
    function setValue(uint256 _value) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.value = _value;
    }

    function setBalance(address user, uint256 amount) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.balances[user] = amount;
    }

    function addToWhitelist(address user) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.whitelist[user] = true;
    }

    function getVersion() public pure returns (string memory) {
        return "V1.0";
    }

    function getDoubleValue() public view initialized returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.value * 2;
    }
}

// ============================================================================
// CONTRACT: UpgradeableV2
// ============================================================================

/**
 * @title UpgradeableV2
 * @dev Version 2 implementation (enhanced)
 */
contract UpgradeableV2 is UpgradeableBase {
    // -------- FUNCTIONS (Enhanced version) --------
    function setValue(uint256 _value) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.value = _value * 2; // New logic: double the value
        ds.lastUpgrade = block.timestamp;
    }

    function setBalance(address user, uint256 amount) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.balances[user] = amount;
        ds.lastUpgrade = block.timestamp;
    }

    function addToWhitelist(address user) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.whitelist[user] = true;
        ds.lastUpgrade = block.timestamp;
    }

    function removeFromWhitelist(address user) public onlyOwner initialized {
        Storage storage ds = _getStorage();
        ds.whitelist[user] = false;
        ds.lastUpgrade = block.timestamp;
    }

    // -------- NEW FUNCTIONS --------
    function getTripleValue() public view initialized returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.value * 3;
    }

    function getVersion() public pure returns (string memory) {
        return "V2.0";
    }

    function getDoubleValue() public view initialized returns (uint256) {
        Storage storage ds = _getStorage();
        return ds.value * 2;
    }
}

// ============================================================================
// CONTRACT: UpgradeableProxy
// ============================================================================

/**
 * @title UpgradeableProxy
 * @dev Proxy for upgradeable contracts
 */
contract UpgradeableProxy {
    // -------- STORAGE --------
    address public implementation;
    address public admin;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event AdminChanged(address indexed admin);

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
    }

    // -------- MODIFIERS --------
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------- FUNCTIONS --------
    function upgrade(address newImpl) public onlyAdmin {
        require(newImpl != address(0), "Invalid implementation");
        implementation = newImpl;
        emit Upgraded(newImpl);
    }

    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0), "Invalid admin");
        admin = newAdmin;
        emit AdminChanged(newAdmin);
    }

    function getImplementation() public view returns (address) {
        return implementation;
    }

    function getAdmin() public view returns (address) {
        return admin;
    }

    // -------- FALLBACK --------
    fallback() external payable {
        address impl = implementation;
        require(impl != address(0), "No implementation");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

// ============================================================================
// CONTRACT: UpgradeManager
// ============================================================================

/**
 * @title UpgradeManager
 * @dev Manages upgradeable contracts
 */
contract UpgradeManager {
    // -------- STATE --------
    address public owner;
    mapping(address => address) public proxies; // proxy -> implementation
    mapping(address => bool) public isUpgradeable;

    // -------- EVENTS --------
    event ProxyDeployed(address indexed proxy, address indexed implementation);
    event ProxyUpgraded(address indexed proxy, address indexed oldImpl, address indexed newImpl);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- DEPLOY FUNCTIONS --------
    function deployProxy(address implementation) public onlyOwner returns (address) {
        require(implementation != address(0), "Invalid implementation");
        UpgradeableProxy proxy = new UpgradeableProxy(implementation);
        address proxyAddr = address(proxy);
        proxies[proxyAddr] = implementation;
        isUpgradeable[proxyAddr] = true;
        emit ProxyDeployed(proxyAddr, implementation);
        return proxyAddr;
    }

    function deployProxyWithInit(
        address implementation,
        bytes memory initData
    ) public onlyOwner returns (address) {
        address proxyAddr = deployProxy(implementation);
        (bool success, ) = proxyAddr.call(initData);
        require(success, "Init failed");
        return proxyAddr;
    }

    // -------- UPGRADE FUNCTIONS --------
    function upgradeProxy(address proxy, address newImpl) public onlyOwner {
        require(isUpgradeable[proxy], "Proxy not tracked");
        require(newImpl != address(0), "Invalid implementation");
        address oldImpl = proxies[proxy];
        UpgradeableProxy(proxy).upgrade(newImpl);
        proxies[proxy] = newImpl;
        emit ProxyUpgraded(proxy, oldImpl, newImpl);
    }

    // -------- ADMIN FUNCTIONS --------
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid owner");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnerChanged(oldOwner, newOwner);
    }

    // -------- VIEW FUNCTIONS --------
    function getImplementation(address proxy) public view returns (address) {
        return proxies[proxy];
    }

    function getProxyAdmin(address proxy) public view returns (address) {
        return UpgradeableProxy(proxy).getAdmin();
    }

    function isTracked(address proxy) public view returns (bool) {
        return isUpgradeable[proxy];
    }
}

// ============================================================================
// CONTRACT: UpgradeableFactory
// ============================================================================

/**
 * @title UpgradeableFactory
 * @dev Factory for upgradeable contracts with automatic initialization
 */
contract UpgradeableFactory {
    address public implementation;
    address public owner;

    event ImplementationUpdated(address indexed oldImpl, address indexed newImpl);

    constructor(address _implementation) {
        owner = msg.sender;
        implementation = _implementation;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    function setImplementation(address newImpl) public onlyOwner {
        require(newImpl != address(0), "Invalid implementation");
        address oldImpl = implementation;
        implementation = newImpl;
        emit ImplementationUpdated(oldImpl, newImpl);
    }

    function createProxy(address admin) public returns (address) {
        UpgradeableProxy proxy = new UpgradeableProxy(implementation);
        address proxyAddr = address(proxy);

        // Transfer admin to specified address
        UpgradeableProxy(proxy).transferAdmin(admin);

        return proxyAddr;
    }

    function createProxyWithInit(
        address admin,
        bytes memory initData
    ) public returns (address) {
        address proxyAddr = createProxy(admin);
        (bool success, ) = proxyAddr.call(initData);
        require(success, "Init failed");
        return proxyAddr;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid owner");
        owner = newOwner;
    }

    function getImplementation() public view returns (address) {
        return implementation;
    }
}

Design Patterns

Design patterns are reusable solutions to common problems in smart contract development. They provide proven, tested approaches to building secure and efficient contracts.

Common Design Patterns:

PatternDescriptionUse Case
Checks-Effects-InteractionsValidate, update state, then interactSecurity
Pull over PushLet users withdraw fundsPayment handling
Circuit BreakerEmergency pause functionalitySecurity
FactoryCreate new contract instancesContract deployment

Code Example – Design Patterns:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: ChecksEffectsInteractions
// ============================================================================

/**
 * @title ChecksEffectsInteractions
 * @dev Demonstrates the Checks-Effects-Interactions pattern for security
 */
contract ChecksEffectsInteractions {
    // -------- STATE VARIABLES --------
    mapping(address => uint256) public balances;
    mapping(address => bool) public whitelist;
    address public owner;

    // -------- EVENTS --------
    event Withdrawal(address indexed user, uint256 amount);
    event Deposit(address indexed user, uint256 amount);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // =========================================================================
    // BAD PATTERN: Reentrancy vulnerable
    // =========================================================================

    /// @dev BAD: Interaction first, then effects (VULNERABLE!)
    function withdrawBad(uint256 amount) public {
        // 1. INTERACTION first (VULNERABLE to reentrancy!)
        payable(msg.sender).transfer(amount);

        // 2. EFFECTS after (can be re-entered)
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
    }

    // =========================================================================
    // GOOD PATTERN: Checks-Effects-Interactions
    // =========================================================================

    /// @dev GOOD: Checks → Effects → Interactions
    function withdrawGood(uint256 amount) public {
        // 1. CHECK: Validate conditions
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(amount > 0, "Amount must be > 0");
        require(!paused, "Contract paused");

        // 2. EFFECTS: Update state first
        balances[msg.sender] -= amount;

        // 3. INTERACTIONS: External calls last
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        require(success, "Transfer failed");

        emit Withdrawal(msg.sender, amount);
    }

    /// @dev Deposit function (CEI compliant)
    function deposit() public payable {
        require(msg.value > 0, "Amount must be > 0");

        // Effects first
        balances[msg.sender] += msg.value;

        // No external interaction needed for deposit
        emit Deposit(msg.sender, msg.value);
    }

    // -------- ADDITIONAL SAFE FUNCTIONS --------
    bool public paused;

    function pause() public onlyOwner {
        paused = true;
    }

    function unpause() public onlyOwner {
        paused = false;
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }
}

// ============================================================================
// CONTRACT: PullOverPush
// ============================================================================

/**
 * @title PullOverPush
 * @dev Demonstrates Pull over Push pattern for secure withdrawals
 */
contract PullOverPush {
    // -------- STATE VARIABLES --------
    mapping(address => uint256) public pendingWithdrawals;
    address public owner;

    // -------- EVENTS --------
    event WithdrawalRequested(address indexed user, uint256 amount);
    event WithdrawalProcessed(address indexed user, uint256 amount);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // =========================================================================
    // PUSH PATTERN (Bad) - Sender controls transfer
    // =========================================================================

    /// @dev PUSH: Sender pushes funds (can fail)
    function pushPayment(address to, uint256 amount) public onlyOwner {
        // Pushing funds to recipient (can fail)
        (bool success, ) = payable(to).call{value: amount}("");
        require(success, "Push failed");
        // Recipient has no control over when/how
    }

    // =========================================================================
    // PULL PATTERN (Good) - Recipient controls transfer
    // =========================================================================

    /// @dev Request withdrawal (recipient controls timing)
    function requestWithdrawal(uint256 amount) public {
        require(amount > 0, "Amount must be > 0");
        require(address(this).balance >= amount, "Insufficient contract balance");

        pendingWithdrawals[msg.sender] += amount;
        emit WithdrawalRequested(msg.sender, amount);
    }

    /// @dev Recipient pulls funds
    function withdrawPending() public {
        uint256 amount = pendingWithdrawals[msg.sender];
        require(amount > 0, "No pending withdrawal");

        // Effects first
        pendingWithdrawals[msg.sender] = 0;

        // Interaction last (pull)
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        require(success, "Transfer failed");

        emit WithdrawalProcessed(msg.sender, amount);
    }

    /// @dev Get pending withdrawal amount
    function getPendingWithdrawal(address user) public view returns (uint256) {
        return pendingWithdrawals[user];
    }

    // -------- ADMIN FUNCTIONS --------
    function fundContract() public payable {
        require(msg.value > 0, "Must send ETH");
    }

    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }
}

// ============================================================================
// CONTRACT: CircuitBreaker
// ============================================================================

/**
 * @title CircuitBreaker
 * @dev Emergency pause functionality (circuit breaker pattern)
 */
contract CircuitBreaker {
    // -------- STATE VARIABLES --------
    bool public paused;
    address public owner;
    uint256 public pausedAt;
    uint256 public unpausedAt;

    // -------- EVENTS --------
    event Paused(address indexed account, uint256 timestamp);
    event Unpaused(address indexed account, uint256 timestamp);

    // -------- MODIFIERS --------
    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- FUNCTIONS --------
    function pause() public onlyOwner {
        require(!paused, "Already paused");
        paused = true;
        pausedAt = block.timestamp;
        emit Paused(msg.sender, pausedAt);
    }

    function unpause() public onlyOwner {
        require(paused, "Not paused");
        paused = false;
        unpausedAt = block.timestamp;
        emit Unpaused(msg.sender, unpausedAt);
    }

    /// @dev Emergency function that can be called when paused
    function emergencyWithdraw() public onlyOwner {
        // Only when paused
        require(paused, "Not paused");

        uint256 balance = address(this).balance;
        (bool success, ) = payable(owner).call{value: balance}("");
        require(success, "Emergency withdrawal failed");
    }

    /// @dev Protected function
    function criticalOperation() public whenNotPaused {
        // Only executes when not paused
    }

    // -------- VIEW FUNCTIONS --------
    function isPaused() public view returns (bool) {
        return paused;
    }

    function getPauseDuration() public view returns (uint256) {
        if (paused) {
            return block.timestamp - pausedAt;
        }
        return 0;
    }
}

// ============================================================================
// CONTRACT: FactoryPattern
// ============================================================================

/**
 * @title FactoryPattern
 * @dev Contract factory pattern for deploying child contracts
 */
contract FactoryPattern {
    // -------- STATE VARIABLES --------
    address[] public allChildren;
    mapping(address => bool) public isChild;
    mapping(address => address[]) public userChildren;
    address public owner;

    // -------- EVENTS --------
    event ChildCreated(address indexed child, address indexed creator, uint256 value);
    event ChildDestroyed(address indexed child, address indexed destroyer);

    // -------- CHILD CONTRACT --------
    contract Child {
        address public factory;
        address public owner;
        uint256 public value;
        bool public destroyed;

        constructor(address _owner, uint256 _value) {
            factory = msg.sender;
            owner = _owner;
            value = _value;
        }

        function destroy() public {
            require(msg.sender == owner || msg.sender == factory, "Not authorized");
            require(!destroyed, "Already destroyed");
            destroyed = true;
            selfdestruct(payable(owner));
        }

        function getValue() public view returns (uint256) {
            return value;
        }

        function getOwner() public view returns (address) {
            return owner;
        }
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- FACTORY FUNCTIONS --------
    function createChild(uint256 value) public returns (address) {
        Child child = new Child(msg.sender, value);
        address childAddr = address(child);
        allChildren.push(childAddr);
        isChild[childAddr] = true;
        userChildren[msg.sender].push(childAddr);
        emit ChildCreated(childAddr, msg.sender, value);
        return childAddr;
    }

    function createChildWithData(uint256 value, bytes memory data) public returns (address) {
        Child child = new Child(msg.sender, value);
        address childAddr = address(child);
        allChildren.push(childAddr);
        isChild[childAddr] = true;
        userChildren[msg.sender].push(childAddr);
        emit ChildCreated(childAddr, msg.sender, value);

        // Execute initialization data
        if (data.length > 0) {
            (bool success, ) = childAddr.call(data);
            require(success, "Init failed");
        }

        return childAddr;
    }

    // -------- VIEW FUNCTIONS --------
    function getChildren() public view returns (address[] memory) {
        return allChildren;
    }

    function getChildCount() public view returns (uint256) {
        return allChildren.length;
    }

    function getUserChildren(address user) public view returns (address[] memory) {
        return userChildren[user];
    }

    function getChildInfo(address childAddr) public view returns (address, uint256, bool) {
        Child child = Child(childAddr);
        return (child.getOwner(), child.getValue(), child.destroyed());
    }

    // -------- ADMIN FUNCTIONS --------
    function destroyChild(address childAddr) public {
        require(isChild[childAddr], "Not a child");
        Child child = Child(childAddr);
        child.destroy();
        emit ChildDestroyed(childAddr, msg.sender);
    }
}

// ============================================================================
// CONTRACT: SingletonPattern
// ============================================================================

/**
 * @title SingletonPattern
 * @dev Singleton pattern (only one instance allowed)
 */
contract SingletonPattern {
    // -------- STATE --------
    static SingletonPattern private _instance;
    address public deployer;
    uint256 public version;

    // -------- EVENTS --------
    event SingletonDeployed(address indexed instance, address indexed deployer);

    // -------- CONSTRUCTOR --------
    constructor(uint256 _version) {
        require(address(_instance) == address(0), "Singleton already exists");
        _instance = this;
        deployer = msg.sender;
        version = _version;
        emit SingletonDeployed(address(this), msg.sender);
    }

    // -------- FUNCTIONS --------
    function getInstance() public view returns (address) {
        return address(_instance);
    }

    function getVersion() public view returns (uint256) {
        return version;
    }

    function isSingleton() public pure returns (bool) {
        return true;
    }
}

// ============================================================================
// CONTRACT: ProxyPatternExample
// ============================================================================

/**
 * @title ProxyPatternExample
 * @dev Demonstrates proxy pattern (simplified)
 */
contract ProxyPatternExample {
    // -------- STATE --------
    address public implementation;
    address public admin;

    // -------- EVENTS --------
    event Upgraded(address indexed implementation);
    event AdminChanged(address indexed admin);

    // -------- MODIFIERS --------
    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(address _implementation) {
        admin = msg.sender;
        implementation = _implementation;
    }

    // -------- FUNCTIONS --------
    function upgrade(address newImpl) public onlyAdmin {
        require(newImpl != address(0), "Invalid implementation");
        implementation = newImpl;
        emit Upgraded(newImpl);
    }

    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0), "Invalid admin");
        admin = newAdmin;
        emit AdminChanged(newAdmin);
    }

    // -------- FALLBACK --------
    fallback() external payable {
        address impl = implementation;
        require(impl != address(0), "No implementation");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    receive() external payable {}
}

Gas Optimization

Gas optimization reduces the cost of executing smart contract functions. It’s crucial for user experience and contract efficiency.

Gas Optimization Techniques:

TechniqueDescriptionGas Saved
Packing VariablesUse smaller typesHigh
CalldataUse calldata for parametersMedium
Short CircuitOptimize conditionalsLow
ConstantsUse constants/immutableMedium

Code Example – Gas Optimization:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// CONTRACT: GasOptimization
// ============================================================================

/**
 * @title GasOptimization
 * @dev Comprehensive gas optimization techniques for Solidity
 */
contract GasOptimization {
    // =========================================================================
    // VARIABLE PACKING
    // =========================================================================

    // -------- UNOPTIMIZED (3 slots) --------
    uint256 public a;
    uint256 public b;
    uint256 public c;

    // -------- OPTIMIZED (2 slots) --------
    uint128 public d; // 16 bytes
    uint128 public e; // 16 bytes → One slot (32 bytes total)
    uint128 public f; // 16 bytes → Second slot

    // -------- MAXIMUM PACKING (1 slot) --------
    uint64 public g; // 8 bytes
    uint64 public h; // 8 bytes
    uint64 public i; // 8 bytes
    uint64 public j; // 8 bytes → All four fit in one 32-byte slot!

    // -------- ADDRESS + BOOL + UINT8 (1 slot) --------
    address public wallet; // 20 bytes
    bool public isActive; // 1 byte
    uint8 public count; // 1 byte
    // Total: 22 bytes (fits in one slot!)

    // =========================================================================
    // CONSTANTS vs VARIABLES vs IMMUTABLES
    // =========================================================================

    // -------- VARIABLE (stored in storage, most expensive) --------
    uint256 public variableValue = 100;

    // -------- CONSTANT (not stored in storage, cheapest) --------
    uint256 public constant CONSTANT_VALUE = 100;

    // -------- IMMUTABLE (set once, not stored in storage) --------
    uint256 public immutable immutableValue;

    constructor(uint256 _value) {
        immutableValue = _value;
    }

    // =========================================================================
    // FUNCTION OPTIMIZATION
    // =========================================================================

    // -------- UNOPTIMIZED (uses memory, more gas) --------
    function sumMemory(uint256[] memory arr) public pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    // -------- OPTIMIZED (uses calldata, less gas) --------
    function sumCalldata(uint256[] calldata arr) public pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    // -------- EXTERNAL vs PUBLIC --------
    // External is cheaper for functions only called externally
    function externalOnly(uint256 x) external pure returns (uint256) {
        return x * 2;
    }

    // Public is more expensive (can be called internally)
    function publicFunction(uint256 x) public pure returns (uint256) {
        return x * 2;
    }

    // =========================================================================
    // SHORT CIRCUIT EVALUATION
    // =========================================================================

    // -------- UNOPTIMIZED (both conditions always checked) --------
    function isEligibleBad(uint256 amount, bool active) public pure returns (bool) {
        return active && amount > 100; // Both checked
    }

    // -------- OPTIMIZED (cheaper condition first) --------
    function isEligibleGood(uint256 amount, bool active) public pure returns (bool) {
        return amount > 100 && active; // amount check first (cheaper)
    }

    // -------- OPTIMIZED with multiple conditions --------
    function isEligibleOptimized(
        uint256 amount,
        bool active,
        bool whitelisted
    ) public pure returns (bool) {
        // Cheapest checks first
        return amount > 100 && active && whitelisted;
    }

    // =========================================================================
    // LOOP OPTIMIZATION
    // =========================================================================

    // -------- UNOPTIMIZED (recalculates length each time) --------
    function sumLoopBad(uint256[] calldata arr) public pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        return total;
    }

    // -------- OPTIMIZED (cache length) --------
    function sumLoopGood(uint256[] calldata arr) public pure returns (uint256) {
        uint256 total = 0;
        uint256 len = arr.length;
        for (uint256 i = 0; i < len; i++) {
            total += arr[i];
        }
        return total;
    }

    // -------- OPTIMIZED (decrement loop) --------
    function sumLoopReverse(uint256[] calldata arr) public pure returns (uint256) {
        uint256 total = 0;
        for (uint256 i = arr.length; i > 0; i--) {
            total += arr[i - 1];
        }
        return total;
    }

    // -------- OPTIMIZED (unchecked for gas savings) --------
    function sumLoopUnchecked(uint256[] calldata arr) public pure returns (uint256) {
        uint256 total = 0;
        uint256 len = arr.length;
        unchecked {
            for (uint256 i = 0; i < len; i++) {
                total += arr[i];
            }
        }
        return total;
    }

    // =========================================================================
    // INCREMENT/DECREMENT
    // =========================================================================

    uint256 public counter;

    // -------- UNOPTIMIZED --------
    function incrementBad() public {
        counter = counter + 1;
    }

    // -------- OPTIMIZED --------
    function incrementGood() public {
        counter++;
    }

    // -------- OPTIMIZED (unchecked) --------
    function incrementUnchecked() public {
        unchecked {
            counter++;
        }
    }

    // =========================================================================
    // UNCHECKED MATH
    // =========================================================================

    function uncheckedAdd(uint256 a, uint256 b) public pure returns (uint256) {
        // For operations that won't overflow
        unchecked {
            return a + b;
        }
    }

    function uncheckedSub(uint256 a, uint256 b) public pure returns (uint256) {
        require(a >= b, "Underflow");
        unchecked {
            return a - b;
        }
    }

    function uncheckedMul(uint256 a, uint256 b) public pure returns (uint256) {
        // Only use when you know a * b won't overflow
        unchecked {
            return a * b;
        }
    }

    // =========================================================================
    // STORAGE vs MEMORY
    // =========================================================================

    struct Data {
        uint256 a;
        uint256 b;
        uint256 c;
    }

    mapping(address => Data) public dataStore;

    // -------- UNOPTIMIZED (reads from storage multiple times) --------
    function processBad(address addr) public view returns (uint256) {
        uint256 a = dataStore[addr].a;
        uint256 b = dataStore[addr].b;
        uint256 c = dataStore[addr].c;
        return a + b + c;
    }

    // -------- OPTIMIZED (reads from storage once) --------
    function processGood(address addr) public view returns (uint256) {
        Data memory data = dataStore[addr]; // One storage read
        return data.a + data.b + data.c;
    }

    // -------- OPTIMIZED (storage pointer for modification) --------
    function setData(address addr, uint256 a, uint256 b, uint256 c) public {
        Data storage data = dataStore[addr]; // Storage pointer (no copy)
        data.a = a;
        data.b = b;
        data.c = c;
    }

    // =========================================================================
    // BITWISE OPERATIONS (faster than arithmetic)
    // =========================================================================

    // Multiply by 2
    function mul2(uint256 x) public pure returns (uint256) {
        return x << 1; // Shift left (faster than x * 2)
    }

    // Divide by 2
    function div2(uint256 x) public pure returns (uint256) {
        return x >> 1; // Shift right (faster than x / 2)
    }

    // Check even
    function isEven(uint256 x) public pure returns (bool) {
        return (x & 1) == 0; // Bitwise AND (faster than x % 2 == 0)
    }

    // Check odd
    function isOdd(uint256 x) public pure returns (bool) {
        return (x & 1) == 1;
    }

    // Power of 2 check
    function isPowerOfTwo(uint256 x) public pure returns (bool) {
        return x != 0 && (x & (x - 1)) == 0;
    }

    // =========================================================================
    // DELETE (gets gas refund)
    // =========================================================================

    uint256 public deleteValue;
    mapping(address => uint256) public deleteMapping;

    function deleteStorage() public {
        delete deleteValue; // Gets gas refund
    }

    function deleteMappingValue(address user) public {
        delete deleteMapping[user]; // Gets gas refund
    }

    // =========================================================================
    // STATE VARIABLE OPTIMIZATION
    // =========================================================================

    // -------- Order matters for packing --------
    // BAD ORDER (3 slots)
    struct BadStruct {
        uint256 a; // slot 0
        bool b; // slot 1 (wastes space)
        uint256 c; // slot 2
    }

    // GOOD ORDER (2 slots)
    struct GoodStruct {
        uint256 a; // slot 0
        uint256 c; // slot 1
        bool b; // slot 1 (packed with c)
    }

    // =========================================================================
    // MAPPING VS ARRAY
    // =========================================================================

    // Arrays are cheaper for iteration
    // Mappings are cheaper for random access

    mapping(address => uint256) public balanceMap;
    address[] public userList;

    function addUser(address user) public {
        if (balanceMap[user] == 0) {
            userList.push(user);
        }
    }

    function getTotalBalance() public view returns (uint256) {
        uint256 total = 0;
        for (uint256 i = 0; i < userList.length; i++) {
            total += balanceMap[userList[i]];
        }
        return total;
    }
}

// ============================================================================
// CONTRACT: GasComparison
// ============================================================================

/**
 * @title GasComparison
 * @dev Demonstrates gas cost comparisons
 */
contract GasComparison {
    // =========================================================================
    // COMPARISON: uint256 vs uint8
    // =========================================================================

    // uint256 uses more gas for storage
    uint256 public bigInt;

    // uint8 uses less gas for storage
    uint8 public smallInt;

    // =========================================================================
    // COMPARISON: public vs private
    // =========================================================================

    // public: generates getter function (more code)
    uint256 public publicVar;

    // private: no getter (less code)
    uint256 private privateVar;

    // =========================================================================
    // COMPARISON: require vs revert
    // =========================================================================

    // -------- require with string (stores string) --------
    function checkRequire(uint256 x) public pure {
        require(x > 0, "Value must be positive");
    }

    // -------- custom error (cheaper) --------
    error ValueTooLow(uint256 value);

    function checkRevert(uint256 x) public pure {
        if (x == 0) revert ValueTooLow(x);
    }

    // =========================================================================
    // COMPARISON: ++i vs i++ (no difference in Solidity 0.8+)
    // =========================================================================

    uint256 public counter;

    function incrementPrefix() public {
        ++counter; // Same gas as counter++
    }

    function incrementPostfix() public {
        counter++; // Same gas as ++counter
    }

    // =========================================================================
    // COMPARISON: For vs While (for loops are preferred)
    // =========================================================================

    function forLoop(uint256 n) public pure returns (uint256) {
        uint256 sum = 0;
        for (uint256 i = 0; i < n; i++) {
            sum += i;
        }
        return sum;
    }

    function whileLoop(uint256 n) public pure returns (uint256) {
        uint256 sum = 0;
        uint256 i = 0;
        while (i < n) {
            sum += i;
            i++;
        }
        return sum;
    }

    // =========================================================================
    // GAS OPTIMIZATION TIPS
    // =========================================================================

    function getOptimizationTips() public pure returns (string memory) {
        return "
            GAS OPTIMIZATION TIPS:
            1. Pack variables (use smaller types)
            2. Use constants and immutables
            3. Use calldata instead of memory
            4. Use external instead of public
            5. Cache array length in loops
            6. Use unchecked math when safe
            7. Use bitwise operations when possible
            8. Delete unused storage
            9. Use custom errors instead of require strings
            10. Avoid duplicate storage reads
        ";
    }
}

3. Token Standards

Fungible Tokens

ERC-20

ERC-20 is the most common token standard for fungible tokens on Ethereum. It defines a standard interface for tokens that are interchangeable (like currencies).

ERC-20 Functions:

FunctionDescription
totalSupply()Total token supply
balanceOf(address)Balance of an address
transfer(address, uint256)Transfer tokens
approve(address, uint256)Approve spending
allowance(address, address)Check allowance
transferFrom(address, address, uint256)Transfer on behalf

Real-World Example:

  • USDC, USDT, DAI (stablecoins)
  • UNI, AAVE, LINK (governance tokens)

Code Example – ERC-20:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC20
// ============================================================================

/**
 * @title IERC20
 * @dev ERC-20 token interface
 */
interface IERC20 {
    // -------- VIEW FUNCTIONS --------
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    // -------- STATE-CHANGING FUNCTIONS --------
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// ============================================================================
// CONTRACT: ERC20
// ============================================================================

/**
 * @title ERC20
 * @dev Complete ERC-20 implementation
 */
contract ERC20 is IERC20 {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 private _totalSupply;

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        _totalSupply = _initialSupply * 10 ** decimals;
        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    // -------- VIEW FUNCTIONS --------
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    // -------- STATE-CHANGING FUNCTIONS --------
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        require(recipient != address(0), "ERC20: transfer to zero address");
        require(_balances[msg.sender] >= amount, "ERC20: insufficient balance");

        _balances[msg.sender] -= amount;
        _balances[recipient] += amount;
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }

    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        require(spender != address(0), "ERC20: approve to zero address");

        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public virtual override returns (bool) {
        require(sender != address(0), "ERC20: transfer from zero address");
        require(recipient != address(0), "ERC20: transfer to zero address");
        require(_balances[sender] >= amount, "ERC20: insufficient balance");
        require(_allowances[sender][msg.sender] >= amount, "ERC20: insufficient allowance");

        _balances[sender] -= amount;
        _balances[recipient] += amount;
        _allowances[sender][msg.sender] -= amount;
        emit Transfer(sender, recipient, amount);
        return true;
    }

    // -------- OPTIONAL FUNCTIONS --------
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[msg.sender][spender];
        _allowances[msg.sender][spender] = currentAllowance + addedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[msg.sender][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _allowances[msg.sender][spender] = currentAllowance - subtractedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    // -------- INTERNAL FUNCTIONS --------
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to zero address");
        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from zero address");
        require(_balances[account] >= amount, "ERC20: insufficient balance");
        _balances[account] -= amount;
        _totalSupply -= amount;
        emit Transfer(account, address(0), amount);
    }

    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from zero address");
        require(spender != address(0), "ERC20: approve to zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = _allowances[owner][spender];
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            _allowances[owner][spender] = currentAllowance - amount;
        }
    }
}

// ============================================================================
// CONTRACT: ERC20Mintable
// ============================================================================

/**
 * @title ERC20Mintable
 * @dev ERC-20 with minting capability
 */
contract ERC20Mintable is ERC20 {
    // -------- STATE VARIABLES --------
    address public minter;
    mapping(address => bool) public minters;

    // -------- EVENTS --------
    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);
    event TokensMinted(address indexed to, uint256 amount);
    event TokensBurned(address indexed from, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) ERC20(_name, _symbol, _decimals, _initialSupply) {
        minter = msg.sender;
        minters[msg.sender] = true;
    }

    // -------- MODIFIERS --------
    modifier onlyMinter() {
        require(minters[msg.sender], "Not a minter");
        _;
    }

    // -------- MINTING FUNCTIONS --------
    function mint(address account, uint256 amount) public onlyMinter {
        require(account != address(0), "ERC20: mint to zero address");
        _mint(account, amount);
        emit TokensMinted(account, amount);
    }

    function mintBatch(address[] memory accounts, uint256[] memory amounts) public onlyMinter {
        require(accounts.length == amounts.length, "Arrays length mismatch");
        for (uint256 i = 0; i < accounts.length; i++) {
            require(accounts[i] != address(0), "ERC20: mint to zero address");
            _mint(accounts[i], amounts[i]);
            emit TokensMinted(accounts[i], amounts[i]);
        }
    }

    // -------- BURNING FUNCTIONS --------
    function burn(uint256 amount) public {
        require(_balances[msg.sender] >= amount, "ERC20: insufficient balance");
        _burn(msg.sender, amount);
        emit TokensBurned(msg.sender, amount);
    }

    function burnFrom(address account, uint256 amount) public {
        _spendAllowance(account, msg.sender, amount);
        _burn(account, amount);
        emit TokensBurned(account, amount);
    }

    // -------- MINTER MANAGEMENT --------
    function addMinter(address account) public onlyMinter {
        require(account != address(0), "Invalid address");
        require(!minters[account], "Already a minter");
        minters[account] = true;
        emit MinterAdded(account);
    }

    function removeMinter(address account) public onlyMinter {
        require(minters[account], "Not a minter");
        require(account != minter, "Cannot remove primary minter");
        minters[account] = false;
        emit MinterRemoved(account);
    }

    // -------- VIEW FUNCTIONS --------
    function isMinter(address account) public view returns (bool) {
        return minters[account];
    }

    function getMinters() public view returns (address[] memory) {
        // This is simplified; in practice you'd maintain a list
        address[] memory minterList = new address[](1);
        minterList[0] = minter;
        return minterList;
    }

    function getDecimals() public view returns (uint8) {
        return decimals;
    }
}

// ============================================================================
// CONTRACT: ERC20Burnable
// ============================================================================

/**
 * @title ERC20Burnable
 * @dev ERC-20 with burn capability
 */
contract ERC20Burnable is ERC20 {
    // -------- EVENTS --------
    event TokensBurned(address indexed from, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) ERC20(_name, _symbol, _decimals, _initialSupply) {}

    // -------- BURNING FUNCTIONS --------
    function burn(uint256 amount) public {
        require(_balances[msg.sender] >= amount, "ERC20: insufficient balance");
        _burn(msg.sender, amount);
        emit TokensBurned(msg.sender, amount);
    }

    function burnFrom(address account, uint256 amount) public {
        _spendAllowance(account, msg.sender, amount);
        _burn(account, amount);
        emit TokensBurned(account, amount);
    }
}

// ============================================================================
// CONTRACT: ERC20Pausable
// ============================================================================

/**
 * @title ERC20Pausable
 * @dev ERC-20 with pause functionality
 */
contract ERC20Pausable is ERC20 {
    // -------- STATE VARIABLES --------
    bool public paused;
    address public pauser;

    // -------- EVENTS --------
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier whenNotPaused() {
        require(!paused, "ERC20Pausable: paused");
        _;
    }

    modifier onlyPauser() {
        require(msg.sender == pauser, "Not pauser");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) ERC20(_name, _symbol, _decimals, _initialSupply) {
        pauser = msg.sender;
    }

    // -------- OVERRIDES --------
    function transfer(address recipient, uint256 amount) public override whenNotPaused returns (bool) {
        return super.transfer(recipient, amount);
    }

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override whenNotPaused returns (bool) {
        return super.transferFrom(sender, recipient, amount);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public onlyPauser {
        require(!paused, "Already paused");
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyPauser {
        require(paused, "Not paused");
        paused = false;
        emit Unpaused(msg.sender);
    }

    function setPauser(address newPauser) public onlyPauser {
        require(newPauser != address(0), "Invalid address");
        pauser = newPauser;
    }
}

// ============================================================================
// CONTRACT: ERC20Snapshot
// ============================================================================

/**
 * @title ERC20Snapshot
 * @dev ERC-20 with snapshot functionality
 */
contract ERC20Snapshot is ERC20 {
    // -------- STATE VARIABLES --------
    struct Snapshot {
        uint256 id;
        uint256[] balances;
    }

    mapping(uint256 => Snapshot) public snapshots;
    uint256 public snapshotCount;

    // -------- EVENTS --------
    event SnapshotTaken(uint256 indexed id, uint256 timestamp);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) ERC20(_name, _symbol, _decimals, _initialSupply) {}

    // -------- SNAPSHOT FUNCTIONS --------
    function takeSnapshot() public returns (uint256) {
        snapshotCount++;
        uint256 id = snapshotCount;

        // Store current balances of all holders
        // In practice, this would require maintaining a list of holders
        snapshots[id].id = id;

        emit SnapshotTaken(id, block.timestamp);
        return id;
    }

    function getSnapshotTotalSupply(uint256 id) public view returns (uint256) {
        // In practice, would retrieve stored supply
        return totalSupply();
    }
}

// ============================================================================
// CONTRACT: ERC20Capped
// ============================================================================

/**
 * @title ERC20Capped
 * @dev ERC-20 with supply cap
 */
contract ERC20Capped is ERC20 {
    // -------- STATE VARIABLES --------
    uint256 public cap;

    // -------- EVENTS --------
    event CapSet(uint256 oldCap, uint256 newCap);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply,
        uint256 _cap
    ) ERC20(_name, _symbol, _decimals, _initialSupply) {
        require(_cap >= _initialSupply, "Cap below initial supply");
        cap = _cap;
    }

    // -------- OVERRIDES --------
    function mint(address account, uint256 amount) public virtual {
        require(totalSupply() + amount <= cap, "ERC20Capped: cap exceeded");
        _mint(account, amount);
    }

    function setCap(uint256 newCap) public {
        // In practice, would require admin/owner
        require(newCap >= totalSupply(), "Cap below current supply");
        uint256 oldCap = cap;
        cap = newCap;
        emit CapSet(oldCap, newCap);
    }
}

ERC-777

ERC-777 is an improved token standard that adds features to ERC-20 while maintaining backward compatibility.

ERC-777 Features:

FeatureDescription
Send/Receive HooksNotify contracts on transfers
OperatorDesignated address can send on behalf
Backward CompatibleWorks with ERC-20
EventsMore detailed event logging

Code Example – ERC-777:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC777
// ============================================================================

/**
 * @title IERC777
 * @dev ERC-777 token interface (advanced token standard)
 */
interface IERC777 {
    // -------- VIEW FUNCTIONS --------
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
    function granularity() external view returns (uint256);

    // -------- OPERATOR FUNCTIONS --------
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
    function authorizeOperator(address operator) external;
    function revokeOperator(address operator) external;

    // -------- TOKEN FUNCTIONS --------
    function send(address recipient, uint256 amount, bytes calldata data) external;
    function burn(uint256 amount, bytes calldata data) external;

    // -------- EVENTS --------
    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );
    event Minted(
        address indexed operator,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );
    event Burned(
        address indexed operator,
        address indexed from,
        uint256 amount,
        bytes data,
        bytes operatorData
    );
    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

// ============================================================================
// INTERFACE: IERC777Recipient
// ============================================================================

/**
 * @title IERC777Recipient
 * @dev Interface for contracts that want to receive ERC-777 tokens
 */
interface IERC777Recipient {
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;
}

// ============================================================================
// INTERFACE: IERC777Sender
// ============================================================================

/**
 * @title IERC777Sender
 * @dev Interface for contracts that want to send ERC-777 tokens
 */
interface IERC777Sender {
    function tokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;
}

// ============================================================================
// CONTRACT: ERC777
// ============================================================================

/**
 * @title ERC777
 * @dev Complete ERC-777 implementation with hooks
 */
contract ERC777 is IERC777 {
    // -------- STATE VARIABLES --------
    string private _name;
    string private _symbol;
    uint256 private _totalSupply;
    uint256 private _granularity = 1;

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => bool)) private _operators;
    mapping(address => bool) private _defaultOperators;

    mapping(address => bool) private _isContract;

    // -------- CONSTRUCTOR --------
    constructor(
        string memory name_,
        string memory symbol_,
        address[] memory defaultOperators_
    ) {
        _name = name_;
        _symbol = symbol_;

        for (uint256 i = 0; i < defaultOperators_.length; i++) {
            _defaultOperators[defaultOperators_[i]] = true;
        }
    }

    // -------- VIEW FUNCTIONS --------
    function name() public view override returns (string memory) {
        return _name;
    }

    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    function totalSupply() public view override returns (uint256) {
        return _totalSupply;
    }

    function balanceOf(address owner) public view override returns (uint256) {
        return _balances[owner];
    }

    function granularity() public view override returns (uint256) {
        return _granularity;
    }

    function isOperatorFor(address operator, address tokenHolder) public view override returns (bool) {
        return _operators[tokenHolder][operator] || _defaultOperators[operator];
    }

    // -------- OPERATOR MANAGEMENT --------
    function authorizeOperator(address operator) public override {
        require(operator != msg.sender, "ERC777: authorizing self");
        _operators[msg.sender][operator] = true;
        emit AuthorizedOperator(operator, msg.sender);
    }

    function revokeOperator(address operator) public override {
        require(_operators[msg.sender][operator], "ERC777: operator not authorized");
        delete _operators[msg.sender][operator];
        emit RevokedOperator(operator, msg.sender);
    }

    function defaultOperators() public view returns (address[] memory) {
        // Return list of default operators (simplified)
        address[] memory operators = new address[](1);
        operators[0] = address(0);
        return operators;
    }

    // -------- SEND FUNCTIONS --------
    function send(address recipient, uint256 amount, bytes calldata data) public override {
        _send(msg.sender, recipient, amount, data, "");
    }

    function sendWithOperator(
        address from,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) public {
        require(isOperatorFor(msg.sender, from), "ERC777: not authorized");
        _send(from, recipient, amount, data, operatorData);
    }

    function _send(
        address from,
        address to,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    ) internal {
        require(from != address(0), "ERC777: transfer from zero address");
        require(to != address(0), "ERC777: transfer to zero address");
        require(amount > 0, "ERC777: transfer amount must be > 0");
        require(_balances[from] >= amount, "ERC777: insufficient balance");

        // Call tokensToSend hook
        if (_isContract[from]) {
            IERC777Sender(from).tokensToSend(msg.sender, from, to, amount, data, operatorData);
        }

        // Update balances
        _balances[from] -= amount;
        _balances[to] += amount;

        // Call tokensReceived hook
        if (_isContract[to]) {
            IERC777Recipient(to).tokensReceived(msg.sender, from, to, amount, data, operatorData);
        }

        emit Sent(msg.sender, from, to, amount, data, operatorData);
        emit Transfer(from, to, amount);
    }

    // -------- BURN FUNCTIONS --------
    function burn(uint256 amount, bytes calldata data) public override {
        _burn(msg.sender, amount, data, "");
    }

    function burnWithOperator(
        address from,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) public {
        require(isOperatorFor(msg.sender, from), "ERC777: not authorized");
        _burn(from, amount, data, operatorData);
    }

    function _burn(
        address from,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    ) internal {
        require(from != address(0), "ERC777: burn from zero address");
        require(_balances[from] >= amount, "ERC777: insufficient balance");

        // Call tokensToSend hook
        if (_isContract[from]) {
            IERC777Sender(from).tokensToSend(msg.sender, from, address(0), amount, data, operatorData);
        }

        // Update balances
        _balances[from] -= amount;
        _totalSupply -= amount;

        emit Burned(msg.sender, from, amount, data, operatorData);
        emit Transfer(from, address(0), amount);
    }

    // -------- MINT FUNCTIONS --------
    function _mint(
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    ) internal {
        require(account != address(0), "ERC777: mint to zero address");
        require(amount > 0, "ERC777: mint amount must be > 0");

        // Update balances
        _balances[account] += amount;
        _totalSupply += amount;

        // Call tokensReceived hook
        if (_isContract[account]) {
            IERC777Recipient(account).tokensReceived(
                msg.sender,
                address(0),
                account,
                amount,
                userData,
                operatorData
            );
        }

        emit Minted(msg.sender, account, amount, userData, operatorData);
        emit Transfer(address(0), account, amount);
    }

    // -------- HELPER FUNCTIONS --------
    function _setContract(address account) internal {
        _isContract[account] = true;
    }

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 amount);
}

// ============================================================================
// CONTRACT: ERC777Token
// ============================================================================

/**
 * @title ERC777Token
 * @dev Extended ERC-777 implementation with initial supply
 */
contract ERC777Token is ERC777 {
    // -------- CONSTRUCTOR --------
    constructor(
        string memory name_,
        string memory symbol_,
        address[] memory defaultOperators_,
        uint256 initialSupply,
        address initialHolder
    ) ERC777(name_, symbol_, defaultOperators_) {
        if (initialSupply > 0) {
            _mint(initialHolder, initialSupply, "", "");
        }
    }

    // -------- MINT FUNCTIONS --------
    function mint(
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    ) public {
        // In practice, would require minter role
        _mint(account, amount, userData, operatorData);
    }
}

// ============================================================================
// CONTRACT: ERC777RecipientMock
// ============================================================================

/**
 * @title ERC777RecipientMock
 * @dev Example ERC-777 recipient contract
 */
contract ERC777RecipientMock is IERC777Recipient {
    uint256 public receivedAmount;
    address public receivedOperator;
    address public receivedFrom;
    bytes public receivedData;

    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external override {
        receivedAmount = amount;
        receivedOperator = operator;
        receivedFrom = from;
        receivedData = data;
    }

    function getReceivedInfo() public view returns (uint256, address, address, bytes memory) {
        return (receivedAmount, receivedOperator, receivedFrom, receivedData);
    }

    function resetReceived() public {
        receivedAmount = 0;
        receivedOperator = address(0);
        receivedFrom = address(0);
        receivedData = "";
    }
}

// ============================================================================
// CONTRACT: ERC777SenderMock
// ============================================================================

/**
 * @title ERC777SenderMock
 * @dev Example ERC-777 sender contract
 */
contract ERC777SenderMock is IERC777Sender {
    bool public hookCalled;

    function tokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external override {
        hookCalled = true;
        require(amount > 0, "Amount must be positive");
    }

    function isHookCalled() public view returns (bool) {
        return hookCalled;
    }

    function resetHook() public {
        hookCalled = false;
    }
}

// ============================================================================
// CONTRACT: ERC777Pausable
// ============================================================================

/**
 * @title ERC777Pausable
 * @dev ERC-777 with pause functionality
 */
contract ERC777Pausable is ERC777 {
    // -------- STATE VARIABLES --------
    bool public paused;
    address public pauser;

    // -------- EVENTS --------
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier whenNotPaused() {
        require(!paused, "ERC777Pausable: paused");
        _;
    }

    modifier onlyPauser() {
        require(msg.sender == pauser, "Not pauser");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(
        string memory name_,
        string memory symbol_,
        address[] memory defaultOperators_
    ) ERC777(name_, symbol_, defaultOperators_) {
        pauser = msg.sender;
    }

    // -------- OVERRIDES --------
    function send(address recipient, uint256 amount, bytes calldata data) public override whenNotPaused {
        super.send(recipient, amount, data);
    }

    function burn(uint256 amount, bytes calldata data) public override whenNotPaused {
        super.burn(amount, data);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public onlyPauser {
        require(!paused, "Already paused");
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyPauser {
        require(paused, "Not paused");
        paused = false;
        emit Unpaused(msg.sender);
    }

    function setPauser(address newPauser) public onlyPauser {
        require(newPauser != address(0), "Invalid address");
        pauser = newPauser;
    }
}

ERC-4626

ERC-4626 is the tokenized vault standard. It standardizes yield-bearing vaults where users deposit assets and receive shares.

ERC-4626 Functions:

FunctionDescription
asset()Underlying asset
totalAssets()Total assets controlled
convertToShares()Convert assets to shares
convertToAssets()Convert shares to assets
deposit()Deposit assets
withdraw()Withdraw assets

Code Example – ERC-4626:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC4626
// ============================================================================

/**
 * @title IERC4626
 * @dev ERC-4626 Tokenized Vault Standard interface
 */
interface IERC4626 {
    // -------- ASSET FUNCTIONS --------
    function asset() external view returns (address assetTokenAddress);

    // -------- ASSET MANAGEMENT --------
    function totalAssets() external view returns (uint256 totalManagedAssets);

    // -------- CONVERSION FUNCTIONS --------
    function convertToShares(uint256 assets) external view returns (uint256 shares);
    function convertToAssets(uint256 shares) external view returns (uint256 assets);

    // -------- DEPOSIT FUNCTIONS --------
    function maxDeposit(address receiver) external view returns (uint256 maxAssets);
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    // -------- WITHDRAW FUNCTIONS --------
    function maxWithdraw(address owner) external view returns (uint256 maxAssets);
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    // -------- EVENTS --------
    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);
    event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);
}

// ============================================================================
// INTERFACE: IERC20
// ============================================================================

/**
 * @title IERC20
 * @dev Basic ERC-20 interface for asset token
 */
interface IERC20 {
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// ============================================================================
// CONTRACT: ERC4626
// ============================================================================

/**
 * @title ERC4626
 * @dev Simple ERC-4626 Tokenized Vault implementation
 */
contract ERC4626 is IERC4626 {
    using Address for address;

    // -------- STATE VARIABLES --------
    address public immutable asset;
    string public name;
    string public symbol;
    uint8 public decimals;

    uint256 private _totalSupply;
    uint256 private _totalAssets;

    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    // -------- CONSTRUCTOR --------
    constructor(
        address _asset,
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        require(_asset != address(0), "ERC4626: invalid asset");
        asset = _asset;
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    // -------- VIEW FUNCTIONS --------
    function totalAssets() public view override returns (uint256) {
        return _totalAssets;
    }

    function convertToShares(uint256 assets) public view override returns (uint256) {
        uint256 supply = _totalSupply;
        return supply == 0 ? assets : (assets * supply) / _totalAssets;
    }

    function convertToAssets(uint256 shares) public view override returns (uint256) {
        uint256 supply = _totalSupply;
        return supply == 0 ? shares : (shares * _totalAssets) / supply;
    }

    function maxDeposit(address) public view override returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view override returns (uint256) {
        return convertToAssets(_balances[owner]);
    }

    function balanceOf(address owner) public view returns (uint256) {
        return _balances[owner];
    }

    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    // -------- DEPOSIT FUNCTIONS --------
    function deposit(uint256 assets, address receiver) public override returns (uint256) {
        require(assets > 0, "ERC4626: deposit zero");
        require(receiver != address(0), "ERC4626: invalid receiver");

        uint256 shares = convertToShares(assets);
        require(shares > 0, "ERC4626: zero shares");

        // Transfer assets from caller to vault
        IERC20(asset).transferFrom(msg.sender, address(this), assets);

        // Update state
        _totalAssets += assets;
        _balances[receiver] += shares;
        _totalSupply += shares;

        emit Deposit(msg.sender, receiver, assets, shares);
        emit Transfer(address(0), receiver, shares);

        return shares;
    }

    function depositWithPermit(
        uint256 assets,
        address receiver,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public returns (uint256) {
        // In practice, would use permit function
        return deposit(assets, receiver);
    }

    // -------- WITHDRAW FUNCTIONS --------
    function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256) {
        require(assets > 0, "ERC4626: withdraw zero");
        require(receiver != address(0), "ERC4626: invalid receiver");

        uint256 shares = convertToShares(assets);
        require(_balances[owner] >= shares, "ERC4626: insufficient balance");

        // Check allowance if not owner
        if (owner != msg.sender) {
            require(_allowances[owner][msg.sender] >= shares, "ERC4626: insufficient allowance");
            _allowances[owner][msg.sender] -= shares;
        }

        // Update state before transfer
        _balances[owner] -= shares;
        _totalSupply -= shares;
        _totalAssets -= assets;

        // Transfer assets to receiver
        IERC20(asset).transfer(receiver, assets);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);
        emit Transfer(owner, address(0), shares);

        return shares;
    }

    // -------- ALLOWANCE FUNCTIONS --------
    function approve(address spender, uint256 amount) public returns (bool) {
        require(spender != address(0), "ERC4626: approve to zero address");
        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        uint256 currentAllowance = _allowances[msg.sender][spender];
        _allowances[msg.sender][spender] = currentAllowance + addedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        uint256 currentAllowance = _allowances[msg.sender][spender];
        require(currentAllowance >= subtractedValue, "ERC4626: decreased allowance below zero");
        _allowances[msg.sender][spender] = currentAllowance - subtractedValue;
        emit Approval(msg.sender, spender, _allowances[msg.sender][spender]);
        return true;
    }

    // -------- INTERNAL FUNCTIONS --------
    function _mint(address account, uint256 shares) internal {
        require(account != address(0), "ERC4626: mint to zero address");
        _totalSupply += shares;
        _balances[account] += shares;
        emit Transfer(address(0), account, shares);
    }

    function _burn(address account, uint256 shares) internal {
        require(account != address(0), "ERC4626: burn from zero address");
        require(_balances[account] >= shares, "ERC4626: insufficient balance");
        _balances[account] -= shares;
        _totalSupply -= shares;
        emit Transfer(account, address(0), shares);
    }
}

// ============================================================================
// CONTRACT: ERC4626Vault
// ============================================================================

/**
 * @title ERC4626Vault
 * @dev Extended ERC-4626 vault with performance fees and management
 */
contract ERC4626Vault is ERC4626 {
    // -------- STATE VARIABLES --------
    address public manager;
    uint256 public managementFee;
    uint256 public performanceFee;
    uint256 public feeRecipient;
    uint256 public lastFeeTime;

    // -------- EVENTS --------
    event FeeCharged(uint256 managementFee, uint256 performanceFee);
    event ManagerChanged(address indexed oldManager, address indexed newManager);
    event FeesUpdated(uint256 managementFee, uint256 performanceFee);

    // -------- MODIFIERS --------
    modifier onlyManager() {
        require(msg.sender == manager, "Only manager");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(
        address _asset,
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _managementFee,
        uint256 _performanceFee
    ) ERC4626(_asset, _name, _symbol, _decimals) {
        manager = msg.sender;
        managementFee = _managementFee;
        performanceFee = _performanceFee;
        lastFeeTime = block.timestamp;
        feeRecipient = msg.sender;
    }

    // -------- OVERRIDES --------
    function totalAssets() public view override returns (uint256) {
        return _totalAssets;
    }

    function deposit(uint256 assets, address receiver) public override returns (uint256) {
        _chargeFees();
        return super.deposit(assets, receiver);
    }

    function withdraw(uint256 assets, address receiver, address owner) public override returns (uint256) {
        _chargeFees();
        return super.withdraw(assets, receiver, owner);
    }

    // -------- FEE FUNCTIONS --------
    function _chargeFees() internal {
        if (block.timestamp > lastFeeTime + 1 days) {
            uint256 feeAmount = (_totalAssets * managementFee) / 10000;
            if (feeAmount > 0) {
                _totalAssets -= feeAmount;
                // In practice, would mint shares to fee recipient
            }
            lastFeeTime = block.timestamp;
            emit FeeCharged(feeAmount, 0);
        }
    }

    // -------- MANAGER FUNCTIONS --------
    function setManager(address newManager) public onlyManager {
        require(newManager != address(0), "Invalid manager");
        address oldManager = manager;
        manager = newManager;
        emit ManagerChanged(oldManager, newManager);
    }

    function setFees(uint256 newManagementFee, uint256 newPerformanceFee) public onlyManager {
        managementFee = newManagementFee;
        performanceFee = newPerformanceFee;
        emit FeesUpdated(newManagementFee, newPerformanceFee);
    }

    function setFeeRecipient(address newRecipient) public onlyManager {
        require(newRecipient != address(0), "Invalid recipient");
        feeRecipient = newRecipient;
    }

    // -------- VIEW FUNCTIONS --------
    function getFees() public view returns (uint256, uint256, address) {
        return (managementFee, performanceFee, feeRecipient);
    }

    function getManager() public view returns (address) {
        return manager;
    }
}

// ============================================================================
// LIBRARY: Address
// ============================================================================

/**
 * @title Address
 * @dev Address utilities
 */
library Address {
    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");
        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value");
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");
        (bool success, bytes memory returndata) = target.call(data);
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// ============================================================================
// CONTRACT: ERC4626Mock
// ============================================================================

/**
 * @title ERC4626Mock
 * @dev Mock ERC-4626 vault for testing
 */
contract ERC4626Mock is ERC4626 {
    // -------- CONSTRUCTOR --------
    constructor(
        address _asset,
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) ERC4626(_asset, _name, _symbol, _decimals) {}

    // -------- MOCK FUNCTIONS --------
    function setTotalAssets(uint256 newTotal) public {
        _totalAssets = newTotal;
    }

    function mintShares(address account, uint256 shares) public {
        _mint(account, shares);
    }

    function burnShares(address account, uint256 shares) public {
        _burn(account, shares);
    }

    function forceTransfer(address from, address to, uint256 shares) public {
        require(_balances[from] >= shares, "Insufficient balance");
        _balances[from] -= shares;
        _balances[to] += shares;
        emit Transfer(from, to, shares);
    }
}

NFTs

ERC-721

ERC-721 is the standard for Non-Fungible Tokens (NFTs) on Ethereum. Each token is unique and represents a distinct digital asset that cannot be exchanged on a one-to-one basis with another token.

ERC-721 Features:

FeatureDescription
Unique TokensEach token has unique ID
OwnershipTrack owner of each token
TransferTransfer ownership
ApprovalApprove addresses to transfer

Real-World Example:

  • CryptoPunks
  • Bored Ape Yacht Club
  • Digital art, collectibles

Code Example – ERC-721:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC721
// ============================================================================

/**
 * @title IERC721
 * @dev ERC-721 Non-Fungible Token standard interface
 */
interface IERC721 {
    // -------- VIEW FUNCTIONS --------
    function balanceOf(address owner) external view returns (uint256);
    function ownerOf(uint256 tokenId) external view returns (address);
    function getApproved(uint256 tokenId) external view returns (address);
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    // -------- STATE-CHANGING FUNCTIONS --------
    function transferFrom(address from, address to, uint256 tokenId) external;
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function setApprovalForAll(address operator, bool approved) external;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
}

// ============================================================================
// INTERFACE: IERC721Metadata
// ============================================================================

/**
 * @title IERC721Metadata
 * @dev ERC-721 Metadata extension
 */
interface IERC721Metadata {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// ============================================================================
// INTERFACE: IERC721Receiver
// ============================================================================

/**
 * @title IERC721Receiver
 * @dev ERC-721 Token Receiver interface
 */
interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

// ============================================================================
// CONTRACT: ERC721
// ============================================================================

/**
 * @title ERC721
 * @dev Complete ERC-721 implementation
 */
contract ERC721 is IERC721, IERC721Metadata {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;

    mapping(uint256 => address) private _owners;
    mapping(address => uint256) private _balances;
    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    // -------- VIEW FUNCTIONS --------
    function balanceOf(address owner) public view override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for zero address");
        return _balances[owner];
    }

    function ownerOf(uint256 tokenId) public view override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    function getApproved(uint256 tokenId) public view override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");
        return _tokenApprovals[tokenId];
    }

    function isApprovedForAll(address owner, address operator) public view override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721: URI query for nonexistent token");
        return string(abi.encodePacked("https://api.example.com/token/", Strings.toString(tokenId)));
    }

    function _exists(uint256 tokenId) internal view returns (bool) {
        return _owners[tokenId] != address(0);
    }

    // -------- APPROVAL FUNCTIONS --------
    function approve(address to, uint256 tokenId) public override {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");
        require(msg.sender == owner || isApprovedForAll(owner, msg.sender), "ERC721: not authorized");

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    function setApprovalForAll(address operator, bool approved) public override {
        require(operator != msg.sender, "ERC721: approve to caller");
        _operatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    // -------- TRANSFER FUNCTIONS --------
    function transferFrom(address from, address to, uint256 tokenId) public override {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller not approved");
        require(to != address(0), "ERC721: transfer to zero address");
        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller not approved");
        require(to != address(0), "ERC721: transfer to zero address");
        _safeTransfer(from, to, tokenId, data);
    }

    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(msg.sender, from, to, tokenId, data), "ERC721: transfer to non-receiver");
    }

    function _transfer(address from, address to, uint256 tokenId) internal {
        address owner = ownerOf(tokenId);
        require(from == owner, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to zero address");

        // Clear approvals
        delete _tokenApprovals[tokenId];

        // Update balances
        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    // -------- INTERNAL FUNCTIONS --------
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    function _checkOnERC721Received(
        address operator,
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal returns (bool) {
        if (to.code.length == 0) {
            return true;
        }

        try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) {
            return retval == IERC721Receiver.onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert("ERC721: transfer to non-receiver");
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // -------- MINT FUNCTIONS --------
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    // -------- BURN FUNCTIONS --------
    function _burn(uint256 tokenId) internal {
        address owner = ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        // Update balances
        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }
}

// ============================================================================
// CONTRACT: ERC721Enumerable
// ============================================================================

/**
 * @title ERC721Enumerable
 * @dev ERC-721 with enumeration extension
 */
contract ERC721Enumerable is ERC721 {
    // -------- STATE VARIABLES --------
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
    mapping(uint256 => uint256) private _ownedTokensIndex;
    uint256[] private _allTokens;
    mapping(uint256 => uint256) private _allTokensIndex;

    // -------- VIEW FUNCTIONS --------
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: index out of bounds");
        return _allTokens[index];
    }

    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: index out of bounds");
        return _ownedTokens[owner][index];
    }

    // -------- INTERNAL FUNCTIONS --------
    function _addTokenToOwner(address to, uint256 tokenId) internal {
        uint256 length = balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    function _removeTokenFromOwner(address from, uint256 tokenId) internal {
        uint256 lastTokenIndex = balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
            _ownedTokens[from][tokenIndex] = lastTokenId;
            _ownedTokensIndex[lastTokenId] = tokenIndex;
        }

        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    function _addTokenToAll(uint256 tokenId) internal {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    function _removeTokenFromAll(uint256 tokenId) internal {
        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _allTokens[lastTokenIndex];
            _allTokens[tokenIndex] = lastTokenId;
            _allTokensIndex[lastTokenId] = tokenIndex;
        }

        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }

    function _mint(address to, uint256 tokenId) internal override {
        super._mint(to, tokenId);
        _addTokenToOwner(to, tokenId);
        _addTokenToAll(tokenId);
    }

    function _burn(uint256 tokenId) internal override {
        address owner = ownerOf(tokenId);
        _removeTokenFromOwner(owner, tokenId);
        _removeTokenFromAll(tokenId);
        super._burn(tokenId);
    }

    function _transfer(address from, address to, uint256 tokenId) internal override {
        super._transfer(from, to, tokenId);
        _removeTokenFromOwner(from, tokenId);
        _addTokenToOwner(to, tokenId);
    }
}

// ============================================================================
// CONTRACT: ERC721URIStorage
// ============================================================================

/**
 * @title ERC721URIStorage
 * @dev ERC-721 with URI storage
 */
contract ERC721URIStorage is ERC721 {
    mapping(uint256 => string) private _tokenURIs;

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
        string memory _tokenURI = _tokenURIs[tokenId];

        if (bytes(_tokenURI).length > 0) {
            return _tokenURI;
        }

        return super.tokenURI(tokenId);
    }

    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    function _burn(uint256 tokenId) internal override {
        super._burn(tokenId);
        if (bytes(_tokenURIs[tokenId]).length > 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// ============================================================================
// CONTRACT: ERC721Pausable
// ============================================================================

/**
 * @title ERC721Pausable
 * @dev ERC-721 with pause functionality
 */
contract ERC721Pausable is ERC721 {
    // -------- STATE VARIABLES --------
    bool public paused;
    address public pauser;

    // -------- EVENTS --------
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier whenNotPaused() {
        require(!paused, "ERC721Pausable: paused");
        _;
    }

    modifier onlyPauser() {
        require(msg.sender == pauser, "Not pauser");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {
        pauser = msg.sender;
    }

    // -------- OVERRIDES --------
    function transferFrom(address from, address to, uint256 tokenId) public override whenNotPaused {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override whenNotPaused {
        super.safeTransferFrom(from, to, tokenId);
    }

    function approve(address to, uint256 tokenId) public override whenNotPaused {
        super.approve(to, tokenId);
    }

    function setApprovalForAll(address operator, bool approved) public override whenNotPaused {
        super.setApprovalForAll(operator, approved);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public onlyPauser {
        require(!paused, "Already paused");
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyPauser {
        require(paused, "Not paused");
        paused = false;
        emit Unpaused(msg.sender);
    }

    function setPauser(address newPauser) public onlyPauser {
        require(newPauser != address(0), "Invalid address");
        pauser = newPauser;
    }
}

// ============================================================================
// LIBRARY: Strings
// ============================================================================

/**
 * @title Strings
 * @dev String utilities
 */
library Strings {
    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) return "0";

        uint256 temp = value;
        uint256 digits;

        while (temp != 0) {
            digits++;
            temp /= 10;
        }

        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + (value % 10)));
            value /= 10;
        }

        return string(buffer);
    }

    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) return "0x0";

        uint256 length = 0;
        uint256 temp = value;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }

        bytes memory buffer = new bytes(length * 2 + 2);
        buffer[0] = "0";
        buffer[1] = "x";

        for (uint256 i = 0; i < length; i++) {
            uint8 byteValue = uint8(value >> (8 * (length - i - 1)));
            buffer[2 + i * 2] = _toHexChar(byteValue >> 4);
            buffer[3 + i * 2] = _toHexChar(byteValue & 0x0F);
        }

        return string(buffer);
    }

    function _toHexChar(uint8 value) private pure returns (bytes1) {
        if (value < 10) {
            return bytes1(uint8(48 + value));
        } else {
            return bytes1(uint8(87 + value));
        }
    }
}

ERC-1155

ERC-1155 is a multi-token standard that combines ERC-20 and ERC-721. It allows for both fungible and non-fungible tokens in a single contract.

ERC-1155 Features:

FeatureDescription
Multi-TokenBoth fungible and non-fungible
Batch OperationsTransfer multiple tokens at once
Gas EfficientSingle contract for multiple tokens
MetadataURI for each token type

Real-World Example:

  • Gaming items (weapons, armor, currency)
  • Multiple assets in one contract

Code Example – ERC-1155:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC1155
// ============================================================================

/**
 * @title IERC1155
 * @dev ERC-1155 Multi-Token standard interface
 */
interface IERC1155 {
    // -------- VIEW FUNCTIONS --------
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);
    function isApprovedForAll(address account, address operator) external view returns (bool);

    // -------- STATE-CHANGING FUNCTIONS --------
    function setApprovalForAll(address operator, bool approved) external;
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;

    // -------- EVENTS --------
    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 value
    );
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );
    event ApprovalForAll(
        address indexed account,
        address indexed operator,
        bool approved
    );
    event URI(string value, uint256 indexed id);
}

// ============================================================================
// INTERFACE: IERC1155Receiver
// ============================================================================

/**
 * @title IERC1155Receiver
 * @dev ERC-1155 Token Receiver interface
 */
interface IERC1155Receiver {
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// ============================================================================
// CONTRACT: ERC1155
// ============================================================================

/**
 * @title ERC1155
 * @dev Complete ERC-1155 implementation
 */
contract ERC1155 is IERC1155 {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;

    mapping(uint256 => mapping(address => uint256)) private _balances;
    mapping(address => mapping(address => bool)) private _operatorApprovals;
    mapping(uint256 => string) private _uris;

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    // -------- VIEW FUNCTIONS --------
    function balanceOf(address account, uint256 id) public view override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for zero address");
        return _balances[id][account];
    }

    function balanceOfBatch(
        address[] memory accounts,
        uint256[] memory ids
    ) public view override returns (uint256[] memory) {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);
        for (uint256 i = 0; i < accounts.length; i++) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }
        return batchBalances;
    }

    function isApprovedForAll(address account, address operator) public view override returns (bool) {
        return _operatorApprovals[account][operator];
    }

    function uri(uint256 id) public view returns (string memory) {
        return _uris[id];
    }

    // -------- APPROVAL FUNCTIONS --------
    function setApprovalForAll(address operator, bool approved) public override {
        require(msg.sender != operator, "ERC1155: setting approval for self");
        _operatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    // -------- TRANSFER FUNCTIONS --------
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public override {
        require(to != address(0), "ERC1155: transfer to zero address");
        require(
            from == msg.sender || isApprovedForAll(from, msg.sender),
            "ERC1155: caller not approved"
        );

        _balances[id][from] -= amount;
        _balances[id][to] += amount;

        emit TransferSingle(msg.sender, from, to, id, amount);

        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155Received(msg.sender, from, id, amount, data) returns (bytes4 retval) {
                require(retval == IERC1155Receiver.onERC1155Received.selector, "ERC1155: transfer to non-receiver");
            } catch {
                revert("ERC1155: transfer to non-receiver");
            }
        }
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public override {
        require(to != address(0), "ERC1155: transfer to zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(
            from == msg.sender || isApprovedForAll(from, msg.sender),
            "ERC1155: caller not approved"
        );

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][from] -= amounts[i];
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(msg.sender, from, to, ids, amounts);

        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) returns (bytes4 retval) {
                require(retval == IERC1155Receiver.onERC1155BatchReceived.selector, "ERC1155: batch transfer to non-receiver");
            } catch {
                revert("ERC1155: batch transfer to non-receiver");
            }
        }
    }

    // -------- INTERNAL FUNCTIONS --------
    function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal {
        require(to != address(0), "ERC1155: mint to zero address");

        _balances[id][to] += amount;
        emit TransferSingle(msg.sender, address(0), to, id, amount);

        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) returns (bytes4 retval) {
                require(retval == IERC1155Receiver.onERC1155Received.selector, "ERC1155: mint to non-receiver");
            } catch {
                revert("ERC1155: mint to non-receiver");
            }
        }
    }

    function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal {
        require(to != address(0), "ERC1155: mint to zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(msg.sender, address(0), to, ids, amounts);

        if (to.code.length > 0) {
            try IERC1155Receiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) returns (bytes4 retval) {
                require(retval == IERC1155Receiver.onERC1155BatchReceived.selector, "ERC1155: batch mint to non-receiver");
            } catch {
                revert("ERC1155: batch mint to non-receiver");
            }
        }
    }

    function _burn(address from, uint256 id, uint256 amount) internal {
        require(from != address(0), "ERC1155: burn from zero address");
        require(_balances[id][from] >= amount, "ERC1155: insufficient balance");

        _balances[id][from] -= amount;
        emit TransferSingle(msg.sender, from, address(0), id, amount);
    }

    function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal {
        require(from != address(0), "ERC1155: burn from zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        for (uint256 i = 0; i < ids.length; i++) {
            require(_balances[ids[i]][from] >= amounts[i], "ERC1155: insufficient balance");
            _balances[ids[i]][from] -= amounts[i];
        }

        emit TransferBatch(msg.sender, from, address(0), ids, amounts);
    }

    function _setURI(uint256 id, string memory uri_) internal {
        _uris[id] = uri_;
        emit URI(uri_, id);
    }
}

// ============================================================================
// CONTRACT: ERC1155Burnable
// ============================================================================

/**
 * @title ERC1155Burnable
 * @dev ERC-1155 with burn capability
 */
contract ERC1155Burnable is ERC1155 {
    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) ERC1155(_name, _symbol) {}

    // -------- BURN FUNCTIONS --------
    function burn(address from, uint256 id, uint256 amount) public {
        require(
            from == msg.sender || isApprovedForAll(from, msg.sender),
            "ERC1155: caller not approved"
        );
        _burn(from, id, amount);
    }

    function burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) public {
        require(
            from == msg.sender || isApprovedForAll(from, msg.sender),
            "ERC1155: caller not approved"
        );
        _burnBatch(from, ids, amounts);
    }
}

// ============================================================================
// CONTRACT: ERC1155Pausable
// ============================================================================

/**
 * @title ERC1155Pausable
 * @dev ERC-1155 with pause functionality
 */
contract ERC1155Pausable is ERC1155 {
    // -------- STATE VARIABLES --------
    bool public paused;
    address public pauser;

    // -------- EVENTS --------
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier whenNotPaused() {
        require(!paused, "ERC1155Pausable: paused");
        _;
    }

    modifier onlyPauser() {
        require(msg.sender == pauser, "Not pauser");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) ERC1155(_name, _symbol) {
        pauser = msg.sender;
    }

    // -------- OVERRIDES --------
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public override whenNotPaused {
        super.safeTransferFrom(from, to, id, amount, data);
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public override whenNotPaused {
        super.safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    function setApprovalForAll(address operator, bool approved) public override whenNotPaused {
        super.setApprovalForAll(operator, approved);
    }

    // -------- PAUSE FUNCTIONS --------
    function pause() public onlyPauser {
        require(!paused, "Already paused");
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyPauser {
        require(paused, "Not paused");
        paused = false;
        emit Unpaused(msg.sender);
    }

    function setPauser(address newPauser) public onlyPauser {
        require(newPauser != address(0), "Invalid address");
        pauser = newPauser;
    }
}

// ============================================================================
// CONTRACT: GameItems
// ============================================================================

/**
 * @title GameItems
 * @dev ERC-1155 game items contract
 */
contract GameItems is ERC1155Burnable, ERC1155Pausable {
    // -------- TOKEN TYPES --------
    uint256 public constant SWORD = 1;
    uint256 public constant SHIELD = 2;
    uint256 public constant GOLD_COIN = 3;
    uint256 public constant HEALING_POTION = 4;
    uint256 public constant RARE_SWORD = 5;
    uint256 public constant LEGENDARY_ARMOR = 6;

    // -------- EVENTS --------
    event ItemMinted(address indexed to, uint256 id, uint256 amount);
    event ItemBurned(address indexed from, uint256 id, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor() ERC1155("GameItems", "GITEMS") {
        // Set URIs
        _setURI(SWORD, "https://api.game.com/sword.json");
        _setURI(SHIELD, "https://api.game.com/shield.json");
        _setURI(GOLD_COIN, "https://api.game.com/gold.json");
        _setURI(HEALING_POTION, "https://api.game.com/potion.json");
        _setURI(RARE_SWORD, "https://api.game.com/rare-sword.json");
        _setURI(LEGENDARY_ARMOR, "https://api.game.com/legendary-armor.json");
    }

    // -------- MINT FUNCTIONS --------
    function mintItem(address to, uint256 id, uint256 amount) public whenNotPaused {
        require(id >= 1 && id <= 6, "Invalid item id");
        require(amount > 0, "Amount must be positive");
        _mint(to, id, amount, "");
        emit ItemMinted(to, id, amount);
    }

    function mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts
    ) public whenNotPaused {
        require(ids.length > 0, "Empty ids");
        require(ids.length == amounts.length, "Length mismatch");
        _mintBatch(to, ids, amounts, "");
        for (uint256 i = 0; i < ids.length; i++) {
            emit ItemMinted(to, ids[i], amounts[i]);
        }
    }

    // -------- BURN FUNCTIONS --------
    function burnItem(uint256 id, uint256 amount) public whenNotPaused {
        require(id >= 1 && id <= 6, "Invalid item id");
        require(amount > 0, "Amount must be positive");
        _burn(msg.sender, id, amount);
        emit ItemBurned(msg.sender, id, amount);
    }

    // -------- GAME FUNCTIONS --------
    function craftSword() public whenNotPaused {
        // Craft a sword using resources
        uint256 goldCost = 10;
        _burn(msg.sender, GOLD_COIN, goldCost);
        _mint(msg.sender, SWORD, 1, "");
    }

    function upgradeArmor() public whenNotPaused {
        // Upgrade armor using rare materials
        _burn(msg.sender, SHIELD, 2);
        _mint(msg.sender, LEGENDARY_ARMOR, 1, "");
    }

    function usePotion() public whenNotPaused {
        // Use healing potion
        _burn(msg.sender, HEALING_POTION, 1);
    }

    // -------- VIEW FUNCTIONS --------
    function getItemInfo(uint256 id) public view returns (string memory, uint256) {
        string memory itemName;
        if (id == SWORD) itemName = "Sword";
        else if (id == SHIELD) itemName = "Shield";
        else if (id == GOLD_COIN) itemName = "Gold Coin";
        else if (id == HEALING_POTION) itemName = "Healing Potion";
        else if (id == RARE_SWORD) itemName = "Rare Sword";
        else if (id == LEGENDARY_ARMOR) itemName = "Legendary Armor";
        else revert("Invalid item id");

        return (itemName, balanceOf(msg.sender, id));
    }

    function getAllBalances(address account) public view returns (
        uint256 swords,
        uint256 shields,
        uint256 gold,
        uint256 potions,
        uint256 rareSwords,
        uint256 legendaryArmors
    ) {
        swords = balanceOf(account, SWORD);
        shields = balanceOf(account, SHIELD);
        gold = balanceOf(account, GOLD_COIN);
        potions = balanceOf(account, HEALING_POTION);
        rareSwords = balanceOf(account, RARE_SWORD);
        legendaryArmors = balanceOf(account, LEGENDARY_ARMOR);
    }
}

ERC-2981

ERC-2981 is the NFT Royalty Standard. It allows NFTs to specify royalty payments to creators on secondary sales.

ERC-2981 Features:

FeatureDescription
Royalty InfoGet royalty information
Split PaymentsMultiple recipients
PercentagePercentage-based royalties

Code Example – ERC-2981:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC2981
// ============================================================================

/**
 * @title IERC2981
 * @dev ERC-2981 NFT Royalty Standard interface
 */
interface IERC2981 {
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// ============================================================================
// CONTRACT: ERC2981
// ============================================================================

/**
 * @title ERC2981
 * @dev ERC-2981 NFT Royalty Standard implementation
 */
contract ERC2981 is IERC2981 {
    // -------- STATE VARIABLES --------
    mapping(uint256 => address) private _royaltyReceivers;
    mapping(uint256 => uint256) private _royaltyBPS; // Basis points (1/10000)

    // -------- VIEW FUNCTIONS --------
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        public
        view
        virtual
        override
        returns (address receiver, uint256 royaltyAmount)
    {
        receiver = _royaltyReceivers[tokenId];
        uint256 bps = _royaltyBPS[tokenId];

        if (receiver == address(0) || bps == 0) {
            return (address(0), 0);
        }

        royaltyAmount = (salePrice * bps) / 10000;
        return (receiver, royaltyAmount);
    }

    // -------- INTERNAL FUNCTIONS --------
    function _setRoyalty(uint256 tokenId, address receiver, uint256 bps) internal {
        require(receiver != address(0), "ERC2981: zero receiver");
        require(bps <= 10000, "ERC2981: bps too high");

        _royaltyReceivers[tokenId] = receiver;
        _royaltyBPS[tokenId] = bps;
    }

    function _setDefaultRoyalty(address receiver, uint256 bps) internal {
        require(receiver != address(0), "ERC2981: zero receiver");
        require(bps <= 10000, "ERC2981: bps too high");

        // Use tokenId 0 for default royalty
        _royaltyReceivers[0] = receiver;
        _royaltyBPS[0] = bps;
    }

    function _deleteRoyalty(uint256 tokenId) internal {
        delete _royaltyReceivers[tokenId];
        delete _royaltyBPS[tokenId];
    }
}

// ============================================================================
// CONTRACT: ERC721Royalty
// ============================================================================

/**
 * @title ERC721Royalty
 * @dev ERC-721 with ERC-2981 Royalty support
 */
contract ERC721Royalty is ERC721, ERC2981 {
    // -------- STATE VARIABLES --------
    uint256 private _nextTokenId;
    address public defaultRoyaltyReceiver;
    uint256 public defaultRoyaltyBPS;

    // -------- EVENTS --------
    event RoyaltySet(uint256 indexed tokenId, address receiver, uint256 bps);
    event DefaultRoyaltySet(address receiver, uint256 bps);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        address _royaltyReceiver,
        uint256 _royaltyBPS
    ) ERC721(_name, _symbol) {
        if (_royaltyReceiver != address(0)) {
            _setDefaultRoyalty(_royaltyReceiver, _royaltyBPS);
            defaultRoyaltyReceiver = _royaltyReceiver;
            defaultRoyaltyBPS = _royaltyBPS;
        }
    }

    // -------- MINT FUNCTIONS --------
    function mint(address to) public returns (uint256) {
        _nextTokenId++;
        uint256 tokenId = _nextTokenId;

        // Set royalty for this token
        if (defaultRoyaltyReceiver != address(0)) {
            _setRoyalty(tokenId, defaultRoyaltyReceiver, defaultRoyaltyBPS);
        }

        _mint(to, tokenId);
        return tokenId;
    }

    function mintWithRoyalty(
        address to,
        address royaltyReceiver,
        uint256 royaltyBPS
    ) public returns (uint256) {
        _nextTokenId++;
        uint256 tokenId = _nextTokenId;

        if (royaltyReceiver == address(0)) {
            if (defaultRoyaltyReceiver != address(0)) {
                _setRoyalty(tokenId, defaultRoyaltyReceiver, defaultRoyaltyBPS);
            }
        } else {
            require(royaltyBPS <= 10000, "ERC721Royalty: bps too high");
            _setRoyalty(tokenId, royaltyReceiver, royaltyBPS);
        }

        _mint(to, tokenId);
        return tokenId;
    }

    // -------- ROYALTY FUNCTIONS --------
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        public
        view
        override(ERC2981)
        returns (address receiver, uint256 royaltyAmount)
    {
        // Check if token has custom royalty
        (receiver, royaltyAmount) = super.royaltyInfo(tokenId, salePrice);

        // If no custom royalty, use default
        if (receiver == address(0) && defaultRoyaltyReceiver != address(0)) {
            receiver = defaultRoyaltyReceiver;
            royaltyAmount = (salePrice * defaultRoyaltyBPS) / 10000;
        }

        return (receiver, royaltyAmount);
    }

    function setRoyalty(uint256 tokenId, address receiver, uint256 bps) public {
        require(_exists(tokenId), "ERC721Royalty: token does not exist");
        require(msg.sender == ownerOf(tokenId), "ERC721Royalty: not owner");
        _setRoyalty(tokenId, receiver, bps);
        emit RoyaltySet(tokenId, receiver, bps);
    }

    function setDefaultRoyalty(address receiver, uint256 bps) public {
        require(msg.sender == owner, "ERC721Royalty: not owner");
        _setDefaultRoyalty(receiver, bps);
        defaultRoyaltyReceiver = receiver;
        defaultRoyaltyBPS = bps;
        emit DefaultRoyaltySet(receiver, bps);
    }

    // -------- VIEW FUNCTIONS --------
    function getRoyaltyInfo(uint256 tokenId) public view returns (address, uint256) {
        address receiver = _royaltyReceivers[tokenId];
        uint256 bps = _royaltyBPS[tokenId];

        if (receiver == address(0)) {
            receiver = defaultRoyaltyReceiver;
            bps = defaultRoyaltyBPS;
        }

        return (receiver, bps);
    }

    function getTokenRoyaltyInfo(uint256 tokenId) public view returns (address, uint256) {
        return (_royaltyReceivers[tokenId], _royaltyBPS[tokenId]);
    }
}

// ============================================================================
// CONTRACT: ERC1155Royalty
// ============================================================================

/**
 * @title ERC1155Royalty
 * @dev ERC-1155 with ERC-2981 Royalty support
 */
contract ERC1155Royalty is ERC1155, ERC2981 {
    // -------- STATE VARIABLES --------
    address public defaultRoyaltyReceiver;
    uint256 public defaultRoyaltyBPS;

    // -------- EVENTS --------
    event RoyaltySet(uint256 indexed id, address receiver, uint256 bps);
    event DefaultRoyaltySet(address receiver, uint256 bps);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        address _royaltyReceiver,
        uint256 _royaltyBPS
    ) ERC1155(_name, _symbol) {
        if (_royaltyReceiver != address(0)) {
            _setDefaultRoyalty(_royaltyReceiver, _royaltyBPS);
            defaultRoyaltyReceiver = _royaltyReceiver;
            defaultRoyaltyBPS = _royaltyBPS;
        }
    }

    // -------- MINT FUNCTIONS --------
    function mintWithRoyalty(
        address to,
        uint256 id,
        uint256 amount,
        address royaltyReceiver,
        uint256 royaltyBPS
    ) public {
        if (royaltyReceiver == address(0)) {
            if (defaultRoyaltyReceiver != address(0)) {
                _setRoyalty(id, defaultRoyaltyReceiver, defaultRoyaltyBPS);
            }
        } else {
            require(royaltyBPS <= 10000, "ERC1155Royalty: bps too high");
            _setRoyalty(id, royaltyReceiver, royaltyBPS);
        }
        _mint(to, id, amount, "");
    }

    // -------- ROYALTY FUNCTIONS --------
    function royaltyInfo(uint256 id, uint256 salePrice)
        public
        view
        override(ERC2981)
        returns (address receiver, uint256 royaltyAmount)
    {
        (receiver, royaltyAmount) = super.royaltyInfo(id, salePrice);

        if (receiver == address(0) && defaultRoyaltyReceiver != address(0)) {
            receiver = defaultRoyaltyReceiver;
            royaltyAmount = (salePrice * defaultRoyaltyBPS) / 10000;
        }

        return (receiver, royaltyAmount);
    }

    function setRoyalty(uint256 id, address receiver, uint256 bps) public {
        _setRoyalty(id, receiver, bps);
        emit RoyaltySet(id, receiver, bps);
    }

    function setDefaultRoyalty(address receiver, uint256 bps) public {
        _setDefaultRoyalty(receiver, bps);
        defaultRoyaltyReceiver = receiver;
        defaultRoyaltyBPS = bps;
        emit DefaultRoyaltySet(receiver, bps);
    }
}

// ============================================================================
// CONTRACT: RoyaltyNFT
// ============================================================================

/**
 * @title RoyaltyNFT
 * @dev NFT with royalty support
 */
contract RoyaltyNFT is ERC721Royalty {
    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        address _royaltyReceiver,
        uint256 _royaltyBPS
    ) ERC721Royalty(_name, _symbol, _royaltyReceiver, _royaltyBPS) {}

    // -------- MINT FUNCTIONS --------
    function mint(address to) public override returns (uint256) {
        return super.mint(to);
    }

    function mintWithRoyalty(
        address to,
        address royaltyReceiver,
        uint256 royaltyBPS
    ) public returns (uint256) {
        return super.mintWithRoyalty(to, royaltyReceiver, royaltyBPS);
    }
}

// ============================================================================
// CONTRACT: RoyaltyNFTWithAutoRoyalty
// ============================================================================

/**
 * @title RoyaltyNFTWithAutoRoyalty
 * @dev NFT with automatic royalty on transfer
 */
contract RoyaltyNFTWithAutoRoyalty is ERC721Royalty {
    // -------- STATE VARIABLES --------
    uint256 public constant ROYALTY_BPS = 500; // 5%

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) ERC721Royalty(_name, _symbol, address(0), 0) {}

    // -------- OVERRIDES --------
    function transferFrom(address from, address to, uint256 tokenId) public override {
        address owner = ownerOf(tokenId);
        require(
            msg.sender == owner || getApproved(tokenId) == msg.sender || isApprovedForAll(owner, msg.sender),
            "ERC721: transfer caller not approved"
        );
        require(to != address(0), "ERC721: transfer to zero address");

        // Check if royalty is set, if not use default
        if (_royaltyReceivers[tokenId] == address(0)) {
            _setRoyalty(tokenId, owner, ROYALTY_BPS);
        }

        _transfer(from, to, tokenId);
    }
}

// ============================================================================
// CONTRACT: RoyaltySplitter
// ============================================================================

/**
 * @title RoyaltySplitter
 * @dev Split royalties among multiple recipients
 */
contract RoyaltySplitter {
    // -------- STATE VARIABLES --------
    address[] public recipients;
    uint256[] public shares;
    uint256 public totalShares;

    // -------- EVENTS --------
    event RoyaltySplit(address indexed receiver, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(address[] memory _recipients, uint256[] memory _shares) {
        require(_recipients.length == _shares.length, "Length mismatch");
        require(_recipients.length > 0, "No recipients");

        recipients = _recipients;
        shares = _shares;

        for (uint256 i = 0; i < _shares.length; i++) {
            totalShares += _shares[i];
        }
    }

    // -------- FUNCTIONS --------
    function splitRoyalty() public payable {
        require(msg.value > 0, "No royalty to split");

        for (uint256 i = 0; i < recipients.length; i++) {
            uint256 amount = (msg.value * shares[i]) / totalShares;
            payable(recipients[i]).transfer(amount);
            emit RoyaltySplit(recipients[i], amount);
        }
    }

    function getRecipients() public view returns (address[] memory) {
        return recipients;
    }

    function getShares() public view returns (uint256[] memory) {
        return shares;
    }

    function getTotalShares() public view returns (uint256) {
        return totalShares;
    }

    // -------- RECEIVE --------
    receive() external payable {
        splitRoyalty();
    }
}

// ============================================================================
// CONTRACT: RoyaltyManager
// ============================================================================

/**
 * @title RoyaltyManager
 * @dev Manage royalties for multiple collections
 */
contract RoyaltyManager {
    // -------- STATE VARIABLES --------
    mapping(address => bool) public collections;
    address public owner;

    // -------- EVENTS --------
    event CollectionRegistered(address indexed collection);
    event CollectionRemoved(address indexed collection);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- FUNCTIONS --------
    function registerCollection(address collection) public onlyOwner {
        collections[collection] = true;
        emit CollectionRegistered(collection);
    }

    function removeCollection(address collection) public onlyOwner {
        collections[collection] = false;
        emit CollectionRemoved(collection);
    }

    function isCollection(address collection) public view returns (bool) {
        return collections[collection];
    }

    function getRoyaltyInfo(address collection, uint256 tokenId, uint256 salePrice)
        public
        view
        returns (address receiver, uint256 royaltyAmount)
    {
        require(collections[collection], "Collection not registered");
        return IERC2981(collection).royaltyInfo(tokenId, salePrice);
    }
}

Smart Accounts

ERC-4337

ERC-4337 is the Account Abstraction standard. It enables smart contract wallets without requiring protocol changes.

ERC-4337 Features:

FeatureDescription
Account AbstractionSmart contract wallets
User OperationsAlternative to transactions
BundlingMultiple operations in one
Gas SponsorshipPay gas with different tokens

Code Example – ERC-4337:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// INTERFACE: IERC4337 (Account Abstraction)
// ============================================================================

/**
 * @title IERC4337
 * @dev Account Abstraction standard interface (EIP-4337)
 */
interface IERC4337 {
    // -------- USER OPERATION STRUCT --------
    struct UserOperation {
        address sender;
        uint256 nonce;
        bytes initCode;
        bytes callData;
        uint256 callGasLimit;
        uint256 verificationGasLimit;
        uint256 preVerificationGas;
        uint256 maxFeePerGas;
        uint256 maxPriorityFeePerGas;
        bytes paymasterAndData;
        bytes signature;
    }

    // -------- FUNCTIONS --------
    function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;
    function validateUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external returns (uint256 validationData);
}

// ============================================================================
// INTERFACE: IAccount
// ============================================================================

/**
 * @title IAccount
 * @dev Account abstraction account interface
 */
interface IAccount {
    function validateUserOp(
        IERC4337.UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external returns (uint256 validationData);
}

// ============================================================================
// INTERFACE: IPaymaster
// ============================================================================

/**
 * @title IPaymaster
 * @dev Paymaster interface for gas sponsorship
 */
interface IPaymaster {
    function validatePaymasterUserOp(
        IERC4337.UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external returns (bytes memory context, uint256 validationData);

    function postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) external;

    enum PostOpMode {
        opSucceeded,
        opReverted,
        postOpReverted
    }
}

// ============================================================================
// CONTRACT: SimpleAccount
// ============================================================================

/**
 * @title SimpleAccount
 * @dev Simple account abstraction implementation
 */
contract SimpleAccount is IAccount {
    // -------- STATE VARIABLES --------
    address public owner;
    uint256 public nonce;
    address public entryPoint;

    // -------- EVENTS --------
    event AccountInitialized(address indexed owner, address indexed entryPoint);
    event Executed(address indexed target, uint256 value, bytes data);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "SimpleAccount: not owner");
        _;
    }

    modifier onlyEntryPoint() {
        require(msg.sender == entryPoint, "SimpleAccount: not entry point");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(address _owner, address _entryPoint) {
        owner = _owner;
        entryPoint = _entryPoint;
        emit AccountInitialized(_owner, _entryPoint);
    }

    // -------- INITIALIZATION --------
    function initialize(address _owner) public {
        require(owner == address(0), "SimpleAccount: already initialized");
        owner = _owner;
        emit AccountInitialized(_owner, entryPoint);
    }

    // -------- VALIDATION --------
    function validateUserOp(
        IERC4337.UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external onlyEntryPoint returns (uint256 validationData) {
        require(userOp.sender == address(this), "SimpleAccount: wrong sender");
        require(userOp.nonce == nonce, "SimpleAccount: wrong nonce");

        // Validate signature
        bytes32 hash = userOpHash;
        bytes memory signature = userOp.signature;
        require(owner == _verifySignature(hash, signature), "SimpleAccount: wrong signature");

        nonce++;
        return 0; // validationData = 0 means success
    }

    function _verifySignature(bytes32 hash, bytes memory signature) internal view returns (address) {
        // In production, use ECDSA.recover(hash, signature)
        // For simplicity, we just return the owner
        return owner;
    }

    // -------- EXECUTION --------
    function execute(address target, uint256 value, bytes calldata data) external onlyOwner {
        (bool success, ) = target.call{value: value}(data);
        require(success, "SimpleAccount: execute failed");
        emit Executed(target, value, data);
    }

    function executeBatch(address[] calldata targets, uint256[] calldata values, bytes[] calldata datas) external onlyOwner {
        require(targets.length == values.length, "SimpleAccount: length mismatch");
        require(targets.length == datas.length, "SimpleAccount: length mismatch");

        for (uint256 i = 0; i < targets.length; i++) {
            (bool success, ) = targets[i].call{value: values[i]}(datas[i]);
            require(success, "SimpleAccount: execute failed");
            emit Executed(targets[i], values[i], datas[i]);
        }
    }

    // -------- VIEW FUNCTIONS --------
    function getOwner() public view returns (address) {
        return owner;
    }

    function getNonce() public view returns (uint256) {
        return nonce;
    }

    function getEntryPoint() public view returns (address) {
        return entryPoint;
    }

    // -------- RECEIVE --------
    receive() external payable {}
}

// ============================================================================
// CONTRACT: SimpleAccountFactory
// ============================================================================

/**
 * @title SimpleAccountFactory
 * @dev Factory for deploying simple accounts
 */
contract SimpleAccountFactory {
    // -------- STATE VARIABLES --------
    address public entryPoint;
    address public accountImplementation;
    mapping(address => address) public accounts;

    // -------- EVENTS --------
    event AccountCreated(address indexed owner, address indexed account);
    event ImplementationUpdated(address indexed oldImpl, address indexed newImpl);

    // -------- CONSTRUCTOR --------
    constructor(address _entryPoint) {
        entryPoint = _entryPoint;
        accountImplementation = address(new SimpleAccount(address(this), _entryPoint));
    }

    // -------- FUNCTIONS --------
    function createAccount(address owner) public returns (address) {
        require(owner != address(0), "SimpleAccountFactory: invalid owner");
        require(accounts[owner] == address(0), "SimpleAccountFactory: account exists");

        SimpleAccount account = new SimpleAccount(owner, entryPoint);
        address accountAddr = address(account);
        accounts[owner] = accountAddr;

        emit AccountCreated(owner, accountAddr);
        return accountAddr;
    }

    function createAccountWithInit(
        address owner,
        bytes memory initData
    ) public returns (address) {
        address accountAddr = createAccount(owner);
        (bool success, ) = accountAddr.call(initData);
        require(success, "SimpleAccountFactory: init failed");
        return accountAddr;
    }

    function setImplementation(address newImplementation) public {
        require(msg.sender == entryPoint, "SimpleAccountFactory: not entry point");
        address oldImpl = accountImplementation;
        accountImplementation = newImplementation;
        emit ImplementationUpdated(oldImpl, newImplementation);
    }

    function getAccount(address owner) public view returns (address) {
        return accounts[owner];
    }

    function getEntryPoint() public view returns (address) {
        return entryPoint;
    }
}

// ============================================================================
// CONTRACT: SimplePaymaster
// ============================================================================

/**
 * @title SimplePaymaster
 * @dev Simple paymaster for gas sponsorship
 */
contract SimplePaymaster is IPaymaster {
    // -------- STATE VARIABLES --------
    address public owner;
    mapping(address => bool) public sponsorships;

    // -------- EVENTS --------
    event SponsorshipAdded(address indexed account);
    event SponsorshipRemoved(address indexed account);
    event PaymasterValidated(address indexed userOp, bytes context);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "SimplePaymaster: not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- PAYMASTER FUNCTIONS --------
    function validatePaymasterUserOp(
        IERC4337.UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) external override returns (bytes memory context, uint256 validationData) {
        require(sponsorships[userOp.sender], "SimplePaymaster: not sponsored");
        context = abi.encode(userOp.sender, userOp.nonce);
        validationData = 0;
        emit PaymasterValidated(userOp.sender, context);
    }

    function postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) external override {
        // Post operation logic
        (address sender, uint256 nonce) = abi.decode(context, (address, uint256));
        // Could implement post-op logic here
    }

    // -------- SPONSORSHIP MANAGEMENT --------
    function addSponsorship(address account) public onlyOwner {
        sponsorships[account] = true;
        emit SponsorshipAdded(account);
    }

    function removeSponsorship(address account) public onlyOwner {
        sponsorships[account] = false;
        emit SponsorshipRemoved(account);
    }

    function isSponsored(address account) public view returns (bool) {
        return sponsorships[account];
    }

    // -------- RECEIVE --------
    receive() external payable {}
}

// ============================================================================
// CONTRACT: EntryPoint
// ============================================================================

/**
 * @title EntryPoint
 * @dev Simple entry point for account abstraction
 */
contract EntryPoint is IERC4337 {
    // -------- STATE VARIABLES --------
    address public owner;
    mapping(address => bool) public accounts;

    // -------- EVENTS --------
    event UserOperationEvent(
        address indexed userOpHash,
        address indexed sender,
        address indexed paymaster,
        uint256 nonce,
        bool success,
        uint256 actualGasCost,
        uint256 actualGasUsed
    );

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "EntryPoint: not owner");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- FUNCTIONS --------
    function handleOps(UserOperation[] calldata ops, address payable beneficiary) external override {
        for (uint256 i = 0; i < ops.length; i++) {
            _handleOp(ops[i], beneficiary);
        }
    }

    function _handleOp(UserOperation calldata op, address payable beneficiary) internal {
        address sender = op.sender;
        require(accounts[sender], "EntryPoint: account not registered");

        // Validate user operation
        bytes32 userOpHash = _getUserOpHash(op);
        uint256 validationData = IAccount(sender).validateUserOp(op, userOpHash, 0);
        require(validationData == 0, "EntryPoint: validation failed");

        // Execute user operation
        (bool success, bytes memory result) = sender.call{gas: op.callGasLimit}(op.callData);
        require(success, "EntryPoint: execution failed");

        emit UserOperationEvent(
            userOpHash,
            sender,
            address(0),
            op.nonce,
            success,
            0,
            op.callGasLimit
        );

        // Transfer gas to beneficiary (simplified)
        beneficiary.transfer(address(this).balance);
    }

    function validateUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external override returns (uint256 validationData) {
        // Validation logic
        validationData = IAccount(userOp.sender).validateUserOp(userOp, userOpHash, missingAccountFunds);
        return validationData;
    }

    function _getUserOpHash(UserOperation calldata op) internal pure returns (bytes32) {
        return keccak256(abi.encode(op));
    }

    // -------- ADMIN FUNCTIONS --------
    function registerAccount(address account) public onlyOwner {
        accounts[account] = true;
    }

    function unregisterAccount(address account) public onlyOwner {
        accounts[account] = false;
    }

    function isAccount(address account) public view returns (bool) {
        return accounts[account];
    }

    // -------- RECEIVE --------
    receive() external payable {}
}

4. Development Tools

IDEs

Remix

Remix is a web-based IDE for Solidity development. It provides a complete development environment without installation.

Remix Features:

FeatureDescription
Browser-BasedNo installation needed
CompilationBuilt-in Solidity compiler
DeploymentDeploy to any network
DebuggingStep through transactions

Code Example – Remix Usage:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// SIMPLE CONTRACT FOR REMIX DEMONSTRATION
// ============================================================================

/**
 * @title SimpleStorage
 * @dev Basic storage contract - perfect for Remix beginners
 */
contract SimpleStorage {
    // -------- STATE VARIABLES --------
    uint256 public storedData;
    address public owner;
    bool public isActive;

    // -------- EVENTS --------
    event DataStored(address indexed user, uint256 value);
    event OwnerChanged(address indexed oldOwner, address indexed newOwner);

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
        isActive = true;
    }

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }

    modifier whenActive() {
        require(isActive, "Contract is not active");
        _;
    }

    // -------- FUNCTIONS --------
    function set(uint256 x) public onlyOwner whenActive {
        storedData = x;
        emit DataStored(msg.sender, x);
    }

    function get() public view returns (uint256) {
        return storedData;
    }

    function increment() public onlyOwner whenActive {
        storedData++;
        emit DataStored(msg.sender, storedData);
    }

    function decrement() public onlyOwner whenActive {
        require(storedData > 0, "Cannot decrement below zero");
        storedData--;
        emit DataStored(msg.sender, storedData);
    }

    // -------- ADMIN FUNCTIONS --------
    function changeOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnerChanged(oldOwner, newOwner);
    }

    function toggleActive() public onlyOwner {
        isActive = !isActive;
    }

    function getOwner() public view returns (address) {
        return owner;
    }

    function isContractActive() public view returns (bool) {
        return isActive;
    }
}

// ============================================================================
// TOKEN CONTRACT FOR REMIX DEMONSTRATION
// ============================================================================

/**
 * @title SimpleToken
 * @dev Basic ERC-20 token for Remix demo
 */
contract SimpleToken {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _totalSupply
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _totalSupply * 10**decimals;
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    // -------- VIEW FUNCTIONS --------
    function totalSupplyView() public view returns (uint256) {
        return totalSupply;
    }

    function balanceOfView(address account) public view returns (uint256) {
        return balanceOf[account];
    }

    function allowanceView(address owner, address spender) public view returns (uint256) {
        return allowance[owner][spender];
    }

    // -------- STATE-CHANGING FUNCTIONS --------
    function transfer(address to, uint256 value) public returns (bool) {
        require(to != address(0), "Invalid address");
        require(balanceOf[msg.sender] >= value, "Insufficient balance");

        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
        emit Transfer(msg.sender, to, value);
        return true;
    }

    function approve(address spender, uint256 value) public returns (bool) {
        require(spender != address(0), "Invalid spender");

        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value) public returns (bool) {
        require(from != address(0), "Invalid from");
        require(to != address(0), "Invalid to");
        require(balanceOf[from] >= value, "Insufficient balance");
        require(allowance[from][msg.sender] >= value, "Insufficient allowance");

        balanceOf[from] -= value;
        balanceOf[to] += value;
        allowance[from][msg.sender] -= value;
        emit Transfer(from, to, value);
        return true;
    }

    // -------- OPTIONAL FUNCTIONS --------
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        allowance[msg.sender][spender] += addedValue;
        emit Approval(msg.sender, spender, allowance[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        require(allowance[msg.sender][spender] >= subtractedValue, "Decreased below zero");
        allowance[msg.sender][spender] -= subtractedValue;
        emit Approval(msg.sender, spender, allowance[msg.sender][spender]);
        return true;
    }
}

// ============================================================================
// NFT CONTRACT FOR REMIX DEMONSTRATION
// ============================================================================

/**
 * @title SimpleNFT
 * @dev Basic NFT for Remix demo
 */
contract SimpleNFT {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;
    uint256 private _tokenIdCounter;
    mapping(uint256 => address) private _owners;
    mapping(address => uint256) private _balances;
    mapping(uint256 => string) private _tokenURIs;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    // -------- CONSTRUCTOR --------
    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    // -------- VIEW FUNCTIONS --------
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "Invalid address");
        return _balances[owner];
    }

    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "Token does not exist");
        return owner;
    }

    function tokenURI(uint256 tokenId) public view returns (string memory) {
        require(_owners[tokenId] != address(0), "Token does not exist");
        return _tokenURIs[tokenId];
    }

    // -------- MINT FUNCTIONS --------
    function mint(address to, string memory uri) public {
        require(to != address(0), "Invalid address");

        _tokenIdCounter++;
        uint256 tokenId = _tokenIdCounter;

        _owners[tokenId] = to;
        _balances[to] += 1;
        _tokenURIs[tokenId] = uri;

        emit Transfer(address(0), to, tokenId);
    }

    function mintBatch(address[] memory tos, string[] memory uris) public {
        require(tos.length == uris.length, "Length mismatch");

        for (uint256 i = 0; i < tos.length; i++) {
            mint(tos[i], uris[i]);
        }
    }

    // -------- TRANSFER FUNCTIONS --------
    function transferFrom(address from, address to, uint256 tokenId) public {
        require(_isApprovedOrOwner(msg.sender, tokenId), "Not approved");
        require(to != address(0), "Invalid address");

        address owner = _owners[tokenId];
        require(owner == from, "Not owner");

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        address owner = _owners[tokenId];
        return spender == owner;
    }

    // -------- VIEW HELPERS --------
    function getTotalSupply() public view returns (uint256) {
        return _tokenIdCounter;
    }

    function getTokenOwner(uint256 tokenId) public view returns (address) {
        return _owners[tokenId];
    }
}

// ============================================================================
// COMPLETE DEMO CONTRACT FOR REMIX
// ============================================================================

/**
 * @title CompleteDemo
 * @dev Complete demonstration contract for Remix
 */
contract CompleteDemo {
    // -------- STATE VARIABLES --------
    string public greeting;
    address public owner;
    uint256 public counter;
    mapping(address => uint256) public balances;

    // -------- EVENTS --------
    event GreetingSet(string greeting);
    event CounterIncremented(uint256 newValue);
    event Deposit(address indexed user, uint256 amount);
    event Withdrawal(address indexed user, uint256 amount);

    // -------- CONSTRUCTOR --------
    constructor(string memory _greeting) {
        greeting = _greeting;
        owner = msg.sender;
    }

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    // -------- FUNCTIONS --------
    function setGreeting(string memory _greeting) public onlyOwner {
        greeting = _greeting;
        emit GreetingSet(_greeting);
    }

    function getGreeting() public view returns (string memory) {
        return greeting;
    }

    function incrementCounter() public {
        counter++;
        emit CounterIncremented(counter);
    }

    function getCounter() public view returns (uint256) {
        return counter;
    }

    function deposit() public payable {
        require(msg.value > 0, "Must send ETH");
        balances[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }

    function withdraw(uint256 amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
        emit Withdrawal(msg.sender, amount);
    }

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function getOwner() public view returns (address) {
        return owner;
    }

    function changeOwner(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        owner = newOwner;
    }

    // -------- FALLBACK --------
    receive() external payable {
        balances[msg.sender] += msg.value;
        emit Deposit(msg.sender, msg.value);
    }
}

VS Code

VS Code is a popular code editor with excellent Solidity support through extensions.

VS Code Extensions:

ExtensionPurpose
SolidityLanguage support
HardhatDevelopment framework
PrettierCode formatting
GitLensVersion control

Frameworks

Hardhat

Hardhat is a development environment for Ethereum. It provides tools for compiling, testing, and deploying smart contracts.

Hardhat Features:

FeatureDescription
CompilationCompile Solidity contracts
TestingWrite and run tests
DeploymentDeploy to any network
DebuggingConsole.log for Solidity
PluginsExtensible ecosystem

Code Example – Hardhat Setup:

// hardhat.config.js
require("@nomiclabs/hardhat-waffle");
require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-etherscan");
require("hardhat-deploy");
require("hardhat-gas-reporter");
require("solidity-coverage");

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  // -------- SOLIDITY CONFIGURATION --------
  solidity: {
    compilers: [
      {
        version: "0.8.17",
        settings: {
          optimizer: {
            enabled: true,
            runs: 200
          }
        }
      },
      {
        version: "0.8.0",
        settings: {
          optimizer: {
            enabled: true,
            runs: 200
          }
        }
      }
    ]
  },

  // -------- NETWORKS --------
  networks: {
    // Hardhat Network (Local)
    hardhat: {
      chainId: 1337,
      mining: {
        auto: true,
        interval: 0
      },
      gas: 12000000,
      blockGasLimit: 12000000,
      allowUnlimitedContractSize: true
    },

    // Local Network (Ganache)
    localhost: {
      url: "http://127.0.0.1:8545",
      chainId: 1337,
      accounts: [
        "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" // Ganache default account
      ]
    },

    // Ethereum Mainnet
    mainnet: {
      url: "https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 20000000000 // 20 gwei
    },

    // Goerli Testnet
    goerli: {
      url: "https://goerli.infura.io/v3/YOUR_INFURA_API_KEY",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 1000000000 // 1 gwei
    },

    // Sepolia Testnet
    sepolia: {
      url: "https://sepolia.infura.io/v3/YOUR_INFURA_API_KEY",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // Polygon Mainnet
    polygon: {
      url: "https://polygon-mainnet.infura.io/v3/YOUR_INFURA_API_KEY",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 30000000000 // 30 gwei
    },

    // Polygon Mumbai Testnet
    mumbai: {
      url: "https://polygon-mumbai.infura.io/v3/YOUR_INFURA_API_KEY",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // Binance Smart Chain Mainnet
    bsc: {
      url: "https://bsc-dataseed.binance.org/",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 5000000000 // 5 gwei
    },

    // BSC Testnet
    bscTestnet: {
      url: "https://data-seed-prebsc-1-s1.binance.org:8545/",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // Avalanche Mainnet
    avalanche: {
      url: "https://api.avax.network/ext/bc/C/rpc",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 25000000000 // 25 gwei
    },

    // Fantom Opera Mainnet
    fantom: {
      url: "https://rpc.ftm.tools",
      accounts: ["0xYOUR_PRIVATE_KEY"],
      gasPrice: 100000000000 // 100 gwei
    },

    // Arbitrum One
    arbitrum: {
      url: "https://arb1.arbitrum.io/rpc",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // Optimism
    optimism: {
      url: "https://mainnet.optimism.io",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // Base
    base: {
      url: "https://mainnet.base.org",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    },

    // zkSync Era
    zkSync: {
      url: "https://mainnet.era.zksync.io",
      accounts: ["0xYOUR_PRIVATE_KEY"]
    }
  },

  // -------- ETHERSCAN CONFIGURATION --------
  etherscan: {
    apiKey: {
      mainnet: "YOUR_ETHERSCAN_API_KEY",
      goerli: "YOUR_ETHERSCAN_API_KEY",
      sepolia: "YOUR_ETHERSCAN_API_KEY",
      polygon: "YOUR_POLYGONSCAN_API_KEY",
      polygonMumbai: "YOUR_POLYGONSCAN_API_KEY",
      bsc: "YOUR_BSCSCAN_API_KEY",
      bscTestnet: "YOUR_BSCSCAN_API_KEY",
      avalanche: "YOUR_SNOWTRACE_API_KEY",
      fantom: "YOUR_FTMSCAN_API_KEY",
      arbitrum: "YOUR_ARBISCAN_API_KEY",
      optimistic: "YOUR_OPTIMISTIC_API_KEY",
      base: "YOUR_BASESCAN_API_KEY"
    }
  },

  // -------- GAS REPORTER --------
  gasReporter: {
    enabled: process.env.REPORT_GAS !== undefined,
    currency: "USD",
    coinmarketcap: "YOUR_COINMARKETCAP_API_KEY",
    gasPrice: 30,
    outputFile: "gas-report.txt",
    noColors: false,
    excludeContracts: ["Mock"]
  },

  // -------- PATHS --------
  paths: {
    sources: "./contracts",
    tests: "./test",
    cache: "./cache",
    artifacts: "./artifacts"
  },

  // -------- MOCHA CONFIG --------
  mocha: {
    timeout: 20000
  },

  // -------- EXTERNAL CONTRACTS --------
  external: {
    contracts: [
      {
        artifacts: "node_modules/@openzeppelin/contracts/build/contracts"
      }
    ]
  },

  // -------- DEPLOYMENT --------
  namedAccounts: {
    deployer: {
      default: 0,
      mainnet: "0xYOUR_DEPLOYER_ADDRESS"
    },
    user1: {
      default: 1
    },
    user2: {
      default: 2
    }
  },

  // -------- CUSTOM TASKS --------
  // Add custom tasks here if needed
};

// ============================================================================
// ENVIRONMENT VARIABLES (.env)
// ============================================================================

// Create a .env file with:
// INFURA_API_KEY=your_infura_api_key
// ALCHEMY_API_KEY=your_alchemy_api_key
// PRIVATE_KEY=your_private_key
// ETHERSCAN_API_KEY=your_etherscan_api_key
// POLYGONSCAN_API_KEY=your_polygonscan_api_key
// BSCSCAN_API_KEY=your_bscscan_api_key
// COINMARKETCAP_API_KEY=your_coinmarketcap_api_key

// ============================================================================
// USAGE
// ============================================================================

// Compile: npx hardhat compile
// Deploy: npx hardhat run scripts/deploy.js --network goerli
// Test: npx hardhat test
// Test with gas report: REPORT_GAS=true npx hardhat test
// Coverage: npx hardhat coverage
// Verify: npx hardhat verify --network goerli CONTRACT_ADDRESS
// Clean: npx hardhat clean
// Node: npx hardhat node
// Console: npx hardhat console
// contracts/Token.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @title Token
 * @dev Basic ERC-20 token implementation
 */
contract Token {
    // -------- STATE VARIABLES --------
    string public name;
    string public symbol;
    uint8 public decimals;
    uint256 public totalSupply;

    mapping(address => uint256) public balances;
    mapping(address => mapping(address => uint256)) public allowances;

    address public owner;
    bool public paused;

    // -------- EVENTS --------
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Mint(address indexed to, uint256 amount);
    event Burn(address indexed from, uint256 amount);
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this");
        _;
    }

    modifier whenNotPaused() {
        require(!paused, "Contract is paused");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _initialSupply
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        owner = msg.sender;

        totalSupply = _initialSupply * 10**decimals;
        balances[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }

    // -------- VIEW FUNCTIONS --------
    function balanceOf(address account) public view returns (uint256) {
        return balances[account];
    }

    function allowance(address owner_, address spender) public view returns (uint256) {
        return allowances[owner_][spender];
    }

    function getOwner() public view returns (address) {
        return owner;
    }

    function isPaused() public view returns (bool) {
        return paused;
    }

    // -------- TRANSFER FUNCTIONS --------
    function transfer(address to, uint256 amount) public whenNotPaused returns (bool) {
        require(to != address(0), "Invalid recipient");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        balances[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function transferFrom(address from, address to, uint256 amount) public whenNotPaused returns (bool) {
        require(from != address(0), "Invalid sender");
        require(to != address(0), "Invalid recipient");
        require(balances[from] >= amount, "Insufficient balance");
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");

        balances[from] -= amount;
        balances[to] += amount;
        allowances[from][msg.sender] -= amount;
        emit Transfer(from, to, amount);
        return true;
    }

    // -------- APPROVAL FUNCTIONS --------
    function approve(address spender, uint256 amount) public whenNotPaused returns (bool) {
        require(spender != address(0), "Invalid spender");

        allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function increaseAllowance(address spender, uint256 addedValue) public whenNotPaused returns (bool) {
        require(spender != address(0), "Invalid spender");

        allowances[msg.sender][spender] += addedValue;
        emit Approval(msg.sender, spender, allowances[msg.sender][spender]);
        return true;
    }

    function decreaseAllowance(address spender, uint256 subtractedValue) public whenNotPaused returns (bool) {
        require(spender != address(0), "Invalid spender");
        require(allowances[msg.sender][spender] >= subtractedValue, "Decreased below zero");

        allowances[msg.sender][spender] -= subtractedValue;
        emit Approval(msg.sender, spender, allowances[msg.sender][spender]);
        return true;
    }

    // -------- MINT FUNCTIONS --------
    function mint(address to, uint256 amount) public onlyOwner whenNotPaused {
        require(to != address(0), "Invalid recipient");
        require(amount > 0, "Amount must be positive");

        totalSupply += amount;
        balances[to] += amount;
        emit Mint(to, amount);
        emit Transfer(address(0), to, amount);
    }

    function mintBatch(address[] memory tos, uint256[] memory amounts) public onlyOwner whenNotPaused {
        require(tos.length == amounts.length, "Length mismatch");

        for (uint256 i = 0; i < tos.length; i++) {
            require(tos[i] != address(0), "Invalid recipient");
            require(amounts[i] > 0, "Amount must be positive");

            totalSupply += amounts[i];
            balances[tos[i]] += amounts[i];
            emit Mint(tos[i], amounts[i]);
            emit Transfer(address(0), tos[i], amounts[i]);
        }
    }

    // -------- BURN FUNCTIONS --------
    function burn(uint256 amount) public whenNotPaused {
        require(amount > 0, "Amount must be positive");
        require(balances[msg.sender] >= amount, "Insufficient balance");

        balances[msg.sender] -= amount;
        totalSupply -= amount;
        emit Burn(msg.sender, amount);
        emit Transfer(msg.sender, address(0), amount);
    }

    function burnFrom(address from, uint256 amount) public whenNotPaused {
        require(amount > 0, "Amount must be positive");
        require(balances[from] >= amount, "Insufficient balance");
        require(allowances[from][msg.sender] >= amount, "Insufficient allowance");

        balances[from] -= amount;
        totalSupply -= amount;
        allowances[from][msg.sender] -= amount;
        emit Burn(from, amount);
        emit Transfer(from, address(0), amount);
    }

    // -------- ADMIN FUNCTIONS --------
    function pause() public onlyOwner {
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyOwner {
        paused = false;
        emit Unpaused(msg.sender);
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        owner = newOwner;
    }

    // -------- VIEW FUNCTIONS --------
    function getTotalSupply() public view returns (uint256) {
        return totalSupply;
    }

    function getTokenInfo() public view returns (
        string memory,
        string memory,
        uint8,
        uint256,
        address,
        bool
    ) {
        return (name, symbol, decimals, totalSupply, owner, paused);
    }
}
// test/Token.js
const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("Token", function() {
    let Token, token;
    let owner, addr1, addr2, addrs;

    // -------- DEPLOY BEFORE EACH TEST --------
    beforeEach(async function() {
        [owner, addr1, addr2, ...addrs] = await ethers.getSigners();

        Token = await ethers.getContractFactory("Token");
        token = await Token.deploy("My Token", "MTK", 18, 1000);
        await token.deployed();
    });

    // -------- DEPLOYMENT TESTS --------
    describe("Deployment", function() {
        it("Should deploy with correct initial supply", async function() {
            const totalSupply = await token.totalSupply();
            expect(totalSupply).to.equal(1000 * 10 ** 18);
        });

        it("Should set the correct name", async function() {
            expect(await token.name()).to.equal("My Token");
        });

        it("Should set the correct symbol", async function() {
            expect(await token.symbol()).to.equal("MTK");
        });

        it("Should set the correct decimals", async function() {
            expect(await token.decimals()).to.equal(18);
        });

        it("Should assign all tokens to owner", async function() {
            const ownerBalance = await token.balanceOf(owner.address);
            const totalSupply = await token.totalSupply();
            expect(ownerBalance).to.equal(totalSupply);
        });

        it("Should set the correct owner", async function() {
            expect(await token.getOwner()).to.equal(owner.address);
        });
    });

    // -------- TRANSFER TESTS --------
    describe("Transfers", function() {
        it("Should transfer tokens between accounts", async function() {
            const amount = 100 * 10 ** 18;

            await token.transfer(addr1.address, amount);

            const ownerBalance = await token.balanceOf(owner.address);
            const addr1Balance = await token.balanceOf(addr1.address);

            expect(ownerBalance).to.equal(900 * 10 ** 18);
            expect(addr1Balance).to.equal(amount);
        });

        it("Should emit Transfer event", async function() {
            const amount = 100 * 10 ** 18;

            await expect(token.transfer(addr1.address, amount))
                .to.emit(token, "Transfer")
                .withArgs(owner.address, addr1.address, amount);
        });

        it("Should fail if sender has insufficient balance", async function() {
            const amount = 2000 * 10 ** 18;

            await expect(token.transfer(addr1.address, amount))
                .to.be.revertedWith("Insufficient balance");
        });

        it("Should fail if recipient is zero address", async function() {
            const amount = 100 * 10 ** 18;

            await expect(token.transfer(ethers.constants.AddressZero, amount))
                .to.be.revertedWith("Invalid recipient");
        });

        it("Should allow transferFrom with allowance", async function() {
            const amount = 100 * 10 ** 18;

            // Owner approves addr1 to spend tokens
            await token.approve(addr1.address, amount);

            // addr1 transfers from owner to addr2
            await token.connect(addr1).transferFrom(owner.address, addr2.address, amount);

            const ownerBalance = await token.balanceOf(owner.address);
            const addr2Balance = await token.balanceOf(addr2.address);

            expect(ownerBalance).to.equal(900 * 10 ** 18);
            expect(addr2Balance).to.equal(amount);
        });

        it("Should fail transferFrom if allowance insufficient", async function() {
            const amount = 100 * 10 ** 18;

            await token.approve(addr1.address, 50 * 10 ** 18);

            await expect(token.connect(addr1).transferFrom(owner.address, addr2.address, amount))
                .to.be.revertedWith("Insufficient allowance");
        });
    });

    // -------- APPROVAL TESTS --------
    describe("Approvals", function() {
        it("Should approve spender correctly", async function() {
            const amount = 100 * 10 ** 18;

            await token.approve(addr1.address, amount);

            const allowance = await token.allowance(owner.address, addr1.address);
            expect(allowance).to.equal(amount);
        });

        it("Should emit Approval event", async function() {
            const amount = 100 * 10 ** 18;

            await expect(token.approve(addr1.address, amount))
                .to.emit(token, "Approval")
                .withArgs(owner.address, addr1.address, amount);
        });

        it("Should increase allowance correctly", async function() {
            const initialAmount = 50 * 10 ** 18;
            const addedAmount = 30 * 10 ** 18;

            await token.approve(addr1.address, initialAmount);
            await token.increaseAllowance(addr1.address, addedAmount);

            const allowance = await token.allowance(owner.address, addr1.address);
            expect(allowance).to.equal(80 * 10 ** 18);
        });

        it("Should decrease allowance correctly", async function() {
            const initialAmount = 100 * 10 ** 18;
            const subtractedAmount = 30 * 10 ** 18;

            await token.approve(addr1.address, initialAmount);
            await token.decreaseAllowance(addr1.address, subtractedAmount);

            const allowance = await token.allowance(owner.address, addr1.address);
            expect(allowance).to.equal(70 * 10 ** 18);
        });

        it("Should fail decreasing allowance below zero", async function() {
            const initialAmount = 50 * 10 ** 18;
            const subtractedAmount = 60 * 10 ** 18;

            await token.approve(addr1.address, initialAmount);

            await expect(token.decreaseAllowance(addr1.address, subtractedAmount))
                .to.be.revertedWith("Decreased below zero");
        });
    });

    // -------- MINT TESTS --------
    describe("Minting", function() {
        it("Should mint tokens correctly", async function() {
            const amount = 100 * 10 ** 18;

            await token.mint(addr1.address, amount);

            const totalSupply = await token.totalSupply();
            const addr1Balance = await token.balanceOf(addr1.address);

            expect(totalSupply).to.equal(1100 * 10 ** 18);
            expect(addr1Balance).to.equal(amount);
        });

        it("Should emit Mint and Transfer events", async function() {
            const amount = 100 * 10 ** 18;

            await expect(token.mint(addr1.address, amount))
                .to.emit(token, "Mint")
                .withArgs(addr1.address, amount)
                .to.emit(token, "Transfer")
                .withArgs(ethers.constants.AddressZero, addr1.address, amount);
        });

        it("Should fail if non-owner tries to mint", async function() {
            const amount = 100 * 10 ** 18;

            await expect(token.connect(addr1).mint(addr1.address, amount))
                .to.be.revertedWith("Only owner can call this");
        });

        it("Should mint batch correctly", async function() {
            const tos = [addr1.address, addr2.address];
            const amounts = [100 * 10 ** 18, 200 * 10 ** 18];

            await token.mintBatch(tos, amounts);

            const totalSupply = await token.totalSupply();
            const addr1Balance = await token.balanceOf(addr1.address);
            const addr2Balance = await token.balanceOf(addr2.address);

            expect(totalSupply).to.equal(1300 * 10 ** 18);
            expect(addr1Balance).to.equal(amounts[0]);
            expect(addr2Balance).to.equal(amounts[1]);
        });
    });

    // -------- BURN TESTS --------
    describe("Burning", function() {
        it("Should burn tokens correctly", async function() {
            const amount = 50 * 10 ** 18;

            await token.burn(amount);

            const totalSupply = await token.totalSupply();
            const ownerBalance = await token.balanceOf(owner.address);

            expect(totalSupply).to.equal(950 * 10 ** 18);
            expect(ownerBalance).to.equal(950 * 10 ** 18);
        });

        it("Should emit Burn and Transfer events", async function() {
            const amount = 50 * 10 ** 18;

            await expect(token.burn(amount))
                .to.emit(token, "Burn")
                .withArgs(owner.address, amount)
                .to.emit(token, "Transfer")
                .withArgs(owner.address, ethers.constants.AddressZero, amount);
        });

        it("Should burn from allowance correctly", async function() {
            const amount = 50 * 10 ** 18;

            await token.approve(addr1.address, amount);
            await token.connect(addr1).burnFrom(owner.address, amount);

            const totalSupply = await token.totalSupply();
            const ownerBalance = await token.balanceOf(owner.address);

            expect(totalSupply).to.equal(950 * 10 ** 18);
            expect(ownerBalance).to.equal(950 * 10 ** 18);
        });

        it("Should fail burning more than balance", async function() {
            const amount = 2000 * 10 ** 18;

            await expect(token.burn(amount))
                .to.be.revertedWith("Insufficient balance");
        });
    });

    // -------- PAUSE TESTS --------
    describe("Pausing", function() {
        it("Should pause contract correctly", async function() {
            await token.pause();

            expect(await token.isPaused()).to.be.true;
        });

        it("Should emit Paused event", async function() {
            await expect(token.pause())
                .to.emit(token, "Paused")
                .withArgs(owner.address);
        });

        it("Should fail transfers when paused", async function() {
            const amount = 100 * 10 ** 18;

            await token.pause();

            await expect(token.transfer(addr1.address, amount))
                .to.be.revertedWith("Contract is paused");
        });

        it("Should unpause contract correctly", async function() {
            await token.pause();
            await token.unpause();

            expect(await token.isPaused()).to.be.false;
        });

        it("Should allow transfers after unpausing", async function() {
            const amount = 100 * 10 ** 18;

            await token.pause();
            await token.unpause();

            await expect(token.transfer(addr1.address, amount))
                .to.emit(token, "Transfer");
        });
    });

    // -------- OWNERSHIP TESTS --------
    describe("Ownership", function() {
        it("Should transfer ownership correctly", async function() {
            await token.transferOwnership(addr1.address);

            expect(await token.getOwner()).to.equal(addr1.address);
        });

        it("Should fail transferring to zero address", async function() {
            await expect(token.transferOwnership(ethers.constants.AddressZero))
                .to.be.revertedWith("Invalid address");
        });

        it("Should fail if non-owner tries to transfer", async function() {
            await expect(token.connect(addr1).transferOwnership(addr2.address))
                .to.be.revertedWith("Only owner can call this");
        });

        it("Should allow new owner to call owner functions", async function() {
            await token.transferOwnership(addr1.address);

            const amount = 100 * 10 ** 18;
            await token.connect(addr1).mint(addr2.address, amount);

            const addr2Balance = await token.balanceOf(addr2.address);
            expect(addr2Balance).to.equal(amount);
        });
    });

    // -------- VIEW TESTS --------
    describe("View Functions", function() {
        it("Should return total supply", async function() {
            const totalSupply = await token.getTotalSupply();
            expect(totalSupply).to.equal(1000 * 10 ** 18);
        });

        it("Should return token info", async function() {
            const info = await token.getTokenInfo();

            expect(info[0]).to.equal("My Token");
            expect(info[1]).to.equal("MTK");
            expect(info[2]).to.equal(18);
            expect(info[3]).to.equal(1000 * 10 ** 18);
            expect(info[4]).to.equal(owner.address);
            expect(info[5]).to.equal(false);
        });
    });

    // -------- EDGE CASES --------
    describe("Edge Cases", function() {
        it("Should handle zero amount transfers", async function() {
            const amount = 0;

            await expect(token.transfer(addr1.address, amount))
                .to.be.revertedWith("Amount must be positive");
        });

        it("Should handle large numbers", async function() {
            const amount = ethers.constants.MaxUint256;

            // Approve first
            await token.approve(addr1.address, amount);

            // TransferFrom works with large numbers
            // Not all of them are transferred, only balance check matters
            // This is just a test to ensure large numbers don't break
            const allowance = await token.allowance(owner.address, addr1.address);
            expect(allowance).to.equal(amount);
        });

        it("Should handle multiple transfers correctly", async function() {
            const amount1 = 100 * 10 ** 18;
            const amount2 = 50 * 10 ** 18;
            const amount3 = 30 * 10 ** 18;

            await token.transfer(addr1.address, amount1);
            await token.transfer(addr2.address, amount2);
            await token.transfer(addr1.address, amount3);

            const addr1Balance = await token.balanceOf(addr1.address);
            const addr2Balance = await token.balanceOf(addr2.address);
            const ownerBalance = await token.balanceOf(owner.address);

            expect(addr1Balance).to.equal(130 * 10 ** 18);
            expect(addr2Balance).to.equal(amount2);
            expect(ownerBalance).to.equal(820 * 10 ** 18);
        });
    });

    // -------- GAS TESTS (Optional) --------
    describe("Gas Usage", function() {
        it("Should be gas efficient for transfers", async function() {
            const amount = 100 * 10 ** 18;

            // Estimate gas for transfer
            const tx = await token.transfer(addr1.address, amount);
            const receipt = await tx.wait();

            expect(receipt.gasUsed).to.be.lessThan(100000);
        });
    });

    // -------- INTEGRATION TESTS --------
    describe("Integration", function() {
        it("Should work with multiple approvals", async function() {
            const amount1 = 50 * 10 ** 18;
            const amount2 = 30 * 10 ** 18;

            await token.approve(addr1.address, amount1);
            await token.approve(addr2.address, amount2);

            const allowance1 = await token.allowance(owner.address, addr1.address);
            const allowance2 = await token.allowance(owner.address, addr2.address);

            expect(allowance1).to.equal(amount1);
            expect(allowance2).to.equal(amount2);
        });

        it("Should handle transfers between non-owners", async function() {
            const amount = 100 * 10 ** 18;

            // Transfer tokens to addr1
            await token.transfer(addr1.address, amount);

            // addr1 transfers to addr2
            await token.connect(addr1).transfer(addr2.address, 50 * 10 ** 18);

            const addr1Balance = await token.balanceOf(addr1.address);
            const addr2Balance = await token.balanceOf(addr2.address);

            expect(addr1Balance).to.equal(50 * 10 ** 18);
            expect(addr2Balance).to.equal(50 * 10 ** 18);
        });
    });
});

Foundry

Foundry is a fast, portable toolkit for Ethereum development written in Rust. It’s becoming the industry standard for smart contract development.

Foundry Features:

FeatureDescription
SpeedVery fast compilation and testing
ForgeTesting framework
CastCommand-line Ethereum tool
AnvilLocal testnet

Code Example – Foundry Setup:

# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup

# Create project
forge init my-project
cd my-project
// src/Token.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Token {
    string public name = "My Token";
    string public symbol = "MTK";
    uint8 public decimals = 18;
    uint256 public totalSupply;
    mapping(address => uint256) public balances;

    constructor(uint256 _initialSupply) {
        totalSupply = _initialSupply * 10**decimals;
        balances[msg.sender] = totalSupply;
    }

    function transfer(address to, uint256 amount) public returns (bool) {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
        return true;
    }
}
// test/Token.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../src/Token.sol";

contract TokenTest is Test {
    Token token;

    function setUp() public {
        token = new Token(1000);
    }

    function testInitialSupply() public {
        assertEq(token.totalSupply(), 1000 * 10**18);
    }
}

Libraries

OpenZeppelin

OpenZeppelin provides secure, audited smart contract libraries. It’s the most trusted source for contract development.

OpenZeppelin Features:

FeatureDescription
ERC StandardsERC-20, ERC-721, ERC-1155
SecurityAudited and battle-tested
UpgradeableProxy patterns
Access ControlOwnable, Roles

Code Example – OpenZeppelin:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title MyToken
 * @dev Using OpenZeppelin standards
 */
contract MyToken is ERC20, Ownable {
    constructor(
        string memory name,
        string memory symbol,
        uint256 initialSupply
    ) ERC20(name, symbol) {
        _mint(msg.sender, initialSupply * 10**decimals());
    }

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
}

Ethers.js

Ethers.js is a JavaScript library that enables applications to interact with the Ethereum blockchain, including smart contracts, wallets, and transactions. It provides a simple API for sending transactions and reading blockchain data.

Ethers.js Features:

FeatureDescription
ProviderConnect to Ethereum nodes
WalletManage private keys
ContractInteract with smart contracts
SignerSign transactions

Code Example – Ethers.js:

// Import ethers
const { ethers } = require("ethers");

// Connect to network
const provider = new ethers.providers.JsonRpcProvider("http://localhost:8545");

// Create wallet
const wallet = new ethers.Wallet("0xPRIVATE_KEY", provider);

// Connect to contract
const contract = new ethers.Contract(
    "0xCONTRACT_ADDRESS",
    [
        "function transfer(address to, uint256 amount) public returns (bool)",
        "function balanceOf(address owner) public view returns (uint256)"
    ],
    wallet
);

// Read data
async function getBalance(address) {
    const balance = await contract.balanceOf(address);
    console.log("Balance:", ethers.utils.formatEther(balance));
}

// Send transaction
async function transfer(to, amount) {
    const tx = await contract.transfer(to, ethers.utils.parseEther(amount));
    await tx.wait();
    console.log("Transaction confirmed:", tx.hash);
}

5. DApp Development

Frontend

React

React is a JavaScript library for building interactive and reusable user interfaces, especially for web applications.It’s the most popular frontend framework for dApps.

React Features:

FeatureDescription
Component-BasedReusable UI components
Virtual DOMEfficient updates
HooksState and lifecycle
EcosystemVast library of packages

Code Example – React Setup:

// App.js
import React, { useState, useEffect } from 'react';
import { ethers } from 'ethers';

function App() {
    const [account, setAccount] = useState(null);
    const [balance, setBalance] = useState(0);

    const connectWallet = async () => {
        if (window.ethereum) {
            const accounts = await window.ethereum.request({
                method: 'eth_requestAccounts'
            });
            setAccount(accounts[0]);

            const provider = new ethers.providers.Web3Provider(window.ethereum);
            const balance = await provider.getBalance(accounts[0]);
            setBalance(ethers.utils.formatEther(balance));
        }
    };

    return (
        <div>
            <h1>Web3 DApp</h1>
            {account ? (
                <div>
                    <p>Connected: {account}</p>
                    <p>Balance: {balance} ETH</p>
                </div>
            ) : (
                <button onClick={connectWallet}>Connect Wallet</button>
            )}
        </div>
    );
}

export default App;

Next.js

Next.js is a React framework for production dApps. It provides server-side rendering, routing, and optimization.

Next.js Features:

FeatureDescription
SSRServer-side rendering
RoutingFile-based routing
API RoutesBackend endpoints
OptimizationPerformance and SEO

Wallet Integration

MetaMask

MetaMask is the most popular cryptocurrency wallet. It provides browser extension and mobile app for interacting with dApps.

MetaMask Features:

FeatureDescription
Browser ExtensionChrome, Firefox, Brave
Mobile AppiOS and Android
Network SwitchingMultiple networks
Transaction SigningSecure signing

Code Example – MetaMask Integration:

// utils/web3.js
import { ethers } from 'ethers';

export const getProvider = () => {
    if (window.ethereum) {
        return new ethers.providers.Web3Provider(window.ethereum);
    }
    return null;
};

export const connectWallet = async () => {
    if (!window.ethereum) {
        alert('Please install MetaMask');
        return null;
    }

    try {
        const accounts = await window.ethereum.request({
            method: 'eth_requestAccounts'
        });
        return accounts[0];
    } catch (error) {
        console.error(error);
        return null;
    }
};

export const sendTransaction = async (to, amount) => {
    const provider = getProvider();
    const signer = provider.getSigner();

    const tx = await signer.sendTransaction({
        to: to,
        value: ethers.utils.parseEther(amount)
    });

    return await tx.wait();
};

WalletConnect

WalletConnect enables dApps to connect with mobile wallets. It uses QR codes and deep linking for connection.

WalletConnect Features:

FeatureDescription
QR CodeScan to connect
Deep LinkingOpen in wallet app
Multiple WalletsRainbow, Trust Wallet
SecureNo private key exposure

Code Example – WalletConnect:

// utils/walletconnect.js
import WalletConnect from '@walletconnect/client';
import QRCodeModal from '@walletconnect/qrcode-modal';

const createConnector = () => {
    return new WalletConnect({
        bridge: 'https://bridge.walletconnect.org',
        qrcodeModal: QRCodeModal
    });
};

export const connectWalletConnect = async () => {
    const connector = createConnector();

    if (!connector.connected) {
        await connector.createSession();
    }

    return connector;
};

export const disconnectWalletConnect = async (connector) => {
    if (connector.connected) {
        await connector.killSession();
    }
};

Blockchain Communication

Reading Blockchain Data

Reading data from the blockchain is essential for dApps. It involves querying the blockchain for balances, transactions, and contract data.

Code Example – Reading Data:

// utils/reading.js
import { ethers } from 'ethers';

// Get provider
const provider = new ethers.providers.JsonRpcProvider(
    'https://mainnet.infura.io/v3/YOUR_API_KEY'
);

// Read block data
const getBlockData = async () => {
    const blockNumber = await provider.getBlockNumber();
    const block = await provider.getBlock(blockNumber);
    console.log('Block:', block);
    return block;
};

// Read account balance
const getAccountBalance = async (address) => {
    const balance = await provider.getBalance(address);
    return ethers.utils.formatEther(balance);
};

// Read contract data
const getTokenBalance = async (contractAddress, ownerAddress) => {
    const abi = ['function balanceOf(address) view returns (uint256)'];
    const contract = new ethers.Contract(contractAddress, abi, provider);
    const balance = await contract.balanceOf(ownerAddress);
    return balance.toString();
};

Writing Transactions

Writing transactions modifies blockchain state. It requires gas fees and user signatures.

Code Example – Writing Transactions:

// utils/writing.js
import { ethers } from 'ethers';

const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

// Send ETH
const sendETH = async (to, amount) => {
    const tx = await signer.sendTransaction({
        to: to,
        value: ethers.utils.parseEther(amount),
        gasLimit: 21000,
        gasPrice: await provider.getGasPrice()
    });
    return await tx.wait();
};

// Call contract function
const callContract = async (contractAddress, abi, functionName, args) => {
    const contract = new ethers.Contract(contractAddress, abi, signer);
    const tx = await contract[functionName](...args);
    return await tx.wait();
};

// Example: Transfer tokens
const transferToken = async (contractAddress, to, amount) => {
    const abi = ['function transfer(address,uint256) returns (bool)'];
    const decimals = 18; // Get from contract
    const tx = await callContract(
        contractAddress,
        abi,
        'transfer',

[to, ethers.utils.parseUnits(amount, decimals)]

); console.log(‘Transaction confirmed:’, tx.transactionHash); };

Decentralized Storage

IPFS

IPFS (InterPlanetary File System) is a decentralized storage system. Content is addressed by its hash, not location.

IPFS Features:

FeatureDescription
Content AddressingAccess by hash
DeduplicationStore once
DecentralizedNo central server
PermanentIf pinned

Code Example – IPFS:

// utils/ipfs.js
import { create } from 'ipfs-http-client';

const ipfs = create('https://ipfs.infura.io:5001');

// Upload file
const uploadFile = async (file) => {
    const result = await ipfs.add(file);
    console.log('IPFS Hash:', result.path);
    return result.path;
};

// Upload JSON
const uploadJSON = async (data) => {
    const jsonString = JSON.stringify(data);
    const result = await ipfs.add(jsonString);
    return result.path;
};

// Retrieve file
const getFile = async (hash) => {
    const chunks = [];
    for await (const chunk of ipfs.cat(hash)) {
        chunks.push(chunk);
    }
    return Buffer.concat(chunks);
};

// Example: Upload NFT metadata
const uploadMetadata = async (name, description, imageHash) => {
    const metadata = {
        name: name,
        description: description,
        image: `ipfs://${imageHash}`,
        attributes: []
    };
    return await uploadJSON(metadata);
};

Filecoin

Filecoin is a decentralized storage network that provides long-term storage with economic incentives.

Arweave

Arweave provides permanent, decentralized storage with a one-time payment model.

Indexing

The Graph

The Graph indexes blockchain data for fast querying. It enables efficient data access for dApps.

The Graph Features:

FeatureDescription
SubgraphDefine what data to index
GraphQLQuery language
DecentralizedDecentralized network

Code Example – The Graph:

// subgraph.yaml
specVersion: 0.0.4
schema:
  file: ./schema.graphql
dataSources:
  - kind: ethereum
    name: Token
    network: mainnet
    source:
      address: "0xCONTRACT_ADDRESS"
      abi: Token
    mapping:
      kind: ethereum/events
      apiVersion: 0.0.5
      language: wasm/assemblyscript
      entities:
        - Transfer
      abis:
        - name: Token
          file: ./abis/Token.json
      eventHandlers:
        - event: Transfer(indexed address,indexed address,uint256)
          handler: handleTransfer
// src/mapping.ts
import { Transfer } from "../generated/Token/Token";
import { TransferEntity } from "../generated/schema";

export function handleTransfer(event: Transfer): void {
    let entity = new TransferEntity(
        event.transaction.hash.toHex()
    );
    entity.from = event.params.from;
    entity.to = event.params.to;
    entity.value = event.params.value;
    entity.blockNumber = event.block.number;
    entity.save();
}
// Query subgraph
const query = `
    {
        transfers(first: 10) {
            from
            to
            value
            blockNumber
        }
    }
`;

const result = await fetch('https://api.thegraph.com/subgraphs/name/USER/SUBGRAPH', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ query })
});

const data = await result.json();
console.log(data);

Domain Names

ENS

ENS (Ethereum Name Service) provides human-readable names for Ethereum addresses.

ENS Features:

FeatureDescription
.eth DomainsHuman-readable names
ResolverMap names to addresses
Reverse RecordsAddress to name

Code Example – ENS:

// utils/ens.js
import { ethers } from 'ethers';

const provider = new ethers.providers.JsonRpcProvider();

// Resolve name to address
const resolveENS = async (name) => {
    const address = await provider.resolveName(name);
    console.log(`${name} -> ${address}`);
    return address;
};

// Reverse lookup: address to name
const reverseResolve = async (address) => {
    const name = await provider.lookupAddress(address);
    console.log(`${address} -> ${name}`);
    return name;
};

// Example
const main = async () => {
    const address = await resolveENS('vitalik.eth');
    const name = await reverseResolve(address);
};

main();

Full Stack Integration

Frontend ↔ Smart Contract Integration

Full stack integration connects the React frontend with smart contracts through Web3 libraries.

Code Example – Full Stack DApp:

// FullStackDApp.jsx
import React, { useState, useEffect } from 'react';
import { ethers } from 'ethers';
import TokenABI from './abis/Token.json';

function FullStackDApp() {
    const [account, setAccount] = useState(null);
    const [balance, setBalance] = useState(0);
    const [contract, setContract] = useState(null);
    const [toAddress, setToAddress] = useState('');
    const [amount, setAmount] = useState('');
    const [loading, setLoading] = useState(false);
    const [txHash, setTxHash] = useState('');

    const CONTRACT_ADDRESS = '0xYOUR_CONTRACT_ADDRESS';

    // Connect wallet
    const connectWallet = async () => {
        if (!window.ethereum) {
            alert('Please install MetaMask');
            return;
        }

        try {
            const accounts = await window.ethereum.request({
                method: 'eth_requestAccounts'
            });
            setAccount(accounts[0]);

            const provider = new ethers.providers.Web3Provider(window.ethereum);
            const signer = provider.getSigner();
            const tokenContract = new ethers.Contract(
                CONTRACT_ADDRESS,
                TokenABI,
                signer
            );
            setContract(tokenContract);

            const balance = await tokenContract.balanceOf(accounts[0]);
            setBalance(ethers.utils.formatEther(balance));

        } catch (error) {
            console.error(error);
        }
    };

    // Transfer tokens
    const transfer = async () => {
        if (!contract || !toAddress || !amount) return;

        setLoading(true);
        try {
            const tx = await contract.transfer(
                toAddress,
                ethers.utils.parseEther(amount)
            );
            await tx.wait();

            setTxHash(tx.hash);

            // Update balance
            const newBalance = await contract.balanceOf(account);
            setBalance(ethers.utils.formatEther(newBalance));

            setToAddress('');
            setAmount('');

        } catch (error) {
            console.error(error);
            alert('Transaction failed');
        }
        setLoading(false);
    };

    return (
        <div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
            <h1>Full Stack DApp</h1>

            {!account ? (
                <button onClick={connectWallet}>Connect Wallet</button>
            ) : (
                <div>
                    <p>Connected: {account}</p>
                    <p>Balance: {balance} MTK</p>

                    <div style={{ marginTop: '20px' }}>
                        <h3>Transfer Tokens</h3>
                        <input
                            type="text"
                            placeholder="Recipient Address"
                            value={toAddress}
                            onChange={(e) => setToAddress(e.target.value)}
                            style={{ width: '100%', padding: '8px', marginBottom: '10px' }}
                        />
                        <input
                            type="number"
                            placeholder="Amount"
                            value={amount}
                            onChange={(e) => setAmount(e.target.value)}
                            style={{ width: '100%', padding: '8px', marginBottom: '10px' }}
                        />
                        <button
                            onClick={transfer}
                            disabled={loading || !toAddress || !amount}
                            style={{ padding: '10px 20px' }}
                        >
                            {loading ? 'Processing...' : 'Transfer'}
                        </button>
                    </div>

                    {txHash && (
                        <div style={{ marginTop: '20px' }}>
                            <p>Transaction: <a href={`https://etherscan.io/tx/${txHash}`} target="_blank">{txHash}</a></p>
                        </div>
                    )}
                </div>
            )}
        </div>
    );
}

export default FullStackDApp;

PHASE 3: ADVANCED WEB3 ECOSYSTEM, SECURITY & SCALABILITY

Master Decentralized Finance, Blockchain Security, Scalability, Protocol Architecture, and Real-World Blockchain Systems.

1. Decentralized Finance (DeFi)

1.1 What is DeFi?

Decentralized Finance (DeFi) is a financial system built on blockchain that operates without centralized intermediaries like banks, brokers, or exchanges. It uses smart contracts to create financial products and services that are open, permissionless, and transparent. Anyone with an internet connection and a crypto wallet can access DeFi services without needing approval from any central authority.

The DeFi Ecosystem:

ComponentDescriptionExample
DEXDecentralized Exchange for peer-to-peer tradingUniswap, SushiSwap
AMMAutomated Market Maker using algorithms for pricingUniswap, Curve
Liquidity PoolsPooled funds that provide liquidity for tradingUniswap pools
LendingBorrow and lend assets with interestAave, Compound
StakingLock assets to earn rewardsEthereum 2.0
Yield FarmingEarn rewards by providing liquidityYearn Finance
Flash LoansUnc collateralized loans repaid in the same transactionAave, dYdX
StablecoinsCryptocurrencies pegged to stable assetsUSDC, DAI, USDT

Real-World Example – Uniswap:

Uniswap is the most popular DEX, using an AMM model where users trade against liquidity pools rather than order books. Liquidity providers deposit token pairs and earn fees from trades.

Code Example – Complete DeFi Protocol:

"""
DECENTRALIZED FINANCE PROTOCOL SIMULATION
=========================================
A comprehensive DeFi protocol with:
- Liquidity Pools (AMM)
- Lending and Borrowing
- Staking and Yield Farming
- Flash Loans
- Stablecoins
"""

import hashlib
import time
import math
import random
from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass, field
from enum import Enum

# ============================================================================
# CORE COMPONENTS
# ============================================================================

@dataclass
class User:
    """User account in DeFi"""
    name: str
    address: str
    balances: Dict[str, float] = field(default_factory=dict)
    positions: Dict[str, Dict] = field(default_factory=dict)
    lending_deposits: Dict[str, float] = field(default_factory=dict)
    lending_borrows: Dict[str, float] = field(default_factory=dict)
    staked_amounts: Dict[str, float] = field(default_factory=dict)
    rewards_earned: Dict[str, float] = field(default_factory=dict)

class Token:
    """Token representation with ERC-20 like functionality"""
    
    def __init__(self, name: str, symbol: str, decimals: int = 18):
        self.name = name
        self.symbol = symbol
        self.decimals = decimals
        self.address = f"0x{hashlib.md5(name.encode()).hexdigest()[:16]}"
        self.total_supply = 0.0
        self.balances: Dict[str, float] = {}
        self.allowances: Dict[str, Dict[str, float]] = {}
        self.created_at = time.time()

    def mint(self, to: str, amount: float) -> bool:
        """Mint new tokens to an address"""
        if amount <= 0:
            return False
        self.balances[to] = self.balances.get(to, 0) + amount
        self.total_supply += amount
        return True

    def transfer(self, from_addr: str, to_addr: str, amount: float) -> bool:
        """Transfer tokens between addresses"""
        if amount <= 0:
            return False
        if self.balances.get(from_addr, 0) < amount:
            return False
        self.balances[from_addr] -= amount
        self.balances[to_addr] = self.balances.get(to_addr, 0) + amount
        return True

    def approve(self, owner: str, spender: str, amount: float) -> bool:
        """Approve spending allowance"""
        if amount < 0:
            return False
        if owner not in self.allowances:
            self.allowances[owner] = {}
        self.allowances[owner][spender] = amount
        return True

    def transfer_from(self, from_addr: str, to_addr: str, spender: str, amount: float) -> bool:
        """Transfer using allowance"""
        if amount <= 0:
            return False
        if self.balances.get(from_addr, 0) < amount:
            return False
        if self.allowances.get(from_addr, {}).get(spender, 0) < amount:
            return False
        self.balances[from_addr] -= amount
        self.balances[to_addr] = self.balances.get(to_addr, 0) + amount
        self.allowances[from_addr][spender] -= amount
        return True

    def balance_of(self, address: str) -> float:
        """Get token balance"""
        return self.balances.get(address, 0)

    def get_info(self) -> Dict:
        """Get token information"""
        return {
            "name": self.name,
            "symbol": self.symbol,
            "decimals": self.decimals,
            "address": self.address,
            "total_supply": self.total_supply,
            "holders": len(self.balances)
        }

# ============================================================================
# LIQUIDITY POOL (AMM)
# ============================================================================

class LiquidityPool:
    """Automated Market Maker (AMM) Liquidity Pool with Constant Product Formula"""
    
    def __init__(self, token_a: Token, token_b: Token, fee: float = 0.003):
        self.token_a = token_a
        self.token_b = token_b
        self.fee = fee
        self.reserve_a = 0.0
        self.reserve_b = 0.0
        self.total_liquidity = 0.0
        self.liquidity_providers: Dict[str, float] = {}
        self.name = f"{token_a.symbol}-{token_b.symbol} Pool"
        self.k = 0.0
        self.total_volume = 0.0
        self.fees_collected = 0.0
        self.created_at = time.time()
        print(f" 🏊 Pool created: {self.name} (Fee: {fee*100}%)")

    def add_liquidity(self, provider: str, amount_a: float, amount_b: float) -> float:
        """Add liquidity to the pool"""
        if amount_a <= 0 or amount_b <= 0:
            print(" ❌ Amounts must be positive")
            return 0

        if not self.token_a.transfer(provider, self.token_a.address, amount_a):
            print(f" ❌ Insufficient {self.token_a.symbol} balance")
            return 0
        if not self.token_b.transfer(provider, self.token_b.address, amount_b):
            print(f" ❌ Insufficient {self.token_b.symbol} balance")
            return 0

        if self.total_liquidity == 0:
            # First deposit
            self.reserve_a = amount_a
            self.reserve_b = amount_b
            self.k = amount_a * amount_b
            liquidity = math.sqrt(amount_a * amount_b)
        else:
            # Calculate liquidity based on current ratio
            liquidity_a = amount_a * self.total_liquidity / self.reserve_a
            liquidity_b = amount_b * self.total_liquidity / self.reserve_b
            liquidity = min(liquidity_a, liquidity_b)

            self.reserve_a += amount_a
            self.reserve_b += amount_b
            self.k = self.reserve_a * self.reserve_b

        # Record liquidity
        self.liquidity_providers[provider] = self.liquidity_providers.get(provider, 0) + liquidity
        self.total_liquidity += liquidity

        print(f" ✅ Added liquidity: {amount_a:.2f} {self.token_a.symbol} + {amount_b:.2f} {self.token_b.symbol}")
        print(f"    Liquidity tokens: {liquidity:.2f}")
        return liquidity

    def remove_liquidity(self, provider: str, liquidity_amount: float) -> tuple:
        """Remove liquidity from the pool"""
        if liquidity_amount <= 0:
            return (0, 0)
        
        if self.liquidity_providers.get(provider, 0) < liquidity_amount:
            print(f" ❌ Insufficient liquidity balance")
            return (0, 0)

        # Calculate token amounts
        amount_a = (liquidity_amount / self.total_liquidity) * self.reserve_a
        amount_b = (liquidity_amount / self.total_liquidity) * self.reserve_b

        # Update reserves
        self.reserve_a -= amount_a
        self.reserve_b -= amount_b
        self.k = self.reserve_a * self.reserve_b

        # Update liquidity
        self.liquidity_providers[provider] -= liquidity_amount
        self.total_liquidity -= liquidity_amount

        # Transfer tokens back
        self.token_a.transfer(self.token_a.address, provider, amount_a)
        self.token_b.transfer(self.token_b.address, provider, amount_b)

        print(f" ✅ Removed liquidity: {amount_a:.2f} {self.token_a.symbol} + {amount_b:.2f} {self.token_b.symbol}")
        return (amount_a, amount_b)

    def swap(self, user: str, token_in: Token, amount_in: float, min_amount_out: float = 0) -> float:
        """Swap tokens using constant product formula"""
        if amount_in <= 0:
            return 0

        # Determine swap direction
        if token_in.address == self.token_a.address:
            # Swap A for B
            if amount_in > self.reserve_a:
                return 0

            # Calculate output (with fee)
            amount_in_with_fee = amount_in * (1 - self.fee)
            amount_out = (self.reserve_b * amount_in_with_fee) / (self.reserve_a + amount_in_with_fee)

            if amount_out < min_amount_out:
                print(f" ❌ Slippage: {amount_out:.2f} < {min_amount_out:.2f}")
                return 0

            if amount_out > self.reserve_b:
                print(f" ❌ Insufficient reserve B")
                return 0

            # Transfer tokens
            if not self.token_a.transfer(user, self.token_a.address, amount_in):
                print(f" ❌ Insufficient {self.token_a.symbol} balance")
                return 0

            # Update reserves
            self.reserve_a += amount_in
            self.reserve_b -= amount_out
            self.k = self.reserve_a * self.reserve_b
            
            # Track volume and fees
            fee_collected = amount_in * self.fee
            self.fees_collected += fee_collected
            self.total_volume += amount_in

            # Transfer output
            self.token_b.transfer(self.token_a.address, user, amount_out)

            print(f" ✅ Swapped: {amount_in:.2f} {self.token_a.symbol} → {amount_out:.2f} {self.token_b.symbol}")
            return amount_out

        elif token_in.address == self.token_b.address:
            # Swap B for A
            if amount_in > self.reserve_b:
                return 0

            amount_in_with_fee = amount_in * (1 - self.fee)
            amount_out = (self.reserve_a * amount_in_with_fee) / (self.reserve_b + amount_in_with_fee)

            if amount_out < min_amount_out:
                print(f" ❌ Slippage: {amount_out:.2f} < {min_amount_out:.2f}")
                return 0

            if amount_out > self.reserve_a:
                print(f" ❌ Insufficient reserve A")
                return 0

            if not self.token_b.transfer(user, self.token_b.address, amount_in):
                print(f" ❌ Insufficient {self.token_b.symbol} balance")
                return 0

            self.reserve_b += amount_in
            self.reserve_a -= amount_out
            self.k = self.reserve_a * self.reserve_b

            fee_collected = amount_in * self.fee
            self.fees_collected += fee_collected
            self.total_volume += amount_in

            self.token_a.transfer(self.token_b.address, user, amount_out)

            print(f" ✅ Swapped: {amount_in:.2f} {self.token_b.symbol} → {amount_out:.2f} {self.token_a.symbol}")
            return amount_out

        return 0

    def get_price(self) -> float:
        """Get price of token_a in terms of token_b"""
        if self.reserve_a == 0:
            return 0
        return self.reserve_b / self.reserve_a

    def get_price_a(self) -> float:
        """Get price of token_b in terms of token_a"""
        if self.reserve_b == 0:
            return 0
        return self.reserve_a / self.reserve_b

    def get_info(self) -> Dict:
        """Get pool information"""
        return {
            "name": self.name,
            "reserve_a": self.reserve_a,
            "reserve_b": self.reserve_b,
            "price": self.get_price(),
            "total_liquidity": self.total_liquidity,
            "k": self.k,
            "fee": self.fee * 100,
            "providers": len(self.liquidity_providers),
            "volume": self.total_volume,
            "fees_collected": self.fees_collected
        }

# ============================================================================
# LENDING POOL
# ============================================================================

class LendingPool:
    """Lending and borrowing pool"""
    
    def __init__(self, token: Token, name: str = None):
        self.token = token
        self.name = name or f"{token.symbol} Lending Pool"
        self.total_deposits = 0.0
        self.total_borrows = 0.0
        self.deposits: Dict[str, float] = {}
        self.borrows: Dict[str, float] = {}
        self.interest_rate = 0.05  # 5% annual
        self.utilization_rate = 0.0
        self.created_at = time.time()
        print(f" 🏦 Lending Pool created: {self.name}")

    def deposit(self, user: str, amount: float) -> bool:
        """Deposit tokens to earn interest"""
        if amount <= 0:
            return False
        
        if not self.token.transfer(user, self.token.address, amount):
            print(f" ❌ Insufficient {self.token.symbol} balance")
            return False

        self.deposits[user] = self.deposits.get(user, 0) + amount
        self.total_deposits += amount
        self._update_utilization()
        print(f" ✅ Deposited: {amount:.2f} {self.token.symbol}")
        return True

    def withdraw(self, user: str, amount: float) -> bool:
        """Withdraw deposited tokens"""
        if amount <= 0:
            return False
        
        if self.deposits.get(user, 0) < amount:
            print(f" ❌ Insufficient deposit balance")
            return False

        # Check available liquidity
        available = self.total_deposits - self.total_borrows
        if amount > available:
            print(f" ❌ Insufficient liquidity")
            return False

        self.deposits[user] -= amount
        self.total_deposits -= amount
        self.token.transfer(self.token.address, user, amount)
        self._update_utilization()
        print(f" ✅ Withdrew: {amount:.2f} {self.token.symbol}")
        return True

    def borrow(self, user: str, amount: float) -> bool:
        """Borrow tokens from the pool"""
        if amount <= 0:
            return False
        
        available = self.total_deposits - self.total_borrows
        if amount > available:
            print(f" ❌ Insufficient liquidity")
            return False

        self.borrows[user] = self.borrows.get(user, 0) + amount
        self.total_borrows += amount
        self.token.transfer(self.token.address, user, amount)
        self._update_utilization()
        print(f" ✅ Borrowed: {amount:.2f} {self.token.symbol}")
        return True

    def repay(self, user: str, amount: float) -> bool:
        """Repay borrowed tokens"""
        if amount <= 0:
            return False
        
        if self.borrows.get(user, 0) < amount:
            print(f" ❌ Borrow amount exceeds debt")
            return False

        if not self.token.transfer(user, self.token.address, amount):
            print(f" ❌ Insufficient {self.token.symbol} balance")
            return False

        self.borrows[user] -= amount
        self.total_borrows -= amount
        self._update_utilization()
        print(f" ✅ Repaid: {amount:.2f} {self.token.symbol}")
        return True

    def _update_utilization(self):
        """Update utilization rate"""
        if self.total_deposits == 0:
            self.utilization_rate = 0
        else:
            self.utilization_rate = self.total_borrows / self.total_deposits

    def get_info(self) -> Dict:
        """Get lending pool information"""
        return {
            "name": self.name,
            "token": self.token.symbol,
            "total_deposits": self.total_deposits,
            "total_borrows": self.total_borrows,
            "utilization": self.utilization_rate * 100,
            "interest_rate": self.interest_rate * 100,
            "depositors": len(self.deposits),
            "borrowers": len(self.borrows)
        }

# ============================================================================
# STAKING POOL
# ============================================================================

class StakingPool:
    """Staking and yield farming pool"""
    
    def __init__(self, staking_token: Token, reward_token: Token, reward_rate: float = 0.1):
        self.staking_token = staking_token
        self.reward_token = reward_token
        self.reward_rate = reward_rate  # Annual reward rate
        self.total_staked = 0.0
        self.stakes: Dict[str, float] = {}
        self.rewards: Dict[str, float] = {}
        self.last_update: Dict[str, float] = {}
        self.created_at = time.time()
        print(f" 🌾 Staking Pool created: {staking_token.symbol} → {reward_token.symbol}")

    def stake(self, user: str, amount: float) -> bool:
        """Stake tokens"""
        if amount <= 0:
            return False
        
        if not self.staking_token.transfer(user, self.staking_token.address, amount):
            print(f" ❌ Insufficient {self.staking_token.symbol} balance")
            return False

        self.stakes[user] = self.stakes.get(user, 0) + amount
        self.total_staked += amount
        self.last_update[user] = time.time()
        
        # Calculate and claim pending rewards
        self._claim_rewards(user)
        
        print(f" ✅ Staked: {amount:.2f} {self.staking_token.symbol}")
        return True

    def unstake(self, user: str, amount: float) -> bool:
        """Unstake tokens"""
        if amount <= 0:
            return False
        
        if self.stakes.get(user, 0) < amount:
            print(f" ❌ Insufficient staked balance")
            return False

        # Claim rewards before unstaking
        self._claim_rewards(user)

        self.stakes[user] -= amount
        self.total_staked -= amount
        self.staking_token.transfer(self.staking_token.address, user, amount)
        print(f" ✅ Unstaked: {amount:.2f} {self.staking_token.symbol}")
        return True

    def claim_rewards(self, user: str) -> float:
        """Claim earned rewards"""
        return self._claim_rewards(user)

    def _claim_rewards(self, user: str) -> float:
        """Internal function to calculate and claim rewards"""
        if user not in self.stakes or self.stakes[user] == 0:
            return 0

        stake_amount = self.stakes[user]
        time_staked = time.time() - self.last_update.get(user, time.time())
        
        # Calculate rewards (annual rate)
        reward = stake_amount * self.reward_rate * (time_staked / (365 * 24 * 3600))
        
        if reward > 0:
            self.rewards[user] = self.rewards.get(user, 0) + reward
            self.reward_token.mint(user, reward)
            print(f" 💰 Claimed rewards: {reward:.4f} {self.reward_token.symbol}")
        
        self.last_update[user] = time.time()
        return reward

    def get_info(self) -> Dict:
        """Get staking pool information"""
        return {
            "staking_token": self.staking_token.symbol,
            "reward_token": self.reward_token.symbol,
            "total_staked": self.total_staked,
            "reward_rate": self.reward_rate * 100,
            "stakers": len(self.stakes)
        }

# ============================================================================
# DECENTRALIZED EXCHANGE
# ============================================================================

class DEX:
    """Decentralized Exchange with multiple liquidity pools"""
    
    def __init__(self, name: str = "DEX"):
        self.name = name
        self.pools: Dict[str, LiquidityPool] = {}
        self.tokens: Dict[str, Token] = {}
        self.total_volume = 0.0
        self.fees_collected = 0.0
        print(f" 📊 DEX '{name}' initialized")

    def add_token(self, token: Token) -> None:
        """Register a token with the DEX"""
        self.tokens[token.address] = token

    def create_pool(self, token_a: Token, token_b: Token, fee: float = 0.003) -> LiquidityPool:
        """Create a new liquidity pool"""
        if token_a.address not in self.tokens:
            self.add_token(token_a)
        if token_b.address not in self.tokens:
            self.add_token(token_b)
        
        pool = LiquidityPool(token_a, token_b, fee)
        pool_key = f"{token_a.address}-{token_b.address}"
        self.pools[pool_key] = pool
        return pool

    def get_pool(self, token_a: Token, token_b: Token) -> Optional[LiquidityPool]:
        """Get pool for two tokens"""
        pool_key = f"{token_a.address}-{token_b.address}"
        return self.pools.get(pool_key)

    def swap(self, user: str, token_in: Token, token_out: Token, amount_in: float, min_amount_out: float = 0) -> float:
        """Swap tokens using the appropriate pool"""
        pool = self.get_pool(token_in, token_out)
        if not pool:
            print(f" ❌ No pool found for {token_in.symbol}-{token_out.symbol}")
            return 0
        
        result = pool.swap(user, token_in, amount_in, min_amount_out)
        if result > 0:
            self.total_volume += amount_in
            self.fees_collected += amount_in * pool.fee
        return result

    def get_stats(self) -> Dict:
        """Get DEX statistics"""
        total_liquidity = sum(p.total_liquidity for p in self.pools.values())
        return {
            "name": self.name,
            "pools": len(self.pools),
            "tokens": len(self.tokens),
            "total_liquidity": total_liquidity,
            "total_volume": self.total_volume,
            "fees_collected": self.fees_collected
        }

# ============================================================================
# DEFI PROTOCOL
# ============================================================================

class DeFiProtocol:
    """Complete DeFi Protocol with all components"""
    
    def __init__(self, name: str = "DeFiProtocol"):
        self.name = name
        self.tokens: Dict[str, Token] = {}
        self.pools: Dict[str, LiquidityPool] = {}
        self.lending_pools: Dict[str, LendingPool] = {}
        self.staking_pools: Dict[str, StakingPool] = {}
        self.users: Dict[str, User] = {}
        self.dex = DEX(f"{name} DEX")
        self.total_value_locked = 0.0
        self.created_at = time.time()
        print(f" 🏛️  DeFi Protocol '{name}' initialized")

    def create_token(self, name: str, symbol: str, decimals: int = 18) -> Token:
        """Create a new token"""
        token = Token(name, symbol, decimals)
        self.tokens[token.address] = token
        self.dex.add_token(token)
        return token

    def create_pool(self, token_a: Token, token_b: Token, fee: float = 0.003) -> LiquidityPool:
        """Create a liquidity pool"""
        pool = self.dex.create_pool(token_a, token_b, fee)
        pool_key = f"{token_a.address}-{token_b.address}"
        self.pools[pool_key] = pool
        return pool

    def create_lending_pool(self, token: Token, name: str = None) -> LendingPool:
        """Create a lending pool"""
        pool = LendingPool(token, name)
        self.lending_pools[token.address] = pool
        return pool

    def create_staking_pool(self, staking_token: Token, reward_token: Token, reward_rate: float = 0.1) -> StakingPool:
        """Create a staking pool"""
        pool = StakingPool(staking_token, reward_token, reward_rate)
        self.staking_pools[staking_token.address] = pool
        return pool

    def register_user(self, name: str) -> User:
        """Register a new user"""
        address = f"0x{hashlib.md5(f'{name}{time.time()}'.encode()).hexdigest()[:16]}"
        user = User(name=name, address=address)
        self.users[address] = user
        print(f" 👤 User registered: {name} ({address[:16]}...)")
        return user

    def get_user(self, address: str) -> Optional[User]:
        """Get user by address"""
        return self.users.get(address)

    def get_stats(self) -> Dict:
        """Get protocol statistics"""
        tvl = 0
        for pool in self.pools.values():
            tvl += pool.reserve_a + pool.reserve_b
        for lending_pool in self.lending_pools.values():
            tvl += lending_pool.total_deposits
        
        self.total_value_locked = tvl
        
        return {
            "name": self.name,
            "tokens": len(self.tokens),
            "pools": len(self.pools),
            "lending_pools": len(self.lending_pools),
            "staking_pools": len(self.staking_pools),
            "users": len(self.users),
            "total_value_locked": tvl,
            "dex_volume": self.dex.total_volume,
            "dex_fees": self.dex.fees_collected
        }

# ============================================================================
# DEMONSTRATION
# ============================================================================

def run_defi_demo():
    """Run complete DeFi protocol demonstration"""
    
    print("=" * 60)
    print(" 🚀 DeFi PROTOCOL DEMONSTRATION")
    print("=" * 60)

    # Initialize protocol
    print("\n 🏛️  Initializing DeFi Protocol...")
    defi = DeFiProtocol("MyDeFi")

    # Create tokens
    print("\n 📝 Creating Tokens...")
    eth = defi.create_token("Ethereum", "ETH")
    usdc = defi.create_token("USD Coin", "USDC")
    dai = defi.create_token("Dai", "DAI")
    wbtc = defi.create_token("Wrapped Bitcoin", "WBTC")
    defi_token = defi.create_token("DeFi Protocol Token", "DFP", 18)

    print(f"   ✅ Created tokens: ETH, USDC, DAI, WBTC, DFP")

    # Register users
    print("\n 👤 Registering Users...")
    alice = defi.register_user("Alice")
    bob = defi.register_user("Bob")
    charlie = defi.register_user("Charlie")
    diana = defi.register_user("Diana")

    # Mint initial tokens
    print("\n 💰 Minting Initial Tokens...")
    initial_supply = 100000
    
    for token in [eth, usdc, dai, wbtc, defi_token]:
        token.mint(defi.name, initial_supply * 100)
        print(f"   Minted {initial_supply * 100} {token.symbol}")

    # Distribute tokens to users
    print("\n 📤 Distributing Tokens to Users...")
    for user in [alice, bob, charlie, diana]:
        for token in [eth, usdc, dai]:
            token.transfer(defi.name, user.address, 1000)
        print(f"   Distributed to {user.name}")

    # Create liquidity pools
    print("\n 🏊 Creating Liquidity Pools...")
    eth_usdc_pool = defi.create_pool(eth, usdc, 0.003)
    eth_dai_pool = defi.create_pool(eth, dai, 0.003)
    wbtc_usdc_pool = defi.create_pool(wbtc, usdc, 0.003)

    # Add liquidity
    print("\n 💧 Adding Liquidity...")
    
    print("\n Alice adds liquidity to ETH/USDC pool:")
    eth_usdc_pool.add_liquidity(alice.address, 100, 200000)
    
    print("\n Bob adds liquidity to ETH/DAI pool:")
    eth_dai_pool.add_liquidity(bob.address, 80, 160000)
    
    print("\n Charlie adds liquidity to WBTC/USDC pool:")
    wbtc_usdc_pool.add_liquidity(charlie.address, 10, 300000)

    # Create lending pools
    print("\n 🏦 Creating Lending Pools...")
    eth_lending = defi.create_lending_pool(eth, "ETH Lending Pool")
    usdc_lending = defi.create_lending_pool(usdc, "USDC Lending Pool")

    # Lending operations
    print("\n 📊 Lending Operations...")
    
    print("\n Diana deposits ETH to lending pool:")
    eth_lending.deposit(diana.address, 50)
    
    print("\n Alice borrows USDC from lending pool:")
    usdc_lending.borrow(alice.address, 5000)

    # Create staking pool
    print("\n 🌾 Creating Staking Pool...")
    staking_pool = defi.create_staking_pool(eth, defi_token, 0.15)

    # Staking operations
    print("\n 📈 Staking Operations...")
    
    print("\n Bob stakes ETH to earn DFP rewards:")
    staking_pool.stake(bob.address, 50)

    # DEX trading
    print("\n 📊 Trading on DEX...")
    
    print("\n Charlie swaps 10 ETH for USDC:")
    defi.dex.swap(charlie.address, eth, usdc, 10)
    
    print("\n Diana swaps 5000 USDC for ETH:")
    defi.dex.swap(diana.address, usdc, eth, 5000)

    # Show pool information
    print("\n 📋 Pool Information:")
    for pool in defi.pools.values():
        info = pool.get_info()
        print(f"\n  {info['name']}:")
        print(f"    Reserve A: {info['reserve_a']:.2f}")
        print(f"    Reserve B: {info['reserve_b']:.2f}")
        print(f"    Price: 1 {pool.token_a.symbol} = {info['price']:.2f} {pool.token_b.symbol}")
        print(f"    Fee: {info['fee']:.1f}%")
        print(f"    Total Liquidity: {info['total_liquidity']:.2f}")

    # Show lending pool information
    print("\n 📋 Lending Pool Information:")
    for lending_pool in defi.lending_pools.values():
        info = lending_pool.get_info()
        print(f"\n  {info['name']}:")
        print(f"    Deposits: {info['total_deposits']:.2f}")
        print(f"    Borrows: {info['total_borrows']:.2f}")
        print(f"    Utilization: {info['utilization']:.1f}%")
        print(f"    Interest Rate: {info['interest_rate']:.1f}%")

    # Show staking pool information
    print("\n 📋 Staking Pool Information:")
    info = staking_pool.get_info()
    print(f"\n  {info['staking_token']} → {info['reward_token']}:")
    print(f"    Total Staked: {info['total_staked']:.2f}")
    print(f"    Reward Rate: {info['reward_rate']:.1f}%")
    print(f"    Stakers: {info['stakers']}")

    # Show user balances
    print("\n 💰 User Balances:")
    for user in [alice, bob, charlie, diana]:
        print(f"\n  {user.name}:")
        for token in [eth, usdc, dai, wbtc, defi_token]:
            balance = token.balance_of(user.address)
            if balance > 0:
                print(f"    {token.symbol}: {balance:.2f}")

    # Protocol statistics
    print("\n 📊 Protocol Statistics:")
    stats = defi.get_stats()
    for key, value in stats.items():
        print(f"  {key}: {value}")

    print("\n" + "=" * 60)
    print(" ✅ DeFi DEMONSTRATION COMPLETE")
    print("=" * 60)

if __name__ == "__main__":
    run_defi_demo()

1.2 DEX (Decentralized Exchange)

What is a DEX?

A Decentralized Exchange (DEX) is a peer-to-peer marketplace where users can trade cryptocurrencies without an intermediary. Unlike centralized exchanges (CEX) like Coinbase or Binance, DEXs don’t hold user funds or require KYC (Know Your Customer) verification. Trades are executed directly between users through smart contracts.

How DEXs Work:

  1. Order Book DEXs: Match buyers and sellers using an order book (e.g., 0x, dYdX)
  2. AMM DEXs: Use liquidity pools and algorithms to determine prices (e.g., Uniswap, Curve)
  3. Aggregators: Find the best prices across multiple DEXs (e.g., 1inch, Paraswap)

Advantages of DEXs:

AdvantageDescription
Self-CustodyUsers control their funds at all times
No KYCNo identity verification required
Censorship-ResistantNo central authority can block trades
TransparentAll transactions are on-chain
ComposableCan be integrated with other DeFi protocols

Example: Uniswap is the most popular DEX, using an AMM model where users trade against liquidity pools rather than order books.

1.3 AMM (Automated Market Maker)

What is AMM?

An Automated Market Maker (AMM) is a protocol that uses algorithms to determine asset prices and provide liquidity, eliminating the need for traditional order books. AMMs are the backbone of most modern DEXs.

Key Formula – Constant Product:

x * y = k

Where:

  • x = Reserve of token A
  • y = Reserve of token B
  • k = Constant product (remains the same)

How AMM Works:

  1. Liquidity providers deposit equal value of two tokens into a pool
  2. The pool calculates prices based on the ratio of reserves
  3. Traders swap tokens, changing the ratio and thus the price
  4. Price moves with the square root of the trade size

Price Impact:

The larger the trade relative to the pool, the greater the price impact. This is why large trades should be split across multiple pools.

Example:

In an ETH/USDC pool with 10 ETH and 20,000 USDC:

  • Initial Price: 1 ETH = 2,000 USDC
  • Swap: User swaps 1 ETH for USDC
  • New Reserves: 11 ETH, 18,181.82 USDC (approximately)
  • New Price: 1 ETH = 1,652.89 USDC
  • Price Impact: ~17.35%

1.4 Liquidity Pools

What are Liquidity Pools?

Liquidity pools are pools of tokens locked in smart contracts that provide liquidity for trading. Users (liquidity providers) deposit tokens and earn fees from trades.

How Liquidity Pools Work:

  1. Deposit: LP deposits equal value of two tokens
  2. LP Tokens: Receives LP tokens representing share of the pool
  3. Earn Fees: Receives a share of trading fees proportional to their share
  4. Withdraw: Can withdraw their share at any time

Impermanent Loss:

When the price of deposited tokens changes relative to when they were deposited, LPs may experience “impermanent loss.” This is a temporary loss that disappears if prices return to the initial ratio.

Example:

Alice deposits 10 ETH and 20,000 USDC (total value: $40,000). If ETH price doubles to $4,000, her share would be worth more in ETH terms but less in USDC terms than if she had just held.

1.5 Yield Farming

What is Yield Farming?

Yield farming is the practice of staking or lending crypto assets to generate high returns, often through multiple protocols. Users “farm” yield by moving their assets between different protocols to maximize returns.

How Yield Farming Works:

  1. Provide Liquidity: Deposit tokens into a liquidity pool
  2. Receive LP Tokens: Get LP tokens representing your share
  3. Stake LP Tokens: Stake LP tokens in a farm
  4. Earn Rewards: Receive additional tokens as rewards
  5. Compound: Reinvest rewards for higher returns

Example:

  1. Deposit ETH and USDC into Uniswap pool
  2. Receive UNI-V2 LP tokens
  3. Stake LP tokens in a yield farm
  4. Earn rewards in the farm’s native token
  5. Sell or stake rewards for even more returns

1.6 Staking

What is Staking?

Staking involves locking or committing cryptocurrency to help secure and operate a Proof of Stake (PoS) blockchain in exchange for rewards. It’s the primary mechanism for Proof of Stake (PoS) blockchains.

How Staking Works:

  1. Lock Tokens: Lock up a minimum amount of tokens
  2. Become Validator/Delegate: Either run a validator node or delegate to one
  3. Earn Rewards: Receive rewards for helping secure the network
  4. Unstaking: Wait for the unbonding period to withdraw

Example:

Ethereum staking: Lock 32 ETH to become a validator and earn ~4-5% APY. Validators are selected to propose blocks and attest to other blocks, earning rewards for their participation.

1.7 Lending and Borrowing

What is DeFi Lending/Borrowing?

Users can lend assets to earn interest or borrow assets by providing collateral. This creates a peer-to-peer lending market without banks.

How Lending Works:

  1. Deposit: User deposits assets into a lending pool
  2. Earn Interest: Earn interest from borrowers
  3. Withdraw: Can withdraw anytime

How Borrowing Works:

  1. Provide Collateral: Deposit assets as collateral (over-collateralized)
  2. Borrow: Borrow up to a certain percentage of collateral value
  3. Pay Interest: Pay variable or fixed interest
  4. Repay: Repay to unlock collateral

Example:

Alice deposits 10 ETH into Aave as collateral and borrows 5,000 DAI at variable interest. If ETH price drops significantly, her position may be liquidated.

1.8 Flash Loans

What are Flash Loans?

Flash loans are uncollateralized loans that allow users to borrow assets and repay them within the same blockchain transaction.They are a unique DeFi innovation that enables arbitrage, refinancing, and other strategies.

How Flash Loans Work:

  1. Borrow: Borrow assets in a single transaction
  2. Use: Use the assets for arbitrage, refinancing, etc.
  3. Repay: Repay the loan + fee in the same transaction
  4. Revert: If repayment fails, the entire transaction reverts

Example:

  1. Borrow 10,000 DAI
  2. Use 10,000 DAI to arbitrage between two exchanges
  3. Profit 100 DAI
  4. Repay 10,000 DAI + 0.09% fee
  5. Keep profit

1.9 Stablecoins

What are Stablecoins?

Stablecoins are cryptocurrencies pegged to stable assets like fiat currency (usually USD). They are designed to provide greater price stability in the highly volatile cryptocurrency market.

Types of Stablecoins:

TypeDescriptionExample
Fiat-BackedBacked by fiat currency reservesUSDC, USDT
Crypto-BackedOver-collateralized by cryptoDAI
AlgorithmicAlgorithm controls supplyUST (failed)

Example: USDC is backed by USD reserves held in regulated financial institutions, with regular audits to verify the reserves.

1.10 Synthetic Assets

What are Synthetic Assets?

Synthetic assets are tokenized derivatives that track the price of real-world assets without holding the underlying asset.

Example: Synthetix allows users to mint synthetic assets like sBTC (tracking Bitcoin) or sGold (tracking gold) by locking SNX tokens as collateral.

1.11 Perpetual Protocols

What are Perpetual Protocols?

Perpetual protocols offer perpetual futures contracts that never expire, allowing traders to take leveraged positions on crypto assets.

Example: GMX is a perpetual DEX that allows up to 30x leverage on ETH and BTC positions.

2. NFTs (Non-Fungible Tokens)

2.1 NFT Architecture

What are NFTs?

Non-Fungible Tokens (NFTs) are unique digital assets representing ownership of a specific item, verified on the blockchain. Unlike fungible tokens (like ETH or USDC), each NFT is unique and cannot be exchanged on a one-to-one basis.

NFT Components:

ComponentDescription
Token IDUnique identifier for the NFT
Contract AddressThe smart contract address
MetadataName, description, image URI
OwnerCurrent owner address
PropertiesAttributes and traits

Code Example – Complete NFT System:

"""
COMPLETE NFT SYSTEM
====================
Full NFT implementation with:
- ERC-721 token standard
- Metadata management
- Minting and trading
- Royalties
- Dynamic NFTs
"""

import hashlib
import json
import time
import random
from typing import Dict, List, Any, Optional
from datetime import datetime
from dataclasses import dataclass, field
from enum import Enum

# ============================================================================
# NFT ENUMS AND TYPES
# ============================================================================

class NFTStatus(Enum):
    """NFT status states"""
    AVAILABLE = "Available"
    LISTED = "Listed"
    SOLD = "Sold"
    BURNED = "Burned"

class NFTTraitType(Enum):
    """Types of NFT traits"""
    ARTIST = "Artist"
    STYLE = "Style"
    YEAR = "Year"
    RARITY = "Rarity"
    PROPERTY = "Property"
    LEVEL = "Level"

@dataclass
class NFTTrait:
    """NFT trait/attribute"""
    trait_type: NFTTraitType
    value: Any
    display_type: Optional[str] = None

@dataclass
class NFTSale:
    """NFT sale record"""
    token_id: int
    seller: str
    buyer: str
    price: float
    timestamp: float
    marketplace_fee: float
    royalty_fee: float

# ============================================================================
# NFT CORE
# ============================================================================

class NFT:
    """NFT token representation with full metadata support"""

    def __init__(self, token_id: int, name: str, description: str, creator: str):
        self.token_id = token_id
        self.name = name
        self.description = description
        self.creator = creator
        self.owner = creator
        self.metadata_uri = f"ipfs://Qm{hashlib.md5(f'{name}{token_id}'.encode()).hexdigest()[:16]}"
        self.attributes: List[NFTTrait] = []
        self.created_at = time.time()
        self.royalty_percentage = 5.0  # 5% royalty to creator
        self.is_dynamic = False
        self.dynamic_data: Dict[str, Any] = {}
        self.status = NFTStatus.AVAILABLE
        self.image_hash = hashlib.sha256(f"{name}_{token_id}".encode()).hexdigest()[:16]
        self.edition = 1
        self.edition_total = 1
        
        print(f" 🎨 NFT created: #{token_id} - {name}")
        print(f"    Creator: {creator[:16]}...")
        print(f"    Owner: {owner[:16]}...")

    def add_trait(self, trait_type: NFTTraitType, value: Any, display_type: Optional[str] = None) -> 'NFT':
        """Add an attribute/trait to the NFT"""
        self.attributes.append(NFTTrait(trait_type, value, display_type))
        return self

    def add_attribute(self, key: str, value: Any) -> 'NFT':
        """Add a custom attribute (legacy method)"""
        try:
            trait_type = NFTTraitType(key.upper())
        except ValueError:
            trait_type = NFTTraitType.PROPERTY
        return self.add_trait(trait_type, value)

    def transfer(self, from_addr: str, to_addr: str) -> bool:
        """Transfer NFT to new owner"""
        if from_addr != self.owner:
            print(f" ❌ {from_addr[:16]}... is not the owner")
            return False

        old_owner = self.owner
        self.owner = to_addr
        self.status = NFTStatus.AVAILABLE
        
        print(f" 🔄 NFT #{self.token_id} transferred: {old_owner[:16]}... → {to_addr[:16]}...")

        # Simulate royalty payment
        if old_owner != self.creator:
            royalty_amount = 0.01  # 0.01 ETH
            print(f" 💰 Royalty paid: {royalty_amount} ETH to {self.creator[:16]}...")

        return True

    def set_dynamic_data(self, data: Dict[str, Any]) -> 'NFT':
        """Set dynamic data for dynamic NFTs"""
        self.is_dynamic = True
        self.dynamic_data.update(data)
        print(f" 🔄 Dynamic NFT updated: {data}")
        return self

    def update_dynamic_property(self, key: str, value: Any) -> 'NFT':
        """Update a single dynamic property"""
        self.is_dynamic = True
        self.dynamic_data[key] = value
        print(f" 🔄 Dynamic property updated: {key} = {value}")
        return self

    def set_edition(self, edition: int, total: int) -> 'NFT':
        """Set edition information"""
        self.edition = edition
        self.edition_total = total
        return self

    def get_metadata(self) -> Dict[str, Any]:
        """Get complete NFT metadata"""
        return {
            "token_id": self.token_id,
            "name": self.name,
            "description": self.description,
            "creator": self.creator,
            "owner": self.owner,
            "metadata_uri": self.metadata_uri,
            "image_hash": self.image_hash,
            "attributes": [
                {
                    "trait_type": trait.trait_type.value,
                    "value": trait.value,
                    "display_type": trait.display_type
                }
                for trait in self.attributes
            ],
            "royalty_percentage": self.royalty_percentage,
            "is_dynamic": self.is_dynamic,
            "dynamic_data": self.dynamic_data if self.is_dynamic else None,
            "status": self.status.value,
            "edition": self.edition,
            "edition_total": self.edition_total,
            "created_at": datetime.fromtimestamp(self.created_at).isoformat()
        }

    def to_dict(self) -> Dict[str, Any]:
        """Convert NFT to dictionary"""
        return self.get_metadata()

    def __str__(self) -> str:
        return f"NFT #{self.token_id} - {self.name} (Owner: {self.owner[:16]}...)"

# ============================================================================
# NFT COLLECTION
# ============================================================================

class NFTCollection:
    """NFT Collection (ERC-721 contract simulation) with full management"""

    def __init__(self, name: str, symbol: str, creator: str, description: str = ""):
        self.name = name
        self.symbol = symbol
        self.creator = creator
        self.description = description
        self.address = f"0x{hashlib.md5(f'{name}{time.time()}'.encode()).hexdigest()[:16]}"
        self.tokens: Dict[int, NFT] = {}
        self.next_token_id = 1
        self.owner_to_tokens: Dict[str, List[int]] = {}
        self.token_approvals: Dict[int, str] = {}
        self.operator_approvals: Dict[str, Dict[str, bool]] = {}
        self.created_at = time.time()
        self.total_sales = 0
        self.total_volume = 0.0
        
        print(f" 📚 NFT Collection: {name} ({symbol}) at {self.address}")

    def mint(self, name: str, description: str, owner: str) -> NFT:
        """Mint a new NFT"""
        token_id = self.next_token_id
        self.next_token_id += 1

        nft = NFT(token_id, name, description, owner)
        self.tokens[token_id] = nft

        if owner not in self.owner_to_tokens:
            self.owner_to_tokens[owner] = []
        self.owner_to_tokens[owner].append(token_id)

        print(f" ✅ Minted NFT #{token_id} to {owner[:16]}...")
        return nft

    def mint_with_metadata(self, name: str, description: str, owner: str, 
                          traits: Dict[str, Any], royalty: float = 5.0) -> NFT:
        """Mint NFT with traits and royalty"""
        nft = self.mint(name, description, owner)
        for key, value in traits.items():
            nft.add_attribute(key, value)
        nft.royalty_percentage = royalty
        return nft

    def transfer(self, token_id: int, from_addr: str, to_addr: str) -> bool:
        """Transfer NFT to new owner"""
        if token_id not in self.tokens:
            print(f" ❌ NFT #{token_id} not found")
            return False

        nft = self.tokens[token_id]

        # Remove from current owner's list
        if from_addr in self.owner_to_tokens:
            if token_id in self.owner_to_tokens[from_addr]:
                self.owner_to_tokens[from_addr].remove(token_id)

        # Transfer
        success = nft.transfer(from_addr, to_addr)
        
        if success:
            # Add to new owner's list
            if to_addr not in self.owner_to_tokens:
                self.owner_to_tokens[to_addr] = []
            self.owner_to_tokens[to_addr].append(token_id)
            
            # Clear approvals
            self.token_approvals.pop(token_id, None)
            
        return success

    def get_nft(self, token_id: int) -> Optional[NFT]:
        """Get NFT by token ID"""
        return self.tokens.get(token_id)

    def get_tokens_by_owner(self, owner: str) -> List[NFT]:
        """Get all NFTs owned by an address"""
        token_ids = self.owner_to_tokens.get(owner, [])
        return [self.tokens[token_id] for token_id in token_ids if token_id in self.tokens]

    def approve(self, token_id: int, approved: str) -> bool:
        """Approve address to transfer NFT"""
        if token_id not in self.tokens:
            return False
        if self.tokens[token_id].owner == approved:
            return False
        
        self.token_approvals[token_id] = approved
        return True

    def set_approval_for_all(self, owner: str, operator: str, approved: bool) -> bool:
        """Set approval for all NFTs"""
        if owner == operator:
            return False
        
        if owner not in self.operator_approvals:
            self.operator_approvals[owner] = {}
        self.operator_approvals[owner][operator] = approved
        return True

    def is_approved_for_all(self, owner: str, operator: str) -> bool:
        """Check if operator is approved for all"""
        return self.operator_approvals.get(owner, {}).get(operator, False)

    def get_approved(self, token_id: int) -> Optional[str]:
        """Get approved address for token"""
        return self.token_approvals.get(token_id)

    def burn(self, token_id: int) -> bool:
        """Burn (destroy) an NFT"""
        if token_id not in self.tokens:
            return False
        
        nft = self.tokens[token_id]
        owner = nft.owner
        
        # Remove from owner's list
        if owner in self.owner_to_tokens and token_id in self.owner_to_tokens[owner]:
            self.owner_to_tokens[owner].remove(token_id)
        
        # Remove approvals
        self.token_approvals.pop(token_id, None)
        
        # Delete token
        del self.tokens[token_id]
        
        print(f" 🔥 NFT #{token_id} burned")
        return True

    def get_collection_info(self) -> Dict[str, Any]:
        """Get collection information"""
        return {
            "name": self.name,
            "symbol": self.symbol,
            "address": self.address,
            "creator": self.creator,
            "description": self.description,
            "total_supply": len(self.tokens),
            "owners": len(self.owner_to_tokens),
            "next_token_id": self.next_token_id,
            "total_sales": self.total_sales,
            "total_volume": self.total_volume,
            "created_at": datetime.fromtimestamp(self.created_at).isoformat()
        }

    def get_summary(self) -> Dict[str, Any]:
        """Get collection summary with stats"""
        info = self.get_collection_info()
        info["tokens"] = [
            {
                "id": token_id,
                "name": nft.name,
                "owner": nft.owner[:16] + "...",
                "status": nft.status.value
            }
            for token_id, nft in self.tokens.items()
        ]
        return info

# ============================================================================
# NFT MARKETPLACE
# ============================================================================

class NFTMarketplace:
    """NFT Marketplace for trading NFTs"""

    def __init__(self, name: str = "NFTMarket", fee_percentage: float = 2.5):
        self.name = name
        self.fee_percentage = fee_percentage
        self.listings: Dict[int, Dict] = {}
        self.sales: List[NFTSale] = []
        self.total_volume = 0.0
        self.created_at = time.time()
        print(f" 🏪 NFT Marketplace '{name}' initialized (Fee: {fee_percentage}%)")

    def list_nft(self, token_id: int, price: float, seller: str, collection: NFTCollection) -> bool:
        """List NFT for sale"""
        nft = collection.get_nft(token_id)
        if not nft:
            print(f" ❌ NFT #{token_id} not found")
            return False
        
        if nft.owner != seller:
            print(f" ❌ {seller[:16]}... is not the owner")
            return False
        
        self.listings[token_id] = {
            "token_id": token_id,
            "price": price,
            "seller": seller,
            "listed_at": time.time(),
            "status": "active"
        }
        nft.status = NFTStatus.LISTED
        
        print(f" 📢 NFT #{token_id} listed for {price} ETH by {seller[:16]}...")
        return True

    def buy_nft(self, token_id: int, buyer: str, collection: NFTCollection) -> bool:
        """Purchase an NFT"""
        if token_id not in self.listings:
            print(f" ❌ NFT #{token_id} not listed")
            return False

        listing = self.listings[token_id]
        nft = collection.get_nft(token_id)
        
        if not nft:
            print(f" ❌ NFT #{token_id} not found")
            return False

        # Calculate fees
        sale_price = listing["price"]
        marketplace_fee = sale_price * self.fee_percentage / 100
        creator_royalty = sale_price * nft.royalty_percentage / 100
        seller_receives = sale_price - marketplace_fee - creator_royalty

        # Transfer NFT
        if collection.transfer(token_id, listing["seller"], buyer):
            # Record sale
            sale = NFTSale(
                token_id=token_id,
                seller=listing["seller"],
                buyer=buyer,
                price=sale_price,
                timestamp=time.time(),
                marketplace_fee=marketplace_fee,
                royalty_fee=creator_royalty
            )
            self.sales.append(sale)
            self.total_volume += sale_price
            collection.total_sales += 1
            collection.total_volume += sale_price

            # Remove listing
            del self.listings[token_id]
            nft.status = NFTStatus.SOLD

            print(f" 🎉 NFT #{token_id} sold for {sale_price} ETH")
            print(f"    Seller receives: {seller_receives:.4f} ETH")
            print(f"    Marketplace fee: {marketplace_fee:.4f} ETH")
            print(f"    Royalty to creator: {creator_royalty:.4f} ETH")

            return True

        return False

    def cancel_listing(self, token_id: int, seller: str) -> bool:
        """Cancel NFT listing"""
        if token_id not in self.listings:
            print(f" ❌ NFT #{token_id} not listed")
            return False
        
        listing = self.listings[token_id]
        if listing["seller"] != seller:
            print(f" ❌ {seller[:16]}... is not the seller")
            return False
        
        del self.listings[token_id]
        print(f" 🚫 NFT #{token_id} listing cancelled")
        return True

    def update_price(self, token_id: int, new_price: float, seller: str) -> bool:
        """Update listing price"""
        if token_id not in self.listings:
            print(f" ❌ NFT #{token_id} not listed")
            return False
        
        listing = self.listings[token_id]
        if listing["seller"] != seller:
            print(f" ❌ {seller[:16]}... is not the seller")
            return False
        
        old_price = listing["price"]
        listing["price"] = new_price
        
        print(f" 💰 NFT #{token_id} price updated: {old_price} → {new_price} ETH")
        return True

    def get_listings(self) -> List[Dict]:
        """Get all active listings"""
        return list(self.listings.values())

    def get_sales_history(self, limit: int = 10) -> List[Dict]:
        """Get sales history"""
        return [
            {
                "token_id": sale.token_id,
                "seller": sale.seller[:16] + "...",
                "buyer": sale.buyer[:16] + "...",
                "price": sale.price,
                "timestamp": datetime.fromtimestamp(sale.timestamp).isoformat()
            }
            for sale in self.sales[-limit:]
        ]

    def get_stats(self) -> Dict:
        """Get marketplace statistics"""
        return {
            "name": self.name,
            "total_listings": len(self.listings),
            "total_sales": len(self.sales),
            "total_volume": self.total_volume,
            "fee_percentage": self.fee_percentage
        }

# ============================================================================
# NFT DEMONSTRATION
# ============================================================================

def nft_demo():
    """Demonstrate complete NFT system functionality"""

    print("=" * 60)
    print(" 🎨 NFT SYSTEM DEMONSTRATION")
    print("=" * 60)

    # Create collection
    print("\n 📚 Creating NFT Collection...")
    collection = NFTCollection("MyArt", "ART", "Alice", "A collection of digital artwork")

    # Create marketplace
    print("\n 🏪 Creating NFT Marketplace...")
    marketplace = NFTMarketplace("ArtMarket", fee_percentage=2.5)

    # Mint NFTs
    print("\n 🎨 Minting NFTs...")
    
    nft1 = collection.mint("Sunset Painting", "Beautiful sunset over the ocean", "Alice")
    nft1.add_attribute("artist", "Alice")
    nft1.add_attribute("year", "2024")
    nft1.add_attribute("style", "Impressionist")
    nft1.add_attribute("rarity", "Rare")

    nft2 = collection.mint("Mountain Scene", "Mountain landscape in winter", "Alice")
    nft2.add_attribute("artist", "Alice")
    nft2.add_attribute("year", "2024")
    nft2.add_attribute("style", "Realist")
    nft2.add_attribute("rarity", "Common")

    nft3 = collection.mint("City Night", "City skyline at night", "Bob")
    nft3.add_attribute("artist", "Bob")
    nft3.add_attribute("year", "2024")
    nft3.add_attribute("style", "Modern")
    nft3.add_attribute("rarity", "Epic")

    nft4 = collection.mint_with_metadata(
        "Dynamic Art",
        "Art that changes with time",
        "Alice",
        {"artist": "Alice", "year": "2024", "style": "Dynamic"},
        10.0
    )
    nft4.set_dynamic_data({"current_phase": "Phase 1", "time_based": True})

    # Show metadata
    print("\n 📋 NFT Metadata:")
    print("-" * 40)

    for token_id in sorted(collection.tokens.keys()):
        nft = collection.get_nft(token_id)
        metadata = nft.get_metadata()
        print(f"\n  NFT #{token_id} - {metadata['name']}:")
        print(f"    Description: {metadata['description']}")
        print(f"    Creator: {metadata['creator'][:16]}...")
        print(f"    Owner: {metadata['owner'][:16]}...")
        print(f"    Attributes: {[f'{a["trait_type"]}: {a["value"]}' for a in metadata['attributes']]}")
        if metadata['is_dynamic']:
            print(f"    Dynamic Data: {metadata['dynamic_data']}")

    # List NFTs on marketplace
    print("\n 📢 Listing NFTs on Marketplace...")
    marketplace.list_nft(1, 5.0, "Alice", collection)
    marketplace.list_nft(3, 3.0, "Bob", collection)
    marketplace.list_nft(4, 8.0, "Alice", collection)

    # Show active listings
    print("\n 📋 Active Listings:")
    for listing in marketplace.get_listings():
        print(f"  NFT #{listing['token_id']} - {listing['price']} ETH (Seller: {listing['seller'][:16]}...)")

    # Buy NFT
    print("\n 🛒 Purchasing NFTs...")
    
    print("\n  Charlie buys NFT #1")
    marketplace.buy_nft(1, "Charlie", collection)
    
    print("\n  Diana buys NFT #3")
    marketplace.buy_nft(3, "Diana", collection)

    # Show collection after sales
    print("\n 📚 Collection After Sales:")
    print("-" * 40)

    for token_id in sorted(collection.tokens.keys()):
        nft = collection.get_nft(token_id)
        print(f"  NFT #{token_id}: {nft.name} -> Owner: {nft.owner[:16]}... (Status: {nft.status.value})")

    # Sales history
    print("\n 📊 Sales History:")
    print("-" * 40)

    for sale in marketplace.get_sales_history():
        print(f"  NFT #{sale['token_id']} - {sale['price']} ETH")
        print(f"    {sale['seller']} → {sale['buyer']}")

    # Collection summary
    print("\n 📊 Collection Summary:")
    print("-" * 40)

    summary = collection.get_summary()
    print(f"  Name: {summary['name']}")
    print(f"  Symbol: {summary['symbol']}")
    print(f"  Total Supply: {summary['total_supply']}")
    print(f"  Owners: {summary['owners']}")
    print(f"  Total Sales: {summary['total_sales']}")
    print(f"  Total Volume: {summary['total_volume']} ETH")

    # Marketplace stats
    print("\n 📊 Marketplace Stats:")
    print("-" * 40)

    stats = marketplace.get_stats()
    print(f"  Name: {stats['name']}")
    print(f"  Total Listings: {stats['total_listings']}")
    print(f"  Total Sales: {stats['total_sales']}")
    print(f"  Total Volume: {stats['total_volume']} ETH")
    print(f"  Fee: {stats['fee_percentage']}%")

    print("\n" + "=" * 60)
    print(" ✅ NFT DEMONSTRATION COMPLETE")
    print("=" * 60)

if __name__ == "__main__":
    nft_demo()

2.2 Metadata

What is NFT Metadata?

NFT Metadata is the descriptive information about an NFT, stored off-chain (usually on IPFS) and linked via the token’s URI. It provides the “content” of the NFT.

Metadata Structure:

{
    "name": "CyberPunk #001",
    "description": "A unique cyberpunk character NFT",
    "image": "ipfs://QmXyZ...",
    "attributes": [
        {
            "trait_type": "Background",
            "value": "Neon City"
        },
        {
            "trait_type": "Head",
            "value": "Cyber Helmet"
        },
        {
            "trait_type": "Eyes",
            "value": "Holographic"
        }
    ],
    "properties": {
        "rarity": "Legendary",
        "collection": "CyberPunks"
    }
}

Example: An NFT of a digital artwork has metadata containing the artist’s name, description, image URL, and attributes like color, style, and rarity.

2.3 Minting

What is Minting?

Minting is the process of creating a new NFT by deploying it on the blockchain, recording its ownership, and generating its unique token ID.

Minting Process:

  1. Create Art/Content: Create the digital asset
  2. Upload to IPFS: Store the asset and metadata on IPFS
  3. Deploy Contract: Create an NFT smart contract
  4. Mint NFT: Call the mint function with metadata URI
  5. Assign Owner: The minter becomes the owner

Example: An artist creates a digital artwork and “mints” it on OpenSea, paying gas fees to create the NFT on the blockchain.

2.4 Royalties

What are Royalties?

Royalties are automatic payments to creators on secondary sales, typically 5-10% of the sale price, enforced by the smart contract (ERC-2981).

How Royalties Work:

  1. Set Royalty: Creator sets royalty percentage (e.g., 10%)
  2. List NFT: NFT is listed on a marketplace
  3. Secondary Sale: NFT sells for 1 ETH
  4. Royalty Paid: Creator automatically receives 0.1 ETH

Example: An artist sets 10% royalty on their NFT. When it sells for 1 ETH, they automatically receive 0.1 ETH.

2.5 Dynamic NFTs

What are Dynamic NFTs?

Dynamic NFTs can change their metadata or attributes based on external data or conditions. They are “living” NFTs that evolve over time.

Example: A sports card NFT updates its stats based on real-world player performance using Chainlink oracles.

2.6 NFT Marketplaces

What are NFT Marketplaces?

NFT Marketplaces are platforms where users can mint, buy, sell, and trade NFTs.

Popular NFT Marketplaces:

MarketplaceFeaturesSupported Chains
OpenSeaLargest, broadest selectionEthereum, Polygon, Solana
RaribleCommunity-ownedEthereum, Tezos
SuperRareCurated digital artEthereum
LooksRareToken rewardsEthereum
BlurProfessional tradersEthereum

3. DAOs (Decentralized Autonomous Organizations)

3.1 Governance

What is DAO Governance?

DAO Governance is the system by which token holders vote on proposals to manage the organization’s treasury, operations, and direction. It enables decentralized decision-making.

Governance Process:

  1. Proposal Creation: Member creates a proposal
  2. Discussion: Community discusses the proposal
  3. Voting: Token holders vote (for/against/abstain)
  4. Execution: If passed, the proposal is executed

Example: Uniswap DAO token holders vote on protocol upgrades, fee structures, and treasury allocation.

Code Example – Complete DAO System:

"""
COMPLETE DAO SYSTEM
====================
Full DAO implementation with:
- Governance tokens
- Proposal creation and voting
- Treasury management
- Voting mechanisms
- Execution of proposals
"""

import hashlib
import time
import math
from typing import Dict, List, Any, Optional, Set
from datetime import datetime
from dataclasses import dataclass, field
from enum import Enum

# ============================================================================
# DAO ENUMS AND TYPES
# ============================================================================

class VoteChoice(Enum):
    """Vote choices"""
    FOR = "For"
    AGAINST = "Against"
    ABSTAIN = "Abstain"

class ProposalStatus(Enum):
    """Proposal status states"""
    PENDING = "Pending"
    ACTIVE = "Active"
    ENDED = "Ended"
    EXECUTED = "Executed"
    FAILED = "Failed"
    CANCELLED = "Cancelled"

class ProposalType(Enum):
    """Types of proposals"""
    TREASURY = "Treasury Allocation"
    MEMBERSHIP = "Membership Change"
    GOVERNANCE = "Governance Change"
    PARAMETER = "Parameter Change"
    GENERAL = "General"

@dataclass
class Vote:
    """Individual vote record"""
    voter: str
    choice: VoteChoice
    voting_power: float
    timestamp: float

@dataclass
class Proposal:
    """DAO proposal with full details"""
    id: int
    title: str
    description: str
    proposer: str
    proposal_type: ProposalType
    created_at: float
    end_time: float
    for_votes: float = 0.0
    against_votes: float = 0.0
    abstain_votes: float = 0.0
    executed: bool = False
    executed_at: Optional[float] = None
    cancelled: bool = False
    quorum: float = 0.04  # 4% quorum
    approval_threshold: float = 0.5  # 50% approval
    votes: Dict[str, Vote] = field(default_factory=dict)
    execution_data: Dict[str, Any] = field(default_factory=dict)

    def get_status(self) -> ProposalStatus:
        """Get current proposal status"""
        if self.cancelled:
            return ProposalStatus.CANCELLED
        if self.executed:
            return ProposalStatus.EXECUTED
        if time.time() > self.end_time:
            return ProposalStatus.ENDED
        return ProposalStatus.ACTIVE

    def get_result(self) -> str:
        """Get proposal result"""
        if self.cancelled:
            return "Cancelled"
        if self.executed:
            return "Executed"

        status = self.get_status()
        if status == ProposalStatus.ACTIVE:
            return "Not yet decided"

        total_votes = self.for_votes + self.against_votes
        if total_votes < self.quorum:
            return "Failed - Quorum not met"

        if self.for_votes / (self.for_votes + self.against_votes) >= self.approval_threshold:
            return "Passed"
        else:
            return "Failed"

    def get_vote_summary(self) -> Dict[str, Any]:
        """Get vote summary"""
        total = self.for_votes + self.against_votes + self.abstain_votes
        return {
            "for": self.for_votes,
            "against": self.against_votes,
            "abstain": self.abstain_votes,
            "total": total,
            "quorum": self.quorum,
            "status": self.get_status().value,
            "result": self.get_result(),
            "voters": len(self.votes)
        }

    def add_vote(self, voter: str, choice: VoteChoice, voting_power: float) -> bool:
        """Add a vote to the proposal"""
        if voter in self.votes:
            return False
        
        self.votes[voter] = Vote(voter, choice, voting_power, time.time())
        
        if choice == VoteChoice.FOR:
            self.for_votes += voting_power
        elif choice == VoteChoice.AGAINST:
            self.against_votes += voting_power
        elif choice == VoteChoice.ABSTAIN:
            self.abstain_votes += voting_power
        
        return True

# ============================================================================
# GOVERNANCE TOKEN
# ============================================================================

class GovToken:
    """Governance token (ERC-20 simulation) with delegation"""

    def __init__(self, name: str, symbol: str, total_supply: float):
        self.name = name
        self.symbol = symbol
        self.total_supply = total_supply
        self.balances: Dict[str, float] = {}
        self.delegates: Dict[str, str] = {}
        self.voting_power: Dict[str, float] = {}
        self.delegation_history: Dict[str, List[Dict]] = {}
        self.address = f"0x{hashlib.md5(f'{name}{time.time()}'.encode()).hexdigest()[:16]}"
        self.created_at = time.time()
        print(f" 🪙 Governance Token: {name} ({symbol})")

    def mint(self, to: str, amount: float) -> bool:
        """Mint governance tokens"""
        if amount <= 0:
            return False
        self.balances[to] = self.balances.get(to, 0) + amount
        self.total_supply += amount
        self._update_voting_power(to)
        return True

    def transfer(self, from_addr: str, to_addr: str, amount: float) -> bool:
        """Transfer tokens"""
        if amount <= 0:
            return False
        if self.balances.get(from_addr, 0) < amount:
            return False

        self.balances[from_addr] -= amount
        self.balances[to_addr] = self.balances.get(to_addr, 0) + amount
        
        self._update_voting_power(from_addr)
        self._update_voting_power(to_addr)
        return True

    def balance_of(self, address: str) -> float:
        """Get token balance"""
        return self.balances.get(address, 0)

    def delegate(self, delegator: str, delegate: str) -> bool:
        """Delegate voting power to another address"""
        if delegator == delegate:
            return False
        
        # Remove old delegation
        old_delegate = self.delegates.get(delegator)
        if old_delegate:
            self._recalculate_voting_power(old_delegate)
        
        self.delegates[delegator] = delegate
        
        # Record delegation history
        if delegator not in self.delegation_history:
            self.delegation_history[delegator] = []
        self.delegation_history[delegator].append({
            "to": delegate,
            "timestamp": time.time(),
            "amount": self.balances.get(delegator, 0)
        })
        
        self._update_voting_power(delegator)
        self._update_voting_power(delegate)
        return True

    def get_voting_power(self, address: str) -> float:
        """Get voting power of an address"""
        return self.voting_power.get(address, 0)

    def _update_voting_power(self, address: str):
        """Update voting power for an address"""
        self._recalculate_voting_power(address)

    def _recalculate_voting_power(self, address: str):
        """Recalculate voting power for an address"""
        # Reset voting power
        self.voting_power[address] = 0
        
        # Direct balance
        direct_power = self.balances.get(address, 0)
        self.voting_power[address] += direct_power
        
        # Delegated power from others
        for delegator, delegate in self.delegates.items():
            if delegate == address:
                self.voting_power[address] += self.balances.get(delegator, 0)

    def get_delegation_info(self, address: str) -> Dict[str, Any]:
        """Get delegation information for an address"""
        return {
            "delegator": address,
            "delegate_to": self.delegates.get(address),
            "delegated_from": [d for d, delg in self.delegates.items() if delg == address],
            "balance": self.balances.get(address, 0),
            "voting_power": self.voting_power.get(address, 0),
            "delegation_history": self.delegation_history.get(address, [])[-5:]
        }

# ============================================================================
# TREASURY
# ============================================================================

class Treasury:
    """DAO Treasury management"""

    def __init__(self, dao_address: str):
        self.dao_address = dao_address
        self.balances: Dict[str, float] = {}
        self.transactions: List[Dict] = []
        self.total_inflow = 0.0
        self.total_outflow = 0.0
        print(f" 💰 Treasury created for DAO: {dao_address[:16]}...")

    def deposit(self, token: str, amount: float, from_addr: str, note: str = "") -> bool:
        """Deposit funds into treasury"""
        if amount <= 0:
            return False
        
        self.balances[token] = self.balances.get(token, 0) + amount
        self.total_inflow += amount
        
        self.transactions.append({
            "type": "deposit",
            "token": token,
            "amount": amount,
            "from": from_addr,
            "timestamp": time.time(),
            "note": note
        })
        
        print(f" 💰 Treasury deposit: {amount} {token} from {from_addr[:16]}...")
        return True

    def withdraw(self, token: str, amount: float, to_addr: str, note: str = "") -> bool:
        """Withdraw funds from treasury"""
        if amount <= 0:
            return False
        if self.balances.get(token, 0) < amount:
            return False
        
        self.balances[token] -= amount
        self.total_outflow += amount
        
        self.transactions.append({
            "type": "withdraw",
            "token": token,
            "amount": amount,
            "to": to_addr,
            "timestamp": time.time(),
            "note": note
        })
        
        print(f" 💸 Treasury withdrawal: {amount} {token} to {to_addr[:16]}...")
        return True

    def get_balance(self, token: str) -> float:
        """Get treasury balance for a token"""
        return self.balances.get(token, 0)

    def get_total_value(self) -> float:
        """Get total treasury value (simplified)"""
        return sum(self.balances.values())

    def get_transactions(self, limit: int = 20) -> List[Dict]:
        """Get recent transactions"""
        return self.transactions[-limit:]

    def get_summary(self) -> Dict[str, Any]:
        """Get treasury summary"""
        return {
            "total_value": self.get_total_value(),
            "total_inflow": self.total_inflow,
            "total_outflow": self.total_outflow,
            "balance": self.balances,
            "transaction_count": len(self.transactions)
        }

# ============================================================================
# DAO
# ============================================================================

class DAO:
    """Complete DAO implementation"""

    def __init__(self, name: str, gov_token: GovToken, creator: str, 
                 voting_period_days: int = 3, quorum: float = 0.04):
        self.name = name
        self.gov_token = gov_token
        self.creator = creator
        self.address = f"0x{hashlib.md5(f'{name}{time.time()}'.encode()).hexdigest()[:16]}"
        self.proposals: Dict[int, Proposal] = {}
        self.next_proposal_id = 1
        self.treasury = Treasury(self.address)
        self.members: Set[str] = set()
        self.voting_records: Dict[int, Dict[str, bool]] = {}
        self.executed_proposals: List[int] = []
        self.cancelled_proposals: List[int] = []
        self.voting_period_days = voting_period_days
        self.quorum = quorum
        self.created_at = time.time()
        
        # Initialize with creator as member
        self.members.add(creator)
        
        print(f" 🏛️  DAO '{name}' created by {creator[:16]}...")
        print(f"    Governance Token: {gov_token.symbol}")
        print(f"    Voting Period: {voting_period_days} days")
        print(f"    Quorum: {quorum*100}%")
        print(f"    Address: {self.address}")

    def join_dao(self, address: str, token_amount: float = 0) -> bool:
        """Join the DAO"""
        if address in self.members:
            print(f" {address[:16]}... is already a member")
            return False
        
        # Requires minimum token balance
        if token_amount > 0:
            if self.gov_token.balance_of(address) < token_amount:
                print(f" ❌ Insufficient tokens for membership")
                return False
        
        self.members.add(address)
        print(f" ✅ {address[:16]}... joined DAO")
        return True

    def leave_dao(self, address: str) -> bool:
        """Leave the DAO"""
        if address not in self.members:
            print(f" {address[:16]}... is not a member")
            return False
        
        # Cannot leave if created proposals
        for proposal in self.proposals.values():
            if proposal.proposer == address and not proposal.executed:
                print(f" ❌ Cannot leave with pending proposals")
                return False
        
        self.members.remove(address)
        print(f" {address[:16]}... left DAO")
        return True

    def create_proposal(self, title: str, description: str, proposer: str,
                       proposal_type: ProposalType = ProposalType.GENERAL,
                       execution_data: Dict[str, Any] = None) -> Optional[Proposal]:
        """Create a new proposal"""
        if proposer not in self.members:
            print(f" ❌ {proposer[:16]}... is not a member")
            return None

        # Minimum voting power to propose
        if self.gov_token.get_voting_power(proposer) < 10:
            print(f" ❌ Insufficient voting power for proposal")
            return None

        proposal = Proposal(
            id=self.next_proposal_id,
            title=title,
            description=description,
            proposer=proposer,
            proposal_type=proposal_type,
            created_at=time.time(),
            end_time=time.time() + self.voting_period_days * 24 * 3600,
            quorum=self.quorum
        )

        if execution_data:
            proposal.execution_data = execution_data

        self.proposals[proposal.id] = proposal
        self.next_proposal_id += 1
        self.voting_records[proposal.id] = {}

        print(f" 📝 Proposal #{proposal.id} created: {title}")
        print(f"    Type: {proposal_type.value}")
        print(f"    Ends: {datetime.fromtimestamp(proposal.end_time).strftime('%Y-%m-%d %H:%M')}")
        return proposal

    def vote(self, proposal_id: int, voter: str, choice: VoteChoice) -> bool:
        """Vote on a proposal"""
        if proposal_id not in self.proposals:
            print(f" ❌ Proposal #{proposal_id} not found")
            return False

        proposal = self.proposals[proposal_id]

        if proposal.get_status() != ProposalStatus.ACTIVE:
            print(f" ❌ Proposal #{proposal_id} is not active")
            return False

        if voter not in self.members:
            print(f" ❌ {voter[:16]}... is not a member")
            return False

        if voter in self.voting_records[proposal_id]:
            print(f" ❌ {voter[:16]}... already voted")
            return False

        # Get voting power
        voting_power = self.gov_token.get_voting_power(voter)
        if voting_power == 0:
            print(f" ❌ No voting power")
            return False

        # Record vote
        self.voting_records[proposal_id][voter] = True
        proposal.add_vote(voter, choice, voting_power)

        print(f" 🗳️  {voter[:16]}... voted '{choice.value}' on proposal #{proposal_id} (Power: {voting_power})")
        return True

    def cancel_proposal(self, proposal_id: int, caller: str) -> bool:
        """Cancel a proposal"""
        if proposal_id not in self.proposals:
            print(f" ❌ Proposal #{proposal_id} not found")
            return False

        proposal = self.proposals[proposal_id]
        
        if proposal.get_status() != ProposalStatus.ACTIVE:
            print(f" ❌ Proposal #{proposal_id} cannot be cancelled")
            return False

        if proposal.proposer != caller:
            print(f" ❌ Only proposer can cancel")
            return False

        proposal.cancelled = True
        self.cancelled_proposals.append(proposal_id)
        print(f" 🚫 Proposal #{proposal_id} cancelled")
        return True

    def execute_proposal(self, proposal_id: int) -> bool:
        """Execute a passed proposal"""
        if proposal_id not in self.proposals:
            print(f" ❌ Proposal #{proposal_id} not found")
            return False

        proposal = self.proposals[proposal_id]

        if proposal.executed:
            print(f" ❌ Proposal #{proposal_id} already executed")
            return False

        result = proposal.get_result()
        if result != "Passed":
            print(f" ❌ Proposal #{proposal_id} {result}")
            return False

        # Execute proposal
        proposal.executed = True
        proposal.executed_at = time.time()
        self.executed_proposals.append(proposal_id)

        # Handle treasury proposal
        if proposal.proposal_type == ProposalType.TREASURY:
            if "token" in proposal.execution_data and "amount" in proposal.execution_data:
                self.treasury.withdraw(
                    proposal.execution_data["token"],
                    proposal.execution_data["amount"],
                    proposal.execution_data.get("to", proposal.proposer),
                    proposal.title
                )

        print(f" ✅ Proposal #{proposal_id} executed: {proposal.title}")
        return True

    def get_proposal_status(self, proposal_id: int) -> Dict[str, Any]:
        """Get detailed proposal status"""
        if proposal_id not in self.proposals:
            return {"error": "Proposal not found"}

        proposal = self.proposals[proposal_id]
        votes = proposal.get_vote_summary()
        
        return {
            "id": proposal.id,
            "title": proposal.title,
            "description": proposal.description,
            "type": proposal.proposal_type.value,
            "status": proposal.get_status().value,
            "result": proposal.get_result(),
            "votes": votes,
            "proposer": proposal.proposer[:16] + "...",
            "created": datetime.fromtimestamp(proposal.created_at).isoformat(),
            "ends": datetime.fromtimestamp(proposal.end_time).isoformat(),
            "executed_at": datetime.fromtimestamp(proposal.executed_at).isoformat() if proposal.executed_at else None,
            "voters": len(proposal.votes)
        }

    def get_stats(self) -> Dict[str, Any]:
        """Get DAO statistics"""
        active = sum(1 for p in self.proposals.values() 
                    if p.get_status() == ProposalStatus.ACTIVE)
        ended = sum(1 for p in self.proposals.values() 
                   if p.get_status() == ProposalStatus.ENDED)
        
        total_votes = 0
        for proposal in self.proposals.values():
            total_votes += len(proposal.votes)

        return {
            "name": self.name,
            "members": len(self.members),
            "proposals_total": len(self.proposals),
            "proposals_active": active,
            "proposals_ended": ended,
            "proposals_executed": len(self.executed_proposals),
            "proposals_cancelled": len(self.cancelled_proposals),
            "total_votes": total_votes,
            "treasury_total": self.treasury.get_total_value(),
            "token_supply": self.gov_token.total_supply,
            "created": datetime.fromtimestamp(self.created_at).isoformat()
        }

# ============================================================================
# DAO DEMONSTRATION
# ============================================================================

def dao_demo():
    """Demonstrate complete DAO functionality"""

    print("=" * 60)
    print(" 🏛️  DAO DEMONSTRATION")
    print("=" * 60)

    # Create governance token
    print("\n 🪙 Creating Governance Token...")
    token = GovToken("DAO Token", "DAO", 10000)
    
    # Distribute tokens
    print("\n 📤 Distributing Tokens...")
    token.mint("Alice", 2000)
    token.mint("Bob", 1500)
    token.mint("Charlie", 1000)
    token.mint("David", 500)
    token.mint("Eve", 300)

    # Create DAO
    print("\n 🏛️  Creating DAO...")
    dao = DAO("MyDAO", token, "Alice", voting_period_days=1, quorum=0.04)

    # Members join DAO
    print("\n 👥 Members Joining DAO...")
    for member in ["Alice", "Bob", "Charlie", "David", "Eve"]:
        dao.join_dao(member)
        # Delegate voting power to themselves
        token.delegate(member, member)

    # Show voting power
    print("\n 💪 Voting Power:")
    print("-" * 40)
    for member in ["Alice", "Bob", "Charlie", "David", "Eve"]:
        power = token.get_voting_power(member)
        balance = token.balance_of(member)
        print(f"  {member}: {power:.1f} (Balance: {balance:.1f})")

    # Fund treasury
    print("\n 💰 Funding Treasury...")
    dao.treasury.deposit("ETH", 100, "Alice", "Initial funding")
    dao.treasury.deposit("USDC", 10000, "Bob", "Community grant")

    # Create proposals
    print("\n 📝 Creating Proposals...")
    
    proposal1 = dao.create_proposal(
        "Community Garden Project",
        "Allocate 50 ETH to fund the community garden project in the neighborhood.",
        "Alice",
        ProposalType.TREASURY,
        {"token": "ETH", "amount": 50, "to": "GardenProject"}
    )

    proposal2 = dao.create_proposal(
        "Website Redesign",
        "Hire a developer to redesign the DAO website with modern UI/UX.",
        "Bob",
        ProposalType.TREASURY,
        {"token": "USDC", "amount": 5000, "to": "WebDevTeam"}
    )

    proposal3 = dao.create_proposal(
        "Governance Update",
        "Reduce quorum from 4% to 2% for faster decision making.",
        "Charlie",
        ProposalType.GOVERNANCE
    )

    # Vote on proposals
    print("\n 🗳️  Voting on Proposals...")

    # Proposal 1 voting
    print("\n  Proposal #1 - Community Garden:")
    dao.vote(1, "Alice", VoteChoice.FOR)
    dao.vote(1, "Bob", VoteChoice.FOR)
    dao.vote(1, "Charlie", VoteChoice.AGAINST)
    dao.vote(1, "David", VoteChoice.ABSTAIN)
    dao.vote(1, "Eve", VoteChoice.FOR)

    # Proposal 2 voting
    print("\n  Proposal #2 - Website Redesign:")
    dao.vote(2, "Alice", VoteChoice.FOR)
    dao.vote(2, "Bob", VoteChoice.FOR)
    dao.vote(2, "Charlie", VoteChoice.FOR)
    dao.vote(2, "David", VoteChoice.AGAINST)

    # Proposal 3 voting
    print("\n  Proposal #3 - Governance Update:")
    dao.vote(3, "Alice", VoteChoice.FOR)
    dao.vote(3, "Bob", VoteChoice.AGAINST)
    dao.vote(3, "Charlie", VoteChoice.FOR)

    # Show proposal statuses
    print("\n 📋 Proposal Statuses:")
    print("-" * 40)

    for proposal_id in [1, 2, 3]:
        status = dao.get_proposal_status(proposal_id)
        print(f"\n  Proposal #{proposal_id}: {status['title']}")
        print(f"    Status: {status['status']}")
        print(f"    Result: {status['result']}")
        print(f"    Votes: For={status['votes']['for']:.1f}, Against={status['votes']['against']:.1f}, "
              f"Abstain={status['votes']['abstain']:.1f}")
        print(f"    Voters: {status['voters']}")

    # Execute passed proposals
    print("\n ✅ Executing Proposals...")

    print("\n  Executing Proposal #1...")
    dao.execute_proposal(1)

    print("\n  Executing Proposal #2...")
    dao.execute_proposal(2)

    # DAO statistics
    print("\n 📊 DAO Statistics:")
    print("-" * 40)

    stats = dao.get_stats()
    for key, value in stats.items():
        print(f"  {key}: {value}")

    # Treasury summary
    print("\n 💰 Treasury Summary:")
    print("-" * 40)

    treasury_summary = dao.treasury.get_summary()
    print(f"  Total Value: {treasury_summary['total_value']:.2f}")
    print(f"  Total Inflow: {treasury_summary['total_inflow']:.2f}")
    print(f"  Total Outflow: {treasury_summary['total_outflow']:.2f}")
    print(f"  Balances: {treasury_summary['balance']}")

    print("\n" + "=" * 60)
    print(" ✅ DAO DEMONSTRATION COMPLETE")
    print("=" * 60)

if __name__ == "__main__":
    dao_demo()

3.2 Governance Tokens

What are Governance Tokens?

Governance tokens give holders voting rights in a DAO, allowing them to participate in decision-making about the protocol’s future.

Key Functions:

FunctionDescription
VotingVote on proposals
DelegationDelegate voting power to others
Proposal CreationCreate new proposals
Treasury ControlVote on treasury allocation

Example: UNI tokens allow holders to vote on Uniswap proposals.

3.3 Treasury

What is a DAO Treasury?

The treasury is the DAO’s pool of funds managed by token holder votes, used for operations, grants, and development.

Example: The ENS DAO treasury manages millions of dollars in ETH and stablecoins.

3.4 Voting Mechanisms

Voting Methods:

MethodDescriptionExample
Token-WeightedOne token = One voteMost DAOs
QuadraticSquare root of tokensGitcoin
Vote DelegationDelegate votesCompound

4. Layer 2 & Blockchain Scaling

4.1 Blockchain Scalability

What is Blockchain Scalability?

Scalability refers to a blockchain’s ability to handle increasing transaction volume while maintaining speed and low cost.

The Scalability Challenge:

BlockchainTPSComparison
Bitcoin~7Very limited
Ethereum~15Limited
Visa~24,000Industry standard

Layer 2 solutions aim to bridge this gap by processing transactions off-chain.

4.2 Rollups

What are Rollups?

Rollups are Layer 2 solutions that process transactions off-chain and batch them into a single transaction on the main chain, dramatically increasing throughput.

Types of Rollups:

TypeDescriptionExample
Optimistic RollupsAssume transactions are valid, with fraud proofsArbitrum, Optimism
ZK RollupsUse zero-knowledge proofs for validityzkSync, Starknet

How Rollups Work:

  1. Batch Transactions: Collect many transactions off-chain
  2. Process Off-Chain: Execute transactions off-chain
  3. Submit Batch: Submit a single batch to main chain
  4. Verify: Main chain verifies the batch

Example: Arbitrum processes thousands of transactions per second while inheriting Ethereum’s security.

4.3 Optimistic Rollups

Optimistic Rollups assume transactions are valid by default and only verify them if someone submits a fraud proof or dispute. They provide a period for challenges (fraud proofs).

Key Features:

  • Fraud Proofs: Anyone can challenge a transaction
  • Challenger Period: 7-day period for challenges
  • Security: Inherits main chain security

Example: Arbitrum and Optimism are the leading Optimistic Rollups.

4.4 ZK Rollups

ZK Rollups use zero-knowledge proofs to prove the validity of all transactions.

Key Features:

  • Immediate Finality: No challenge period
  • Privacy: Transactions can be private
  • Scalability: Higher throughput than optimistic

Example: zkSync and Starknet are leading ZK Rollups.

4.5 Polygon

Polygon is a Layer 2 scaling solution for Ethereum that offers multiple scaling technologies.

Polygon Solutions:

SolutionDescription
PoS ChainSidechain with Ethereum compatibility
zkEVMZK rollup with full EVM compatibility
MidenSTARK-based rollup

4.6 Arbitrum

Arbitrum is an Optimistic Rollup developed by Offchain Labs.

Key Features:

  • EVM Compatible: Supports existing Ethereum contracts
  • Low Fees: Significant fee reduction
  • Ecosystem: Growing ecosystem of dApps

4.7 Optimism

Optimism is an Optimistic Rollup with a focus on simplicity and developer experience.

Key Features:

  • Full EVM Equivalence: Works exactly like Ethereum
  • Retroactive Public Goods Funding: Funding for public goods
  • Simple: Easy to deploy

4.8 Base

Base is a Layer 2 solution built by Coinbase, optimized for on-chain applications.

Key Features:

  • Coinbase Backed: Trusted by Coinbase
  • EVM Compatible: Works with existing tools
  • Low Fees: Leverages L2 technology

4.9 Starknet

Starknet is a ZK Rollup using STARK proofs.

Key Features:

  • Cairo: Native programming language
  • High Performance: Thousands of TPS
  • Privacy: Optional privacy features

4.10 zkSync

zkSync is a ZK Rollup with EVM compatibility.

Key Features:

  • zkEVM: EVM-compatible zero-knowledge rollup
  • Low Fees: Very low transaction costs
  • Fast: Near-instant finality

4.11 Celestia

Celestia is a modular blockchain network that provides data availability for other blockchains and rollups.

Key Concepts:

  • Modular: Separates consensus and execution
  • Data Availability: Provides data availability sampling
  • Rollup Support: Enables rollups to use Celestia for data

4.12 Data Availability

Data Availability ensures that transaction data is available for verification.

Importance:

  • Validation: Nodes need data to validate transactions
  • Security: Prevents data withholding attacks
  • Scalability: Enables light clients

4.13 Danksharding

Danksharding is Ethereum’s sharding proposal.

Key Features:

  • Data Availability: Focuses on data availability
  • Simplified: Simpler than previous sharding proposals
  • Future: Enables full sharding in the future

4.14 Proto-Danksharding (EIP-4844)

Proto-Danksharding (EIP-4844) is a transitional sharding proposal.

Key Features:

  • Blob Transactions: New transaction type for blobs
  • Gas Efficiency: Reduces rollup costs
  • Future: Paves the way for full sharding

5. Cross-Chain & Oracle Networks

5.1 Blockchain Bridges

Blockchain Bridges connect different blockchains, enabling asset and data transfer between them.

Bridge Types:

TypeDescriptionExample
CentralizedTrusted bridgeBinance Bridge
DecentralizedTrustless bridgeHop Protocol
Light ClientUses light clientsCosmos IBC

5.2 Wrapped Tokens

Wrapped Tokens are tokens that represent assets from other blockchains.

Example: Wrapped Bitcoin (WBTC) is an ERC-20 token representing Bitcoin on Ethereum.

5.3 Cross-Chain Messaging

Cross-Chain Messaging enables communication between different blockchains.

Example: LayerZero enables cross-chain messaging between 30+ chains.

5.4 Cosmos

Cosmos is an ecosystem of interconnected blockchains.

Key Features:

  • IBC: Inter-Blockchain Communication
  • Tendermint: Consensus engine
  • Cosmos SDK: Framework for building blockchains

5.5 Polkadot

Polkadot is a sharded blockchain network.

Key Features:

  • Relay Chain: The main chain
  • Parachains: Connected blockchains
  • XCMP: Cross-chain messaging

5.6 IBC (Inter-Blockchain Communication)

IBC is a protocol that enables secure communication and data transfer between different blockchains.

Key Features:

  • Trustless: No trusted third party
  • Light Client: Uses light clients for verification
  • Flexible: Works with various blockchains

Chainlink is a decentralized oracle network.

Key Features:

  • Oracles: Provide external data to blockchains
  • Decentralized: Multiple nodes ensure reliability
  • Secure: Cryptographic guarantees

5.8 VRF (Verifiable Random Function)

VRF provides verifiable randomness for blockchain applications.

Example: Chainlink VRF generates random numbers for NFT minting and gaming.

6. Blockchain Security & Auditing

6.1 Smart Contract Security

Smart Contract Security involves preventing vulnerabilities and attacks in blockchain code through audits, best practices, and formal verification.

Key Principles:

PrincipleDescription
Checks-Effects-InteractionsUpdate state before external calls
Fail EarlyValidate inputs early
Defensive ProgrammingAssume worst-case
Minimal ComplexityKeep code simple

Example: The DAO hack in 2016 stole $60M due to a reentrancy vulnerability, leading to the Ethereum hard fork.

6.2 Common Vulnerabilities

Common Smart Contract Vulnerabilities:

VulnerabilityDescriptionPrevention
ReentrancyCalling external contract before updating stateChecks-Effects-Interactions pattern
Integer OverflowNumbers exceeding maximum valueSafeMath libraries
Access ControlUnauthorized access to functionsOnlyOwner modifier
Front RunningTransactions being exploited by minersCommit-reveal schemes
Sandwich AttackTrading around a user’s transactionSlippage protection
Oracle ManipulationManipulating price oraclesMultiple oracle sources
Flash Loan AttackUsing flash loans to exploitSecure contract design

Code Example – Security Vulnerabilities:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// ============================================================================
// LIBRARY: SafeMath
// ============================================================================

/**
 * @title SafeMath
 * @dev Safe mathematical operations (for pre-0.8 compatibility)
 */
library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction underflow");
        return a - b;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

// ============================================================================
// CONTRACT: SecureBank
// ============================================================================

/**
 * @title SecureBank
 * @dev Demonstrates security best practices and common vulnerabilities
 */
contract SecureBank {
    using SafeMath for uint256;

    // -------- STATE VARIABLES --------
    mapping(address => uint256) public balances;
    mapping(address => bool) public hasWithdrawn;
    address public owner;
    uint256 public totalDeposits;
    bool public paused;

    // -------- EVENTS --------
    event Deposit(address indexed user, uint256 amount);
    event Withdrawal(address indexed user, uint256 amount);
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);
    event Paused(address indexed account);
    event Unpaused(address indexed account);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier whenNotPaused() {
        require(!paused, "Contract paused");
        _;
    }

    modifier whenPaused() {
        require(paused, "Contract not paused");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- DEPOSIT FUNCTIONS --------
    function deposit() public payable whenNotPaused {
        require(msg.value > 0, "Amount must be > 0");
        balances[msg.sender] = balances[msg.sender].add(msg.value);
        totalDeposits = totalDeposits.add(msg.value);
        emit Deposit(msg.sender, msg.value);
    }

    // =========================================================================
    // SECURE WITHDRAW (Checks-Effects-Interactions)
    // =========================================================================

    /// @notice Secure withdrawal using CEI pattern
    function withdraw(uint256 amount) public whenNotPaused {
        // 1. CHECK: Validate conditions
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(amount > 0, "Amount must be > 0");

        // 2. EFFECTS: Update state first
        balances[msg.sender] = balances[msg.sender].sub(amount);
        totalDeposits = totalDeposits.sub(amount);
        hasWithdrawn[msg.sender] = true;

        // 3. INTERACTIONS: External calls last
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        require(success, "Transfer failed");

        emit Withdrawal(msg.sender, amount);
    }

    // =========================================================================
    // REENTRANCY DEMONSTRATION
    // =========================================================================

    /// @dev VULNERABLE: Shows reentrancy vulnerability (DO NOT USE)
    function withdrawVulnerable(uint256 amount) public {
        // WARNING: This is vulnerable to reentrancy!
        if (balances[msg.sender] >= amount) {
            // ❌ External call before state update
            (bool success, ) = msg.sender.call{value: amount}("");
            require(success, "Transfer failed");
            // ❌ State updated after external call
            balances[msg.sender] -= amount;
        }
    }

    /// @dev SECURE: Uses CEI pattern
    function withdrawSecure(uint256 amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        // ✅ State update first
        balances[msg.sender] -= amount;
        // ✅ External call after state update
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }

    // =========================================================================
    // REENTRANCY GUARD (Optional)
    // =========================================================================

    bool internal _locked;

    modifier noReentrant() {
        require(!_locked, "Reentrancy guard");
        _locked = true;
        _;
        _locked = false;
    }

    function withdrawWithGuard(uint256 amount) public whenNotPaused noReentrant {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] = balances[msg.sender].sub(amount);
        (bool success, ) = payable(msg.sender).call{value: amount}("");
        require(success, "Transfer failed");
    }

    // =========================================================================
    // OVERFLOW/UNDERFLOW PROTECTION
    // =========================================================================

    /// @notice Using SafeMath or Solidity 0.8+ built-in checks
    function safeAdd(uint256 a, uint256 b) public pure returns (uint256) {
        return a.add(b); // Using SafeMath
    }

    function safeSub(uint256 a, uint256 b) public pure returns (uint256) {
        return a.sub(b); // Using SafeMath
    }

    // =========================================================================
    // ACCESS CONTROL
    // =========================================================================

    /// @notice Transfer ownership
    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    // =========================================================================
    // PAUSE FUNCTIONALITY
    // =========================================================================

    function pause() public onlyOwner {
        require(!paused, "Already paused");
        paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyOwner whenPaused {
        paused = false;
        emit Unpaused(msg.sender);
    }

    // =========================================================================
    // EMERGENCY FUNCTIONS
    // =========================================================================

    function emergencyWithdraw() public onlyOwner whenPaused {
        uint256 balance = address(this).balance;
        payable(owner).transfer(balance);
    }

    // =========================================================================
    // VIEW FUNCTIONS
    // =========================================================================

    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function getTotalDeposits() public view returns (uint256) {
        return totalDeposits;
    }

    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function getOwner() public view returns (address) {
        return owner;
    }

    // -------- FALLBACK --------
    receive() external payable {
        // Handle ETH sent directly
        balances[msg.sender] = balances[msg.sender].add(msg.value);
        totalDeposits = totalDeposits.add(msg.value);
        emit Deposit(msg.sender, msg.value);
    }
}

// ============================================================================
// CONTRACT: ReentrancyAttacker
// ============================================================================

/**
 * @title ReentrancyAttacker
 * @dev Demonstrates a reentrancy attack (for educational purposes)
 */
contract ReentrancyAttacker {
    SecureBank public bank;
    address public owner;
    uint256 public attackCount;

    constructor(address _bankAddress) {
        bank = SecureBank(_bankAddress);
        owner = msg.sender;
    }

    function attack() public payable {
        require(msg.value > 0, "Must send ETH");
        bank.deposit{value: msg.value}();
        bank.withdrawVulnerable(msg.value);
    }

    receive() external payable {
        if (address(bank).balance >= 1 ether && attackCount < 10) {
            attackCount++;
            bank.withdrawVulnerable(msg.value);
        }
    }

    function getBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function withdraw() public {
        require(msg.sender == owner, "Not owner");
        payable(owner).transfer(address(this).balance);
    }
}

// ============================================================================
// CONTRACT: SecureVault
// ============================================================================

/**
 * @title SecureVault
 * @dev Advanced secure vault with multiple security features
 */
contract SecureVault {
    using SafeMath for uint256;

    // -------- STATE --------
    mapping(address => uint256) public balances;
    mapping(address => uint256) public lastWithdrawal;
    uint256 public withdrawalDelay = 1 days;
    address public owner;
    bool public paused;

    // -------- EVENTS --------
    event Deposit(address indexed user, uint256 amount);
    event Withdrawal(address indexed user, uint256 amount);
    event WithdrawalRequested(address indexed user, uint256 amount, uint256 releaseTime);

    // -------- MODIFIERS --------
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier whenNotPaused() {
        require(!paused, "Contract paused");
        _;
    }

    // -------- CONSTRUCTOR --------
    constructor() {
        owner = msg.sender;
    }

    // -------- DEPOSIT --------
    function deposit() public payable whenNotPaused {
        require(msg.value > 0, "Amount must be > 0");
        balances[msg.sender] = balances[msg.sender].add(msg.value);
        emit Deposit(msg.sender, msg.value);
    }

    // -------- WITHDRAW WITH DELAY --------
    function requestWithdrawal(uint256 amount) public whenNotPaused {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        require(amount > 0, "Amount must be > 0");

        balances[msg.sender] = balances[msg.sender].sub(amount);
        lastWithdrawal[msg.sender] = block.timestamp.add(withdrawalDelay);

        emit WithdrawalRequested(msg.sender, amount, lastWithdrawal[msg.sender]);
    }

    function executeWithdrawal() public whenNotPaused {
        require(lastWithdrawal[msg.sender] > 0, "No withdrawal requested");
        require(block.timestamp >= lastWithdrawal[msg.sender], "Withdrawal delay not met");

        uint256 amount = balances[msg.sender];
        require(amount > 0, "No balance to withdraw");

        balances[msg.sender] = 0;
        lastWithdrawal[msg.sender] = 0;

        payable(msg.sender).transfer(amount);
        emit Withdrawal(msg.sender, amount);
    }

    // -------- ADMIN --------
    function pause() public onlyOwner {
        paused = true;
    }

    function unpause() public onlyOwner {
        paused = false;
    }

    function setWithdrawalDelay(uint256 newDelay) public onlyOwner {
        withdrawalDelay = newDelay;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0), "Invalid address");
        owner = newOwner;
    }

    // -------- VIEW --------
    function getBalance(address user) public view returns (uint256) {
        return balances[user];
    }

    function getContractBalance() public view returns (uint256) {
        return address(this).balance;
    }

    function getWithdrawalTime(address user) public view returns (uint256) {
        return lastWithdrawal[user];
    }

    receive() external payable {
        deposit();
    }
}

7. Testing, Deployment & DevOps

7.1 Testing

Types of Testing:

Test TypeDescriptionTools
Unit TestingTest individual functionsHardhat, Foundry
Integration TestingTest contract interactionsHardhat, Foundry
Fuzz TestingRandom input testingEchidna, Foundry
Mainnet Fork TestingTest on a copy of mainnetHardhat fork

7.2 Deployment

Deployment Pipeline:

Write Contracts → Test Locally → Deploy to Testnet → Verify Contracts → Deploy to Mainnet

Example: Use Hardhat to deploy a contract with deployment scripts.

7.3 Infrastructure

Infrastructure Components:

ComponentPurposeExamples
RPC ProvidersConnect to blockchainInfura, Alchemy
MonitoringTrack performanceThe Graph
LoggingDebug and auditContract events

8. Advanced Blockchain Concepts

8.1 Zero-Knowledge Proofs

Zero-Knowledge Proofs (ZKPs) allow a prover to prove they know information without revealing it.

Applications:

  • Privacy in transactions
  • Identity verification
  • Layer 2 scaling (ZK Rollups)

8.2 MEV (Miner Extractable Value)

MEV is the value miners can extract by reordering, including, or censoring transactions.

MEV Examples:

TypeDescription
ArbitrageExploiting price differences
LiquidationsLiquidating under-collateralized positions
Front RunningInserting transactions before others

8.3 Account Abstraction

Account Abstraction (ERC-4337) enables smart contract wallets without protocol changes.

Features:

  • Smart contract wallets
  • Gas sponsorship
  • Social recovery
  • Multi-signature

9. Real-World Applications

9.1 Supply Chain

Blockchain for Supply Chain:

BenefitDescription
TraceabilityTrack products from origin
AuthenticityVerify product authenticity
EfficiencyReduce paperwork

Example: IBM Food Trust tracks mangoes in 2.2 seconds vs 6 days traditionally.

9.2 Digital Identity

Decentralized Identity (DID):

  • Self-sovereign identity
  • User-controlled data
  • Privacy-preserving

Example: Estonia uses blockchain for 95% of health data.

9.3 Healthcare

Healthcare Applications:

  • Medical records management
  • Drug traceability
  • Clinical trial transparency

Example: MedRec uses blockchain for patient-controlled medical records.

9.4 Gaming and GameFi

Blockchain Gaming:

  • True ownership of assets
  • Play-to-earn mechanics
  • Interoperable items

Example: Axie Infinity pioneered play-to-earn gaming.

9.5 DePIN (Decentralized Physical Infrastructure Networks)

DePIN uses blockchain to incentivize physical infrastructure deployment.

Examples:

  • Helium (wireless networks)
  • Filecoin (storage networks)
  • Render Network (GPU rendering)

9.6 Real World Assets (RWA)

Real World Assets are traditional assets tokenized on blockchain.

Examples:

  • Real estate tokenization
  • Treasury bills on-chain
  • Commodity tokenization

10. Blockchain Business & Careers

10.1 Tokenomics Design

Tokenomics is the economics of token creation and distribution.

Key Elements:

ElementDescription
Supply ModelFixed, inflationary, deflationary
DistributionHow tokens are distributed
UtilityWhat tokens are used for
GovernanceHow decisions are made

10.2 Fundraising Methods

MethodDescriptionExample
ICOInitial Coin OfferingEthereum
IEOInitial Exchange OfferingBinance Launchpad
IDOInitial DEX OfferingUniswap
AirdropsFree token distributionUNI airdrop

10.3 Career Paths

CareerDescriptionSkills
Blockchain DeveloperBuild blockchain applicationsSolidity, Web3
Smart Contract EngineerWrite and audit contractsSolidity, Security
Web3 Full-Stack DeveloperBuild dAppsReact, Web3.js
Protocol EngineerDesign blockchain protocolsRust, Go
Security EngineerAudit smart contractsSolidity, Security
Blockchain ResearcherAdvance the fieldResearch, Cryptography

PHASE 3 – COMPLETE PROJECT

Integrated DeFi, DAO & NFT Platform

"""
COMPLETE PROJECT: DeFi & DAO INTEGRATION
==========================================
A fully integrated system combining:
- DeFi protocols (lending, borrowing, swapping)
- DAO governance
- NFT integration
- Yield farming
- Real-time monitoring
"""

import hashlib
import time
import math
import random
from typing import Dict, List, Any, Optional, Set
from datetime import datetime
from dataclasses import dataclass, field
from enum import Enum

# ============================================================================
# ENUMS AND TYPES
# ============================================================================

class ProposalStatus(Enum):
    ACTIVE = "Active"
    PASSED = "Passed"
    FAILED = "Failed"
    EXECUTED = "Executed"

class NFTStatus(Enum):
    AVAILABLE = "Available"
    LISTED = "Listed"
    SOLD = "Sold"

class YieldFarmStatus(Enum):
    ACTIVE = "Active"
    ENDED = "Ended"
    PAUSED = "Paused"

# ============================================================================
# DATA CLASSES
# ============================================================================

@dataclass
class User:
    """User account with full portfolio"""
    name: str
    address: str
    balance: float = 0.0
    staked: float = 0.0
    deposits: Dict[str, float] = field(default_factory=dict)
    nfts: List[int] = field(default_factory=list)
    yield_farms: Dict[str, float] = field(default_factory=dict)
    transaction_history: List[Dict] = field(default_factory=list)
    created_at: float = field(default_factory=time.time)

@dataclass
class LendingPosition:
    """Lending position details"""
    token: str
    amount: float
    interest_earned: float = 0.0
    start_time: float = field(default_factory=time.time)

@dataclass
class BorrowPosition:
    """Borrowing position details"""
    token: str
    amount: float
    interest_owed: float = 0.0
    collateral: float = 0.0
    start_time: float = field(default_factory=time.time)

@dataclass
class YieldFarm:
    """Yield farming pool"""
    name: str
    staking_token: str
    reward_token: str
    total_staked: float = 0.0
    reward_rate: float = 0.0
    status: YieldFarmStatus = YieldFarmStatus.ACTIVE
    users: Dict[str, float] = field(default_factory=dict)
    rewards: Dict[str, float] = field(default_factory=dict)
    created_at: float = field(default_factory=time.time)

# ============================================================================
# PLATFORM IMPLEMENTATION
# ============================================================================

class IntegratedPlatform:
    """Complete integrated DeFi + DAO + NFT platform"""

    def __init__(self, name: str = "Web3Platform"):
        self.name = name
        self.users: Dict[str, User] = {}
        self.lending_pool: Dict[str, Dict] = {}
        self.borrow_pool: Dict[str, Dict] = {}
        self.positions: Dict[str, Dict] = {}
        self.lending_positions: Dict[str, Dict[str, LendingPosition]] = {}
        self.borrow_positions: Dict[str, Dict[str, BorrowPosition]] = {}
        self.dao_proposals: List[Dict] = []
        self.nft_collection: Dict[int, Dict] = {}
        self.yield_farms: Dict[str, YieldFarm] = {}
        self.next_nft_id = 1
        self.total_value_locked = 0.0
        self.transactions: List[Dict] = []
        self.treasury_balance = 0.0
        self.dao_members: Set[str] = set()
        self.governance_token = "GOV"
        self.token_prices: Dict[str, float] = {
            "ETH": 2000.0,
            "DAI": 1.0,
            "USDC": 1.0,
            "GOV": 10.0,
            "WBTC": 30000.0
        }

        print(f" 🏛️  Platform '{name}' initialized")
        print(f"    Governance Token: {self.governance_token}")
        print(f"    Initial Prices: {self.token_prices}")

    # =========================================================================
    # USER MANAGEMENT
    # =========================================================================

    def register_user(self, name: str) -> User:
        """Register a new user"""
        address = f"0x{hashlib.md5(f'{name}{time.time()}'.encode()).hexdigest()[:16]}"
        user = User(name=name, address=address)
        self.users[address] = user
        self.dao_members.add(address)
        print(f" 👤 User registered: {name} ({address[:16]}...)")
        return user

    def get_user(self, address: str) -> Optional[User]:
        """Get user by address"""
        return self.users.get(address)

    def get_user_by_name(self, name: str) -> Optional[User]:
        """Get user by name"""
        for user in self.users.values():
            if user.name == name:
                return user
        return None

    # =========================================================================
    # LENDING AND BORROWING
    # =========================================================================

    def deposit_lending(self, user_addr: str, token: str, amount: float) -> bool:
        """Deposit into lending pool"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if user.balance < amount:
            print(f" ❌ Insufficient balance")
            return False

        # Transfer to lending pool
        user.balance -= amount

        # Initialize lending pool if needed
        if token not in self.lending_pool:
            self.lending_pool[token] = {"total": 0, "users": {}}
        self.lending_pool[token]["total"] += amount
        self.lending_pool[token]["users"][user_addr] = self.lending_pool[token]["users"].get(user_addr, 0) + amount

        # Track position
        if user_addr not in self.lending_positions:
            self.lending_positions[user_addr] = {}
        self.lending_positions[user_addr][token] = LendingPosition(token, amount)

        # Update TVL
        self.total_value_locked += amount * self.token_prices.get(token, 1)

        self._add_transaction(user_addr, "DEPOSIT_LENDING", {
            "token": token,
            "amount": amount,
            "pool": "lending"
        })

        print(f" ✅ Deposited {amount:.2f} {token} into lending pool")
        return True

    def withdraw_lending(self, user_addr: str, token: str, amount: float) -> bool:
        """Withdraw from lending pool"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if token not in self.lending_pool:
            print(f" ❌ Lending pool not found")
            return False

        if self.lending_pool[token]["users"].get(user_addr, 0) < amount:
            print(f" ❌ Insufficient deposit")
            return False

        # Calculate interest (simplified)
        interest = amount * 0.02  # 2% interest

        # Update lending pool
        self.lending_pool[token]["total"] -= amount
        self.lending_pool[token]["users"][user_addr] -= amount

        # Add interest to user
        user.balance += amount + interest
        self.total_value_locked -= amount * self.token_prices.get(token, 1)

        # Update position
        if user_addr in self.lending_positions and token in self.lending_positions[user_addr]:
            self.lending_positions[user_addr][token].amount -= amount
            self.lending_positions[user_addr][token].interest_earned += interest
            if self.lending_positions[user_addr][token].amount <= 0:
                del self.lending_positions[user_addr][token]

        self._add_transaction(user_addr, "WITHDRAW_LENDING", {
            "token": token,
            "amount": amount,
            "interest": interest,
            "pool": "lending"
        })

        print(f" ✅ Withdrew {amount:.2f} {token} + {interest:.2f} interest")
        return True

    def borrow_lending(self, user_addr: str, token: str, amount: float) -> bool:
        """Borrow from lending pool"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        # Check collateral (75% LTV)
        total_deposits = sum(self.lending_pool.get(t, {}).get("users", {}).get(user_addr, 0) 
                            for t in self.lending_pool)
        max_borrow = total_deposits * 0.75

        if amount > max_borrow:
            print(f" ❌ Insufficient collateral. Max borrow: {max_borrow:.2f}")
            return False

        # Check pool liquidity
        if self.lending_pool.get(token, {}).get("total", 0) < amount:
            print(f" ❌ Insufficient liquidity in pool")
            return False

        # Execute borrow
        self.lending_pool[token]["total"] -= amount
        user.balance += amount
        self.total_value_locked += amount * self.token_prices.get(token, 1)

        # Track borrow position
        if user_addr not in self.borrow_positions:
            self.borrow_positions[user_addr] = {}
        self.borrow_positions[user_addr][token] = BorrowPosition(
            token, amount, 0, total_deposits * 0.75
        )

        self._add_transaction(user_addr, "BORROW", {
            "token": token,
            "amount": amount,
            "collateral": total_deposits * 0.75
        })

        print(f" ✅ Borrowed {amount:.2f} {token}")
        return True

    def repay_borrow(self, user_addr: str, token: str, amount: float) -> bool:
        """Repay borrowed amount"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if user_addr not in self.borrow_positions or token not in self.borrow_positions[user_addr]:
            print(f" ❌ No borrow position found")
            return False

        if user.balance < amount:
            print(f" ❌ Insufficient balance")
            return False

        borrow_pos = self.borrow_positions[user_addr][token]
        if amount > borrow_pos.amount:
            print(f" ❌ Amount exceeds borrow")
            return False

        # Calculate interest (simplified)
        interest = amount * 0.05  # 5% interest

        # Repay
        user.balance -= amount + interest
        borrow_pos.amount -= amount
        borrow_pos.interest_owed += interest

        # Update lending pool
        if token not in self.lending_pool:
            self.lending_pool[token] = {"total": 0, "users": {}}
        self.lending_pool[token]["total"] += amount

        if borrow_pos.amount <= 0:
            del self.borrow_positions[user_addr][token]

        self._add_transaction(user_addr, "REPAY", {
            "token": token,
            "amount": amount,
            "interest": interest
        })

        print(f" ✅ Repaid {amount:.2f} {token} + {interest:.2f} interest")
        return True

    # =========================================================================
    # SWAPPING
    # =========================================================================

    def swap_tokens(self, user_addr: str, token_in: str, token_out: str, amount: float) -> bool:
        """Swap tokens with simulated price impact"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if user.balance < amount:
            print(f" ❌ Insufficient balance")
            return False

        # Simulate price impact
        price_impact = amount / 1000
        if token_in in self.token_prices and token_out in self.token_prices:
            rate = self.token_prices[token_in] / self.token_prices[token_out]
            amount_out = amount * rate * (1 - price_impact)
        else:
            amount_out = amount * 0.95  # 5% slippage

        # Execute swap
        user.balance -= amount
        user.balance += amount_out

        self._add_transaction(user_addr, "SWAP", {
            "token_in": token_in,
            "token_out": token_out,
            "amount_in": amount,
            "amount_out": amount_out,
            "price_impact": price_impact * 100
        })

        print(f" ✅ Swapped {amount:.2f} {token_in} → {amount_out:.2f} {token_out}")
        return True

    # =========================================================================
    # NFT MANAGEMENT
    # =========================================================================

    def mint_nft(self, user_addr: str, name: str, description: str, 
                 attributes: Dict[str, Any] = None) -> int:
        """Mint an NFT"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return 0

        token_id = self.next_nft_id
        self.next_nft_id += 1

        self.nft_collection[token_id] = {
            "id": token_id,
            "name": name,
            "description": description,
            "owner": user_addr,
            "created": time.time(),
            "attributes": attributes or {},
            "status": NFTStatus.AVAILABLE.value,
            "transfers": []
        }

        user.nfts.append(token_id)

        self._add_transaction(user_addr, "MINT_NFT", {
            "token_id": token_id,
            "name": name
        })

        print(f" ✅ NFT #{token_id} minted: {name}")
        return token_id

    def transfer_nft(self, token_id: int, from_addr: str, to_addr: str) -> bool:
        """Transfer NFT to another user"""
        if token_id not in self.nft_collection:
            print(f" ❌ NFT not found")
            return False

        nft = self.nft_collection[token_id]
        if nft["owner"] != from_addr:
            print(f" ❌ Not the owner")
            return False

        if to_addr not in self.users:
            print(f" ❌ Recipient not found")
            return False

        # Remove from sender
        sender_user = self.get_user(from_addr)
        if sender_user:
            sender_user.nfts.remove(token_id)

        # Add to recipient
        recipient_user = self.get_user(to_addr)
        if recipient_user:
            recipient_user.nfts.append(token_id)

        # Update NFT
        nft["owner"] = to_addr
        nft["transfers"].append({
            "from": from_addr,
            "to": to_addr,
            "timestamp": time.time()
        })

        self._add_transaction(to_addr, "RECEIVE_NFT", {
            "token_id": token_id,
            "from": from_addr[:16] + "..."
        })

        print(f" ✅ NFT #{token_id} transferred to {to_addr[:16]}...")
        return True

    # =========================================================================
    # YIELD FARMING
    # =========================================================================

    def create_yield_farm(self, name: str, staking_token: str, 
                          reward_token: str, reward_rate: float) -> YieldFarm:
        """Create a yield farming pool"""
        farm = YieldFarm(name, staking_token, reward_token, reward_rate=reward_rate)
        self.yield_farms[name] = farm
        print(f" 🌾 Yield farm created: {name} ({staking_token} → {reward_token})")
        return farm

    def stake_tokens(self, user_addr: str, farm_name: str, amount: float) -> bool:
        """Stake tokens in yield farm"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if farm_name not in self.yield_farms:
            print(f" ❌ Farm not found")
            return False

        farm = self.yield_farms[farm_name]

        if user.balance < amount:
            print(f" ❌ Insufficient balance")
            return False

        # Transfer to farm
        user.balance -= amount
        farm.users[user_addr] = farm.users.get(user_addr, 0) + amount
        farm.total_staked += amount

        self._add_transaction(user_addr, "STAKE", {
            "farm": farm_name,
            "amount": amount,
            "token": farm.staking_token
        })

        print(f" ✅ Staked {amount:.2f} {farm.staking_token} in {farm_name}")
        return True

    def unstake_tokens(self, user_addr: str, farm_name: str, amount: float) -> bool:
        """Unstake tokens from yield farm"""
        user = self.get_user(user_addr)
        if not user:
            print(f" ❌ User not found")
            return False

        if farm_name not in self.yield_farms:
            print(f" ❌ Farm not found")
            return False

        farm = self.yield_farms[farm_name]

        if farm.users.get(user_addr, 0) < amount:
            print(f" ❌ Insufficient staked amount")
            return False

        # Calculate rewards
        reward = amount * farm.reward_rate

        # Return tokens
        farm.users[user_addr] -= amount
        farm.total_staked -= amount
        user.balance += amount + reward

        self._add_transaction(user_addr, "UNSTAKE", {
            "farm": farm_name,
            "amount": amount,
            "reward": reward
        })

        print(f" ✅ Unstaked {amount:.2f} + {reward:.2f} rewards from {farm_name}")
        return True

    # =========================================================================
    # DAO GOVERNANCE
    # =========================================================================

    def create_dao_proposal(self, proposer: str, title: str, 
                            description: str, execution_data: Dict = None) -> int:
        """Create a DAO proposal"""
        if proposer not in self.dao_members:
            print(f" ❌ Proposer not a DAO member")
            return 0

        proposal_id = len(self.dao_proposals) + 1
        self.dao_proposals.append({
            "id": proposal_id,
            "title": title,
            "description": description,
            "proposer": proposer,
            "created": time.time(),
            "voting_ends": time.time() + 3 * 24 * 3600,
            "votes_for": 0.0,
            "votes_against": 0.0,
            "voted": {},
            "executed": False,
            "execution_data": execution_data or {}
        })

        print(f" 📝 DAO Proposal #{proposal_id} created: {title}")
        return proposal_id

    def vote_proposal(self, proposal_id: int, user_addr: str, choice: str) -> bool:
        """Vote on a DAO proposal"""
        if user_addr not in self.dao_members:
            print(f" ❌ User not a DAO member")
            return False

        if proposal_id > len(self.dao_proposals):
            print(f" ❌ Proposal not found")
            return False

        proposal = self.dao_proposals[proposal_id - 1]

        if user_addr in proposal["voted"]:
            print(f" ❌ Already voted")
            return False

        if time.time() > proposal["voting_ends"]:
            print(f" ❌ Voting has ended")
            return False

        # Voting power based on balance and staked tokens
        user = self.get_user(user_addr)
        voting_power = user.balance + user.staked + sum(user.deposits.values())

        if voting_power <= 0:
            print(f" ❌ No voting power")
            return False

        proposal["voted"][user_addr] = choice

        if choice.lower() == "for":
            proposal["votes_for"] += voting_power
        elif choice.lower() == "against":
            proposal["votes_against"] += voting_power
        else:
            print(f" ❌ Invalid choice")
            return False

        print(f" 🗳️  Voted '{choice}' on proposal #{proposal_id} (Power: {voting_power:.2f})")
        return True

    def execute_proposal(self, proposal_id: int) -> bool:
        """Execute a passed DAO proposal"""
        if proposal_id > len(self.dao_proposals):
            print(f" ❌ Proposal not found")
            return False

        proposal = self.dao_proposals[proposal_id - 1]

        if proposal["executed"]:
            print(f" ❌ Already executed")
            return False

        if time.time() <= proposal["voting_ends"]:
            print(f" ❌ Voting still active")
            return False

        total_votes = proposal["votes_for"] + proposal["votes_against"]
        quorum = 50.0  # Minimum voting power for quorum

        if total_votes < quorum:
            print(f" ❌ Quorum not met (Need {quorum}, have {total_votes:.2f})")
            return False

        if proposal["votes_for"] > proposal["votes_against"]:
            proposal["executed"] = True

            # Execute treasury proposal
            exec_data = proposal.get("execution_data", {})
            if exec_data.get("type") == "treasury_withdrawal":
                token = exec_data.get("token", "ETH")
                amount = exec_data.get("amount", 0)
                to = exec_data.get("to", proposal["proposer"])
                if self.treasury_balance >= amount:
                    self.treasury_balance -= amount
                    user = self.get_user(to)
                    if user:
                        user.balance += amount

            print(f" ✅ Proposal #{proposal_id} executed: {proposal['title']}")
            return True
        else:
            print(f" ❌ Proposal #{proposal_id} failed")
            return False

    # =========================================================================
    # TREASURY
    # =========================================================================

    def deposit_treasury(self, amount: float) -> None:
        """Deposit funds into treasury"""
        self.treasury_balance += amount
        print(f" 💰 Treasury deposit: {amount:.2f} ETH")

    def withdraw_treasury(self, amount: float, to: str) -> bool:
        """Withdraw funds from treasury (requires DAO proposal)"""
        if self.treasury_balance < amount:
            print(f" ❌ Insufficient treasury balance")
            return False

        self.treasury_balance -= amount
        user = self.get_user(to)
        if user:
            user.balance += amount

        print(f" 💸 Treasury withdrawal: {amount:.2f} ETH to {to[:16]}...")
        return True

    # =========================================================================
    # MONITORING AND STATS
    # =========================================================================

    def _add_transaction(self, user_addr: str, tx_type: str, data: Dict) -> None:
        """Add transaction to history"""
        self.transactions.append({
            "user": user_addr[:16] + "...",
            "type": tx_type,
            "data": data,
            "timestamp": time.time()
        })

    def get_user_portfolio(self, user_addr: str) -> Dict[str, Any]:
        """Get user's complete portfolio"""
        user = self.get_user(user_addr)
        if not user:
            return {}

        total_value = user.balance + user.staked + sum(user.deposits.values())

        return {
            "name": user.name,
            "address": user.address[:16] + "...",
            "balance": user.balance,
            "staked": user.staked,
            "deposits": user.deposits,
            "nfts": user.nfts,
            "total_value": total_value,
            "lending_positions": self.lending_positions.get(user_addr, {}),
            "borrow_positions": self.borrow_positions.get(user_addr, {}),
            "transactions": len(user.transaction_history)
        }

    def get_platform_stats(self) -> Dict[str, Any]:
        """Get platform statistics"""
        total_nfts = len(self.nft_collection)
        total_users = len(self.users)
        total_staked = sum(farm.total_staked for farm in self.yield_farms.values())
        total_deposits = sum(pool["total"] for pool in self.lending_pool.values())

        return {
            "name": self.name,
            "users": total_users,
            "nfts": total_nfts,
            "dao_proposals": len(self.dao_proposals),
            "dao_members": len(self.dao_members),
            "total_value_locked": self.total_value_locked,
            "total_staked": total_staked,
            "total_deposits": total_deposits,
            "transactions": len(self.transactions),
            "treasury_balance": self.treasury_balance,
            "yield_farms": len(self.yield_farms)
        }

    def get_token_price(self, token: str) -> float:
        """Get current token price"""
        return self.token_prices.get(token, 0.0)

    def update_token_price(self, token: str, price: float) -> None:
        """Update token price"""
        self.token_prices[token] = price

# ============================================================================
# DEMONSTRATION
# ============================================================================

def platform_demo():
    """Demonstrate integrated platform"""

    print("=" * 60)
    print(" 🚀 INTEGRATED DeFi + DAO + NFT PLATFORM")
    print("=" * 60)

    # Initialize platform
    platform = IntegratedPlatform("MyWeb3Platform")

    # Register users
    print("\n 👤 Registering Users...")
    alice = platform.register_user("Alice")
    bob = platform.register_user("Bob")
    charlie = platform.register_user("Charlie")
    diana = platform.register_user("Diana")

    # Fund users
    print("\n 💰 Funding Users...")
    alice.balance = 1000
    bob.balance = 500
    charlie.balance = 100
    diana.balance = 200

    print("✅ Initial balances set!")

    # ===== DEFI OPERATIONS =====
    print("\n 📊 DeFi Operations:")
    print("-" * 40)

    print("\n  Alice deposits 500 ETH into lending pool")
    platform.deposit_lending(alice.address, "ETH", 500)

    print("\n  Bob deposits 300 DAI into lending pool")
    platform.deposit_lending(bob.address, "DAI", 300)

    print("\n  Bob borrows 200 DAI from lending pool")
    platform.borrow_lending(bob.address, "DAI", 200)

    print("\n  Charlie swaps 50 ETH for USDC")
    platform.swap_tokens(charlie.address, "ETH", "USDC", 50)

    # ===== YIELD FARMING =====
    print("\n 🌾 Yield Farming:")
    print("-" * 40)

    farm = platform.create_yield_farm("ETH-GOV Farm", "ETH", "GOV", 0.15)
    print("\n  Alice stakes 200 ETH in yield farm")
    platform.stake_tokens(alice.address, "ETH-GOV Farm", 200)

    # ===== NFT OPERATIONS =====
    print("\n 🎨 NFT Operations:")
    print("-" * 40)

    print("\n  Alice mints an NFT")
    nft1 = platform.mint_nft(alice.address, "CyberPunk #1", 
                             "A cyberpunk character", {"rarity": "Epic", "type": "Character"})

    print("\n  Bob mints an NFT")
    nft2 = platform.mint_nft(bob.address, "CyberPunk #2", 
                             "Another cyberpunk character", {"rarity": "Rare", "type": "Character"})

    print("\n  Diana mints an NFT")
    nft3 = platform.mint_nft(diana.address, "Digital Landscape", 
                             "Beautiful digital landscape", {"rarity": "Common", "type": "Art"})

    # ===== DAO OPERATIONS =====
    print("\n 🏛️  DAO Operations:")
    print("-" * 40)

    print("\n  Alice creates a DAO proposal")
    platform.create_dao_proposal(
        alice.address,
        "Fund Community NFT Gallery",
        "Allocate 1000 tokens to fund a community NFT gallery",
        {"type": "treasury_withdrawal", "token": "ETH", "amount": 100, "to": "community_wallet"}
    )

    print("\n  Bob creates a DAO proposal")
    platform.create_dao_proposal(
        bob.address,
        "Add New Yield Farm",
        "Add a new yield farm for USDC-GOV pair",
        {"type": "add_farm", "token": "USDC"}
    )

    print("\n  Voting on proposals...")
    platform.vote_proposal(1, alice.address, "for")
    platform.vote_proposal(1, bob.address, "for")
    platform.vote_proposal(1, charlie.address, "against")
    platform.vote_proposal(1, diana.address, "for")

    platform.vote_proposal(2, alice.address, "for")
    platform.vote_proposal(2, bob.address, "for")
    platform.vote_proposal(2, charlie.address, "for")

    print("\n  Executing proposals...")
    platform.execute_proposal(1)
    platform.execute_proposal(2)

    # ===== FINAL STATE =====
    print("\n 📊 Final State:")
    print("-" * 40)

    print("\n  User Balances:")
    for user in [alice, bob, charlie, diana]:
        print(f"    {user.name}: {user.balance:.2f}")

    print("\n  User NFTs:")
    print(f"    Alice: {alice.nfts}")
    print(f"    Bob: {bob.nfts}")
    print(f"    Charlie: {charlie.nfts}")
    print(f"    Diana: {diana.nfts}")

    print("\n  Platform Statistics:")
    stats = platform.get_platform_stats()
    for key, value in stats.items():
        print(f"    {key}: {value}")

    # ===== PORTFOLIO VIEW =====
    print("\n 📈 User Portfolio (Alice):")
    print("-" * 40)

    portfolio = platform.get_user_portfolio(alice.address)
    for key, value in portfolio.items():
        if key != "address":
            print(f"    {key}: {value}")

    print("\n" + "=" * 60)
    print(" ✅ INTEGRATED PLATFORM DEMONSTRATION COMPLETE")
    print("=" * 60)
    print("\n  This project demonstrates:")
    print("  1. DeFi lending and borrowing with interest")
    print("  2. Token swaps with price impact")
    print("  3. NFT minting and transfer")
    print("  4. Yield farming with rewards")
    print("  5. DAO proposal creation and voting")
    print("  6. Treasury management")
    print("  7. Integrated user experience")

if __name__ == "__main__":
    platform_demo()
Scroll to Top