Blockchain, crypto & Web3
Blockchain, cryptocurrency, and Web3 represent a fundamental paradigm shift from centralized, trust‑based internet services to a decentralized, verifiable digital economy. At its core, blockchain is a distributed, immutable ledger secured by advanced cryptography using hash functions for data integrity, elliptic curve digital signatures for identity and ownership, and consensus mechanisms like Proof‑of‑Stake and BFT to synchronize state across thousands of independent nodes without a central authority. This cryptographic backbone enables native digital assets (cryptocurrencies) and programmatic value transfer via smart contracts, which are self‑executing code that governs everything from fungible tokens (ERC‑20) and non‑fungible assets (ERC‑721/1155) to complex decentralized financial primitives like automated market makers, lending protocols, and stablecoins. Web3 extends this infrastructure into a full‑stack user experience, where frontend applications connect to blockchain networks via wallet providers (EIP‑1193, WalletConnect) and decentralized indexing layers (The Graph), enabling users to retain custody of their data, identity (SIWE), and assets. The ecosystem continues to evolve through Layer‑2 scaling solutions (Optimistic and ZK‑rollups) to overcome the blockchain trilemma, cross‑chain interoperability protocols (IBC, CCIP, LayerZero) to connect isolated networks, and zero‑knowledge proofs to enable privacy and verifiable computation. Ultimately, Web3 is not just a technology stack but a socio‑economic movement, restructuring digital ownership, governance (DAOs), and value creation into a trustless, permissionless, and composable framework where users become stakeholders rather than mere products.

Blockchain, crypto & Web3
Content Overview
- PHASE 1: BLOCKCHAIN and CRYPTO
- Blockchain Foundations & Cryptocurrency
- 1. Introduction to Blockchain
- 2. Blockchain Fundamentals
- 2.1 Distributed Ledger Technology (DLT)
- 2.2 Blockchain Architecture
- 2.3 Blockchain Components
- 2.4 Blocks
- 2.5 Block Header
- 2.6 Genesis Block
- 2.7 Transactions
- 2.8 Transaction Lifecycle
- 2.9 Mempool
- 2.10 Blockchain State
- 2.11 UTXO Model
- 2.12 Account-Based Model
- 2.13 Peer-to-Peer Network
- 2.14 Nodes
- 2.15 Consensus Mechanisms
- 2.16 Mining
- 2.17 Validators
- 2.18 Finality
- 2.19 Forks
- 2.20 Mainnet, Testnet, Devnet
- 2.21 Sidechains
- 2.22 Blockchain Types
- 3. Cryptography
- 3.1 Cryptography Fundamentals
- 3.2 Hash Functions
- 3.3 SHA-256
- 3.4 Keccak-256
- 3.5 Public Key Cryptography
- 3.6 Private Keys
- 3.7 Public Keys
- 3.8 Wallet Addresses
- 3.9 Digital Signatures
- 3.10 ECDSA
- 3.11 EdDSA
- 3.12 Elliptic Curve Cryptography (ECC)
- 3.13 Merkle Trees
- 3.14 Entropy
- 3.15 Random Number Generation
- 3.16 HD Wallet Standards
- 3.17 Zero-Knowledge Proof Fundamentals
- 4. Cryptocurrency
- 5. Wallets & Transactions
- PHASE 1 – COMPLETE PROJECT
- PHASE 2: WEB3 DEVELOPMENT & DECENTRALIZED APPLICATIONS
- PHASE 3: ADVANCED WEB3 ECOSYSTEM, SECURITY & SCALABILITY
- 1. Decentralized Finance (DeFi)
- 2. NFTs (Non-Fungible Tokens)
- 3. DAOs (Decentralized Autonomous Organizations)
- 4. Layer 2 & Blockchain Scaling
- 5. Cross-Chain & Oracle Networks
- 6. Blockchain Security & Auditing
- 7. Testing, Deployment & DevOps
- 8. Advanced Blockchain Concepts
- 9. Real-World Applications
- 10. Blockchain Business & Careers
- PHASE 3 – COMPLETE PROJECT
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.
- Alice creates a transaction and digitally signs it using her private key.
- The transaction is sent to the Bitcoin network for verification.
- Miners validate the transaction and include it in a block
- The block is added to the blockchain
- Bob receives 1 BTC in his wallet
- The transaction is permanently recorded and cannot be reversed or modified.
Key Components of Blockchain:
| Component | Description | Example |
|---|---|---|
| Distributed Ledger | Database spread across multiple locations | Every node has a copy |
| Immutable Records | Once added, data cannot be changed | Transactions are permanent |
| Consensus Mechanisms | Agreement protocols that validate transactions | Proof of Work, Proof of Stake |
| Cryptographic Security | Mathematical encryption that secures data | SHA-256 hashing |
| Smart Contracts | Self-executing code on the blockchain | Ethereum 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:
| Feature | Blockchain | DAG | Hashgraph |
|---|---|---|---|
| Structure | Chain of blocks | Directed graph | Gossip + graph |
| Speed | Medium | High | Very High |
| Scalability | Limited | High | Very High |
| Security | Very High | High | Very High |
| Maturity | High | Medium | Low |
| Energy Use | High (PoW) | Low | Low |
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:
- User interacts with an application (Layer 5)
- Application calls a smart contract (Layer 4)
- Smart contract creates transactions
- Consensus validates and orders transactions (Layer 3)
- Network broadcasts to all nodes (Layer 2)
- 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:
- It links blocks together (previous block hash)
- It verifies all transactions (merkle root)
- It proves computational work (nonce and difficulty)
- It provides timing information (timestamp)
- 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:
- Proof of Existence: It proves that the block was created after January 3, 2009
- Historical Significance: It references a real newspaper headline from that date
- 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:
- User creates transaction in their wallet
- Wallet signs transaction with private key
- Signed transaction is broadcast to the network
- Nodes validate the transaction
- Miners/validators include it in a block
- 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:
| Aspect | UTXO | Account-Based |
|---|---|---|
| Privacy | Better (new addresses) | Less private |
| State Size | Larger (all UTXOs) | Smaller (balances) |
| Complexity | More complex | Simpler |
| Smart Contracts | Harder | Easier |
| Parallel Processing | Easier | Harder |
| Examples | Bitcoin, Cardano | Ethereum, 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:
- They select one or more UTXOs to spend
- They create a transaction with inputs (the UTXOs being spent) and outputs (new UTXOs being created)
- The transaction is signed and broadcast
- The old UTXOs are marked as spent
- 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.
- Input: UTXO A (5 BTC) + UTXO B (3 BTC) = 8 BTC total
- Output 1: 6 BTC to Bob (new UTXO)
- 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:
- User creates a transaction
- Transaction is signed and broadcast
- Nodes validate the transaction
- State is updated directly: sender balance decreases, recipient balance increases
- Nonce is incremented
- 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:
- It connects to a “bootstrap node” (a well-known, trusted node)
- The bootstrap node provides a list of other nodes
- The new node connects to those nodes
- It builds its peer list from connected nodes
Message Propagation:
Gossip Protocol:
Information spreads through the network like gossip:
- Node receives a message (transaction or block)
- Node validates the message
- Node relays the message to its peers
- The process repeats, spreading across the network
Types of Network Messages:
| Message Type | Purpose |
|---|---|
version | Handshake, version info |
verack | Acknowledge version |
inv | Inventory (list of items) |
getdata | Request data items |
block | Send a block |
tx | Send a transaction |
addr | Send peer addresses |
ping/pong | Check 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:
| Mechanism | Description | Energy | Speed | Examples |
|---|---|---|---|---|
| Proof of Work (PoW) | Solve computational puzzles | Very High | Slow | Bitcoin, Litecoin |
| Proof of Stake (PoS) | Stake cryptocurrency to validate | Low | Fast | Ethereum, Cardano |
| Delegated PoS (DPoS) | Stakeholders vote for delegates | Low | Fast | EOS, Tron |
| PBFT | Byzantine Fault Tolerant | Low | Fast | Hyperledger |
Proof of Work (PoW):
How it Works:
- Miners collect transactions from the mempool
- They compete to solve a mathematical puzzle (finding a nonce)
- The first to solve creates the block
- Other nodes verify and accept the block
- 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:
- Validators stake (lock up) cryptocurrency
- The network randomly selects a validator
- Selected validator proposes a block
- Other validators attest to validity
- 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:
- Transaction Collection: Miners collect pending transactions from the mempool
- Block Creation: They create a candidate block with those transactions
- Puzzle Solving: They search for a nonce that makes the block hash meet the target
- Block Propagation: When found, the block is broadcast to the network
- Verification: Other nodes verify and accept the block
- Reward: The miner receives block reward + transaction fees
Mining Hardware Evolution:
| Era | Hardware | Description | Speed |
|---|---|---|---|
| 2009 | CPU | Standard computer processors | 1-5 MH/s |
| 2010 | GPU | Graphics cards (100x faster) | 100-500 MH/s |
| 2012 | FPGA | Field Programmable Gate Arrays | 100-500 MH/s |
| 2013+ | ASIC | Application-Specific ICs | 100+ 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:
| Requirement | Description |
|---|---|
| Stake | Minimum tokens to become validator |
| Hardware | Reliable server with good uptime |
| Connectivity | Fast, stable internet |
| Security | Secure key management |
| Experience | Understanding 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:
- Assets are locked on the main chain before they can be transferred or represented on the sidechain.
- Equivalent assets are unlocked on the sidechain
- Assets can be transferred back to the main chain
Sidechain Features:
| Feature | Description |
|---|---|
| Independent Consensus | Can use different consensus mechanisms |
| Custom Features | Can have specialized functionality |
| Scalability | Offloads transactions from main chain |
| Asset Transfer | Two-way peg for assets |
Examples:
| Sidechain | Main Chain | Purpose |
|---|---|---|
| Liquid | Bitcoin | Faster transactions, confidential transactions |
| Polygon | Ethereum | Scaling, lower fees |
| xDai | Ethereum | Stablecoin 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:
| Function | Output Size | Used In | Characteristics |
|---|---|---|---|
| SHA-256 | 256 bits | Bitcoin | Double SHA-256 used for mining |
| Keccak-256 | 256 bits | Ethereum | Based on SHA-3 competition |
| RIPEMD-160 | 160 bits | Bitcoin | Used for address generation |
| SHA-3 | 256-512 bits | Modern | Latest 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:
- Padding: The input message is padded so its length is 448 mod 512 bits (leaving 64 bits for length)
- Length: The original length of the message is appended as a 64-bit integer
- Initialization: Eight 32-bit state variables are initialized with specific constants
- Processing: The message is processed in 512-bit chunks through 64 rounds of operations
- Output: The final state is concatenated to produce the 256-bit hash
SHA-256 Properties:
| Property | Value |
|---|---|
| Output Size | 256 bits (32 bytes, 64 hex characters) |
| Block Size | 512 bits (64 bytes) |
| Security Level | 128-bit collision resistance |
| Performance | Fast and efficient |
| Rounds | 64 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.
| Feature | Keccak-256 | SHA-3 |
|---|---|---|
| Padding | Different padding | NIST-standard padding |
| Security | Very High | Very High |
| Used In | Ethereum, many dApps | General use |
| Standard | Pre-SHA-3 | FIPS 202 |
Keccak-256 Properties:
| Property | Description |
|---|---|
| Output Size | 256 bits (32 bytes, 64 hex characters) |
| Construction | Sponge construction (not Merkle-Damgård) |
| Security | 128-bit collision resistance |
| Performance | Fast and efficient |
| Used In | Ethereum, 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:
- Absorbing phase: Input data is absorbed into the state
- 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:
| Application | How It Works | Purpose |
|---|---|---|
| Address Generation | Public key → Hash → Address | Receive funds |
| Transaction Signing | Private key signs transaction | Prove ownership |
| Identity Verification | Public key verifies signature | Establish identity |
| Secure Communication | Public key encrypts messages | Private 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:
| Format | Description | Example | Use Case |
|---|---|---|---|
| Hex | 64 hex characters | 0x1e99423a4ed27608… | Machine-readable |
| WIF | Wallet Import Format | 5HueCGU8rMjxEXxi… | Easy to copy |
| Mnemonic | 12-24 words | “abandon ability able…” | Human-friendly backup |
Private Key Security:
| Best Practice | Why |
|---|---|
| Store Offline | Prevents online hacking |
| Use Hardware Wallet | Private key never leaves device |
| Multiple Backups | Protects against loss |
| Never Share | Anyone with key controls funds |
| Secure Location | Physical 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:
| Format | Prefix | Size | Description | Use Case |
|---|---|---|---|---|
| Uncompressed | 0x04 | 65 bytes | Full x and y coordinates | Legacy systems |
| Compressed | 0x02/0x03 | 33 bytes | x coordinate + parity | Modern wallets |
| Hex | Varies | Varies | Hexadecimal representation | Development |
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:
- Public Key → SHA-256 → RIPEMD-160 → Address
- 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?
| Reason | Explanation |
|---|---|
| Length | Addresses are shorter (34 vs 65 bytes) |
| Error Detection | Checksums help catch typos |
| Readability | Easier to copy and share |
| Privacy | Different addresses from same public key |
| Compatibility | Standardized format |
Address Formats by Blockchain:
| Blockchain | Format | Example | Checksum |
|---|---|---|---|
| Bitcoin | Base58Check | 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa | Yes |
| Bitcoin (SegWit) | Bech32 | bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq | Yes |
| Ethereum | Hex + 0x | 0x742d35Cc6634C0532925a3b844Bc454e4438f44e | EIP-55 |
| Solana | Base58 | 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWVH | No |
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:
| Property | Description | Importance |
|---|---|---|
| Authenticity | Proves signer’s identity | Verifies who signed |
| Integrity | Message not altered | Detects tampering |
| Non-Repudiation | Signer can’t deny signing | Legal proof |
Applications in Blockchain:
| Application | How It Works | Purpose |
|---|---|---|
| Transaction Signing | Private key signs transaction | Prove ownership |
| Identity Verification | Public key verifies signature | Authenticate user |
| Authorization | Signatures authorize actions | Security |
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:
- A random number (k) is generated
- The message is hashed
- The signature is computed using the private key and k
Verification:
- The signature is verified using the public key
- The hash of the message is used
- The signature is validated without needing the private key
ECDSA Parameters:
| Parameter | Description | Value (Bitcoin) |
|---|---|---|
| Curve | Elliptic curve | secp256k1 |
| Key Size | Private key size | 256 bits |
| Security Level | Collision resistance | 128 bits |
| Signature Size | r + s | 64 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:
| Feature | Description | Advantage |
|---|---|---|
| Curve | ed25519 | High performance |
| Security | 128-bit | Very secure |
| Speed | Very Fast | Faster than ECDSA |
| Deterministic | Yes | No randomness needed |
| Batch Verification | Yes | Multiple signatures at once |
EdDSA vs ECDSA:
| Feature | ECDSA | EdDSA |
|---|---|---|
| Curve | secp256k1 | ed25519 |
| Sign Speed | Reference | 20% Faster |
| Verify Speed | Reference | 20% Faster |
| Deterministic | No | Yes |
| Batch Verify | No | Yes |
| Security | 128-bit | 128-bit |
| Key Size | 256-bit | 256-bit |
| Used In | Bitcoin, ETH | Solana, 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:
- Point Addition: Adding two points on the curve
- Point Doubling: Adding a point to itself
- Scalar Multiplication: Multiplying a point by a scalar
- 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:
- Provide Hash2, Hash34
- Hash(Hash1 + Hash2) = Hash12
- Hash(Hash12 + Hash34) = Merkle Root
- 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:
| Source | Quality | Use Case |
|---|---|---|
| Hardware RNG | Very High | High security |
| Mouse Movements | Medium | General use |
| System Time | Low | Not secure |
| User Input | Low | Not 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:
| Type | Description | Use Case |
|---|---|---|
| CSPRNG | Cryptographically Secure | Keys, nonces, signatures |
| PRNG | Pseudo-Random | Simulation, testing |
| HRNG | Hardware RNG | High security |
| TRNG | True RNG | Physical randomness |
CSPRNG Properties:
| Property | Description |
|---|---|
| Unpredictable | Future outputs cannot be predicted |
| High Entropy | Based on high-quality randomness |
| Secure | Resistant 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:
- Generate a master seed (128-512 bits)
- Derive master private key from seed
- Generate child keys using derivation paths
- 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:
- Generate random entropy (128-256 bits)
- Calculate checksum
- Map to word list (2048 words)
- 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:
| Cryptocurrency | Coin Type |
|---|---|
| Bitcoin | 0 |
| Ethereum | 60 |
| Solana | 501 |
| Cardano | 1815 |
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:
| Property | Description |
|---|---|
| Completeness | If statement is true, prover can convince verifier |
| Soundness | If statement is false, no one can convince verifier |
| Zero-Knowledge | Verifier learns nothing except the statement’s truth |
Types of Zero-Knowledge Proofs:
| Type | Description | Use Case |
|---|---|---|
| ZK-SNARKs | Succinct Non-Interactive | Efficient, small proofs |
| ZK-STARKs | Transparent, No trusted setup | Security, 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:
| Characteristic | Description | Example |
|---|---|---|
| Decentralized | No central authority | Bitcoin has no CEO or headquarters |
| Cryptographic | Secured by cryptography | Private keys control funds |
| Digital | Exists only online | No physical coins or notes |
| Borderless | Global and accessible | Anyone with internet can participate |
| Transparent | Public ledger | All transactions are visible |
How Cryptocurrencies Work:
- 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.
- Transactions: Users send coins to each other via the blockchain
- Security: Cryptography secures transactions and ownership
- Consensus: Network participants validate transactions
Cryptocurrency vs Fiat Currency:
| Aspect | Cryptocurrency | Fiat Currency |
|---|---|---|
| Control | Decentralized | Central bank |
| Supply | Limited/capped | Infinite (can print) |
| Physical | Digital only | Physical + digital |
| Global | Borderless | Country-specific |
| Privacy | Pseudonymous | KYC 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:
| Feature | Description |
|---|---|
| Network | Peer-to-peer, decentralized |
| Supply | Capped at 21 million BTC |
| Consensus | Proof of Work (PoW) |
| Block Time | ~10 minutes |
| Transaction Speed | ~7 TPS |
| Security | Very 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:
| Year | Block Reward | Supply Mined |
|---|---|---|
| 2009 | 50 BTC | 10.5M |
| 2012 | 25 BTC | 15.75M |
| 2016 | 12.5 BTC | 18.375M |
| 2020 | 6.25 BTC | 19.6875M |
| 2024 | 3.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:
| Feature | Description |
|---|---|
| Network | Smart contract platform |
| Purpose | Programmable blockchain |
| Consensus | Proof of Stake (PoS) |
| Block Time | ~12 seconds |
| Transaction Speed | ~15 TPS |
| Language | Solidity, Vyper |
Ethereum vs Bitcoin:
| Aspect | Bitcoin | Ethereum |
|---|---|---|
| Purpose | Digital money | Smart contracts |
| Language | Limited scripting | Turing-complete |
| Consensus | PoW | PoS |
| Block Time | 10 min | 12 sec |
| Supply | 21M cap | No hard cap |
| Innovation | First crypto | Programmable |
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:
| Category | Description | Examples |
|---|---|---|
| Platforms | Smart contract platforms | Ethereum, Solana, Cardano |
| DeFi | Decentralized finance | Uniswap, Aave, Compound |
| Privacy | Private transactions | Monero, Zcash, Dash |
| Storage | Data storage | Filecoin, Arweave |
| Gaming | Blockchain games | Axie 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:
| Type | Description | Examples |
|---|---|---|
| Fiat-Backed | Backed by fiat reserves | USDC, USDT, BUSD |
| Crypto-Backed | Backed by crypto collateral | DAI, sUSD |
| Algorithmic | Algorithm controls supply | UST (failed) |
Why Stablecoins Matter:
- Stability: Protect against market volatility
- Trading: Base pairs for crypto trading
- Payments: Stable value for transactions
- 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:
| Name | Launch Year | Peak Market Cap | Notable Feature |
|---|---|---|---|
| Dogecoin | 2013 | ~$90B | First meme coin |
| Shiba Inu | 2020 | ~$40B | “Dogecoin killer” |
| Pepe | 2023 | ~$5B | Pepe 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?
| Aspect | Coins | Tokens |
|---|---|---|
| Definition | Native cryptocurrency | Digital asset on blockchain |
| Blockchain | Has own blockchain | Built on existing blockchain |
| Purpose | Currency, fee payment | Utility, governance, asset |
| Examples | BTC, ETH, SOL | USDC, UNI, AAVE |
Coins vs Tokens Comparison:
| Feature | Coins | Tokens |
|---|---|---|
| Own Blockchain | Yes | No |
| Used for Fees | Yes | No |
| Utility | Payment, store of value | App-specific |
| Creation | Requires blockchain | Easy to create |
| Supply | Limited | Depends 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:
| Token | Platform | Purpose |
|---|---|---|
| LINK | Chainlink | Pay for oracle services |
| UNI | Uniswap | Governance + fee sharing |
| AAVE | Aave | Lending/borrowing fees |
| MATIC | Polygon | Pay 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:
| Feature | Description |
|---|---|
| Voting | Vote on proposals |
| Proposals | Submit changes |
| Delegation | Delegate votes |
| Treasury | Control 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:
| Feature | Description |
|---|---|
| Asset-Backed | Represent real assets |
| Regulated | Subject to securities laws |
| Dividends | May pay dividends |
| Ownership | Represent 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:
| Concept | Description |
|---|---|
| Supply | Total tokens available |
| Distribution | How tokens are allocated |
| Utility | What tokens do |
| Incentives | Why 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:
| Model | Description | Examples |
|---|---|---|
| Fixed Supply | Capped total | BTC (21M) |
| Inflationary | Unlimited supply | ETH, DOGE |
| Deflationary | Decreasing supply | BNB (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:
| Coin | Inflation Rate | Purpose |
|---|---|---|
| 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:
| Mechanism | Description | Examples |
|---|---|---|
| Burning | Tokens destroyed | BNB, ETH (EIP-1559) |
| Limited Supply | Capped total | BTC (21M) |
| Decreased Emissions | Reduced rewards | Halving 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:
| Event | Year | Block Reward |
|---|---|---|
| Genesis | 2009 | 50 BTC |
| Halving 1 | 2012 | 25 BTC |
| Halving 2 | 2016 | 12.5 BTC |
| Halving 3 | 2020 | 6.25 BTC |
| Halving 4 | 2024 | 3.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:
| Metric | Description |
|---|---|
| Trading Volume | Amount traded daily |
| Order Book Depth | Buy/sell orders |
| Spread | Bid-ask difference |
| Slippage | Price 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:
| Category | Market Cap | Examples |
|---|---|---|
| Large Cap | > $10B | BTC, ETH, BNB |
| Mid Cap | $1B – $10B | ADA, DOT, LINK |
| Small Cap | < $1B | New 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:
| Aspect | Market Cap | FDV |
|---|---|---|
| Definition | Current value | Potential value |
| Supply | Circulating | Total |
| Comparison | Actual | Theoretical |
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:
| Component | Description |
|---|---|
| Lending | Deposits in lending protocols |
| DEX | Liquidity in DEX pools |
| Staking | Staked tokens |
| Yield | Yield 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:
| Component | Purpose |
|---|---|
| Private Key | Sign transactions |
| Public Key | Receive funds |
| Address | Share with others |
| Seed Phrase | Backup 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:
| Wallet | Type | Platform |
|---|---|---|
| MetaMask | Browser Extension | Desktop |
| Trust Wallet | Mobile App | iOS/Android |
| Coinbase Wallet | Mobile App | iOS/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:
| Type | Description | Examples |
|---|---|---|
| Hardware Wallet | Physical device | Ledger, Trezor |
| Paper Wallet | Printed keys | Paper, metal |
| Air-Gapped | Offline computer | Dedicated 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:
| Wallet | Security Level | Price | Supported Coins |
|---|---|---|---|
| Ledger Nano X | Very High | $149 | 1,000+ |
| Ledger Nano S | Very High | $59 | 1,000+ |
| Trezor Model T | Very High | $219 | 1,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:
| Custodian | Type | Features |
|---|---|---|
| Coinbase | Exchange | Regulated, insured |
| Binance | Exchange | Large, low fees |
| PayPal | Payment | Easy, 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:
| Wallet | Type | Features |
|---|---|---|
| MetaMask | Browser | dApp integration |
| Trust Wallet | Mobile | Multi-chain |
| Ledger | Hardware | Cold 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:
| Format | Words | Bits |
|---|---|---|
| BIP-39 | 12 | 128 |
| BIP-39 | 24 | 256 |
Security Guidelines:
| Rule | Why |
|---|---|
| Never Share | Anyone with phrase controls funds |
| Write Down | Don’t store digitally |
| Backup Multiple | Prevent single point of failure |
| Store Secure | Physical 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:
- Create Transaction: Specify recipient, amount, gas, etc.
- Hash Transaction: Calculate transaction hash
- Sign with Private Key: Encrypt hash with private key
- 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:
| Term | Description |
|---|---|
| Gas | Unit of computational work |
| Gas Limit | Maximum gas allowed |
| Gas Price | Price per gas unit |
| Gwei | 1 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 Type | Typical Gas Limit |
|---|---|
| ETH Transfer | 21,000 |
| ERC-20 Transfer | 65,000 |
| Uniswap Swap | 100,000+ |
| Contract Deployment | 1,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:
| Factor | Effect |
|---|---|
| Network Congestion | Higher = More Expensive |
| Transaction Priority | Higher = Faster Processing |
| Time of Day | Varies |
| Current Gas Price | Market-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:
| Unit | Value |
|---|---|
| 1 Gwei | 10^-9 ETH |
| 1 ETH | 10^9 Gwei |
| 1,000 Gwei | 0.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:
| Property | Description |
|---|---|
| Starts at 0 | First transaction |
| Increments by 1 | Each new transaction |
| Unique per Address | No 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:
| Config | Description | Use Case |
|---|---|---|
| 1-of-2 | One key needed | Redundancy |
| 2-of-3 | Two of three keys | Common (business) |
| 3-of-5 | Three of five keys | High 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:
| Blockchain | Explorer |
|---|---|
| Bitcoin | blockchain.com |
| Ethereum | etherscan.io |
| Solana | solscan.io |
| Polygon | polygonscan.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:
| Practice | Description |
|---|---|
| Seed Phrase Backup | Write down, store securely |
| Cold Storage | Keep keys offline |
| Multi-Sig | Distribute control |
| Two-Factor Authentication | Additional security layer |
| Regular Updates | Keep 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:
| Benefit | Description | Example |
|---|---|---|
| Censorship Resistance | No central authority can shut it down | Bitcoin cannot be blocked by any government |
| No Single Point of Failure | System continues even if nodes fail | Ethereum runs on thousands of nodes |
| User Control | Users own their data and assets | Self-custody of crypto assets |
| Transparency | All actions are public and verifiable | Anyone can audit the code |
| Permissionless | Anyone can participate | No 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:
| Component | Description | Purpose |
|---|---|---|
| Ethereum Blockchain | The underlying ledger | Store transactions and state |
| ETH (Ether) | Native cryptocurrency | Pay for transactions (gas) |
| EVM | Ethereum Virtual Machine | Execute smart contracts |
| Smart Contracts | Programmable code | Build dApps and tokens |
| dApps | Decentralized applications | User-facing applications |
| Wallets | Key management | Store and send ETH |
| Nodes | Network participants | Validate and secure the network |
Ethereum’s Evolution:
| Phase | Year | Description |
|---|---|---|
| Frontier | 2015 | Initial launch, basic functionality |
| Homestead | 2016 | First production release |
| Metropolis | 2017-2018 | Improved security and scalability |
| Serenity (ETH 2.0) | 2020-2023 | Proof of Stake, sharding |
| The Merge | 2022 | Transition 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:
- Compilation: Smart contract code (Solidity) is compiled to EVM bytecode
- Deployment: Bytecode is deployed to the blockchain
- Execution: When called, the EVM executes the bytecode
- State Changes: The EVM updates the blockchain state
EVM Characteristics:
| Characteristic | Description |
|---|---|
| Turing-Complete | Can execute any program (given enough resources) |
| Deterministic | Same input always produces same output |
| Isolated | Each contract runs in its own environment |
| Gas Metered | Each operation costs gas to prevent infinite loops |
| Stack-Based | Uses 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:
| Characteristic | Description |
|---|---|
| Self-Executing | Automatically executes when conditions are met |
| Immutable | Once deployed, cannot be changed |
| Transparent | Code is visible on the blockchain |
| Trustless | No need for third-party trust |
| Automated | No 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 Case | Description |
|---|---|
| Token Contracts | Create and manage tokens (ERC-20, ERC-721) |
| DeFi Protocols | Lending, borrowing, trading |
| DAOs | Decentralized governance |
| NFTs | Digital ownership and royalties |
| Marketplaces | Decentralized 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:
| Characteristic | Description |
|---|---|
| Controlled By | Private key |
| Can Send ETH | Yes, to any address |
| Can Send Transactions | Yes, any transaction originates from an EOA |
| Can Deploy Contracts | Yes, by sending a contract creation transaction |
| Has Balance | Yes, holds ETH |
| Can Hold Tokens | Yes, 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:
| Characteristic | Description |
|---|---|
| Controlled By | Code (smart contract logic) |
| Can Send ETH | Yes, when triggered by a transaction |
| Can Send Transactions | No, cannot initiate transactions |
| Can Deploy Contracts | Yes, can create other contracts |
| Has Balance | Yes, can hold ETH and tokens |
| Has Storage | Yes, 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:
| Component | Description |
|---|---|
| Function Signatures | Names and parameter types |
| Event Definitions | Event names and parameters |
| Encoding Rules | How to encode data for functions |
| Decoding Rules | How 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:
| Characteristic | Description |
|---|---|
| Low-Level | Machine-like instructions |
| EVM Executable | Directly run by the EVM |
| Gas-Optimized | Each instruction costs gas |
| Immutable | Cannot 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:
| Component | Description |
|---|---|
| Gas Limit | Maximum gas a user is willing to pay |
| Gas Price | Amount per gas unit (in Gwei) |
| Base Fee | Minimum fee set by the network |
| Priority Fee | Tip 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:
| Method | Description |
|---|---|
eth_blockNumber | Get current block number |
eth_getBalance | Get balance of an address |
eth_sendTransaction | Send a transaction |
eth_call | Execute a smart contract call |
eth_getTransactionReceipt | Get 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:
| Provider | Description | Best For |
|---|---|---|
| Infura | Most popular, easy to use | General use |
| Alchemy | Feature-rich, analytics | Advanced applications |
| QuickNode | Fast, global | Performance-critical apps |
| Cloudflare | Privacy-focused | dApps |
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:
| Type | Description | Storage | Example |
|---|---|---|---|
| State Variables | Stored permanently on the blockchain | Blockchain | uint256 public balance; |
| Local Variables | Temporary, exist only during function execution | Memory | uint256 amount = 100; |
| Global Variables | Provide information about the blockchain | Special | block.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 Category | Description | Examples |
|---|---|---|
| Value Types | Store data directly | uint, int, bool, address |
| Reference Types | Store location of data | arrays, structs, mappings |
Common Data Types:
| Type | Description | Example | Use Case |
|---|---|---|---|
| uint | Unsigned integer | uint256 x = 100; | Token balances |
| int | Signed integer | int256 y = -50; | Negative values |
| bool | Boolean (true/false) | bool isActive = true; | Status flags |
| address | Ethereum address | address owner = 0x123...; | User identity |
| string | UTF-8 text | string name = "Alice"; | Names, metadata |
| bytes | Byte array | bytes32 hash; | Cryptographic data |
Real-World Example – Token Contract:
When creating a token:
- Use
uint256for balances (never negative) - Use
addressfor users - Use
stringfor token name and symbol - Use
mappingto 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 Type | Description | Examples |
|---|---|---|
| Arithmetic | Mathematical operations | +, -, *, /, % |
| Comparison | Compare values | ==, !=, >, <, >=, <= |
| Logical | Boolean logic | &&, ||, ! |
| Bitwise | Bit-level operations | &, |, ^, ~, <<, >> |
| Assignment | Assign 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:
| Type | Description | Gas Cost | Use Case |
|---|---|---|---|
| view | Reads state, doesn’t modify | Low | Reading balances |
| pure | No state access, no modification | Lowest | Mathematical calculations |
| payable | Can receive ETH | Normal | Deposits, payments |
| default | Can modify state | Normal | Updates, transfers |
Function Properties:
| Property | Description | Example |
|---|---|---|
| Visibility | Who can call the function | public, private, internal, external |
| Modifiers | Add conditions to functions | onlyOwner, whenNotPaused |
| Returns | What values are returned | returns (uint256) |
| Parameters | Input values | (address _to, uint256 _amount) |
Real-World Example – Token Transfer:
A transfer function:
- Takes
address _toanduint256 _amountas parameters - Has
publicvisibility (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:
| Characteristic | Description |
|---|---|
| Runs Once | Only at deployment time |
| Cannot be Called | Only the deployer can trigger it |
| Initializes State | Sets initial values for state variables |
| Can Accept Parameters | For customizable deployment |
Common Uses:
- Setting Owner: The deployer becomes the owner
- Initial Token Supply: Minting initial tokens
- 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:
| Visibility | Access | Description | Use Case |
|---|---|---|---|
| public | Anyone | Accessible from anywhere | User-facing functions |
| private | Only this contract | Not accessible externally | Internal helpers |
| internal | This contract + children | Not accessible externally | Shared functions |
| external | Only externally | Not accessible internally | Interface 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:
| Structure | Description | Use Case |
|---|---|---|
| if/else | Conditional execution | Validation, branching |
| for | Fixed iteration | Processing arrays |
| while | Conditional iteration | Unknown iteration count |
| do-while | At least once iteration | Guaranteed execution |
| require | Input validation | Security checks |
| revert | Undo transaction | Error handling |
| assert | Internal invariant | Bug detection |
Real-World Example – Transfer Function:
ifto check balancerequireto validate inputsforto 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:
| Characteristic | Description |
|---|---|
| Custom Type | Define your own data structure |
| Multiple Fields | Group related data together |
| Nested | Can contain other structs |
| Stored in State | Can be stored in mappings/arrays |
Real-World Example – User Profile:
A struct for a user profile:
address– User addressstring– Usernameuint256– Agebool– 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:
| Characteristic | Description |
|---|---|
| Predefined Values | Set of allowed values |
| Type-Safe | Only defined values allowed |
| Readable | Names instead of numbers |
| Convertible | Can convert to/from uint |
Real-World Example – Order Status:
An enum for order status:
PendingProcessingShippedDeliveredCancelled
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:
| Type | Description | Gas Cost | Use Case |
|---|---|---|---|
| Fixed | Fixed length, known at compile time | Lower | Known data size |
| Dynamic | Variable length, can grow/shrink | Higher | Unknown data size |
| Memory | Temporary array in function | Lower | Temporary data |
| Storage | Persistent array in state | Higher | Stored 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:
| Characteristic | Description |
|---|---|
| Key-Value | Store values by key |
| Efficient | O(1) lookup time |
| All Keys Exist | Returns default for missing keys |
| No Iteration | Cannot 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:
| Characteristic | Description |
|---|---|
| Log Data | Record information on blockchain |
| Indexable | Can search by indexed parameters |
| Gas Efficient | Cheaper than storing data |
| External Access | Accessible 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:
| Type | Description | Gas Cost | Use Case |
|---|---|---|---|
| require | Check condition, revert if false | Medium | Input validation |
| revert | Explicit revert | Medium | Complex conditions |
| assert | Check internal invariant | High | Bug detection |
| Custom | User-defined errors | Low | Frequent errors |
Real-World Example – Token Transfer:
requirefor balance checkrequirefor address validationrequirefor 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:
| Characteristic | Description |
|---|---|
| Reusable | Apply to multiple functions |
| Composable | Can be combined |
| Readable | Clean and clear code |
| Security | Enforce 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:
| Characteristic | Description |
|---|---|
| Reusable | Share code across contracts |
| Stateless | Cannot hold state variables |
| View/Pure | Functions are view or pure |
| Gas Efficient | Reduces 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:
| Characteristic | Description |
|---|---|
| Function Signatures | Only function declarations |
| No Implementation | No function bodies |
| No State | No state variables |
| Inheritance | Contracts 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:
| Characteristic | Description |
|---|---|
| Unimplemented Functions | Contains abstract functions |
| Cannot Deploy | Cannot be deployed directly |
| Inheritance Base | Meant to be inherited |
| Partial Implementation | Can 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:
| Characteristic | Description |
|---|---|
| Code Reuse | Inherit functions and state |
| Modularity | Build from smaller components |
| Override | Override inherited functions |
| Multiple | Inherit 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:
| Characteristic | Description |
|---|---|
| Permanent | Stored on blockchain |
| Expensive | High gas cost |
| Persistent | Remains between function calls |
| Key-Value | Stored 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:
| Characteristic | Description |
|---|---|
| Temporary | Cleared after function |
| Cheaper | Less gas than storage |
| Limited | Cannot store large data |
| Mutable | Can 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:
| Characteristic | Description |
|---|---|
| Read-Only | Cannot be modified |
| Cheap | Cheaper than memory |
| External | Only available in external functions |
| Non-Persistent | Not 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:
| Characteristic | Description |
|---|---|
| Context | Executes in caller’s context |
| Storage | Uses caller’s storage |
| msg.sender | Preserves original sender |
| msg.value | Preserves 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:
| Benefit | Description |
|---|---|
| Upgradeable | Can update contract logic |
| Immutable Address | Users always interact with same address |
| Storage Preservation | Storage remains intact |
| EIP-1967 | Standard proxy pattern |
Common Proxy Patterns:
| Pattern | Description | Use Case |
|---|---|---|
| Transparent | Simple upgradeable proxy | General use |
| UUPS | Upgradeable with implementation | Gas efficient |
| Beacon | Multiple proxies sharing implementation | Many 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:
| Pattern | Description | Complexity |
|---|---|---|
| Proxy Pattern | Separate logic from state | Medium |
| Diamond Pattern | Multiple implementation contracts | High |
| Eternal Storage | State in separate contract | Medium |
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:
| Pattern | Description | Use Case |
|---|---|---|
| Checks-Effects-Interactions | Validate, update state, then interact | Security |
| Pull over Push | Let users withdraw funds | Payment handling |
| Circuit Breaker | Emergency pause functionality | Security |
| Factory | Create new contract instances | Contract 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:
| Technique | Description | Gas Saved |
|---|---|---|
| Packing Variables | Use smaller types | High |
| Calldata | Use calldata for parameters | Medium |
| Short Circuit | Optimize conditionals | Low |
| Constants | Use constants/immutable | Medium |
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:
| Function | Description |
|---|---|
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:
| Feature | Description |
|---|---|
| Send/Receive Hooks | Notify contracts on transfers |
| Operator | Designated address can send on behalf |
| Backward Compatible | Works with ERC-20 |
| Events | More 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:
| Function | Description |
|---|---|
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:
| Feature | Description |
|---|---|
| Unique Tokens | Each token has unique ID |
| Ownership | Track owner of each token |
| Transfer | Transfer ownership |
| Approval | Approve 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:
| Feature | Description |
|---|---|
| Multi-Token | Both fungible and non-fungible |
| Batch Operations | Transfer multiple tokens at once |
| Gas Efficient | Single contract for multiple tokens |
| Metadata | URI 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:
| Feature | Description |
|---|---|
| Royalty Info | Get royalty information |
| Split Payments | Multiple recipients |
| Percentage | Percentage-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:
| Feature | Description |
|---|---|
| Account Abstraction | Smart contract wallets |
| User Operations | Alternative to transactions |
| Bundling | Multiple operations in one |
| Gas Sponsorship | Pay 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:
| Feature | Description |
|---|---|
| Browser-Based | No installation needed |
| Compilation | Built-in Solidity compiler |
| Deployment | Deploy to any network |
| Debugging | Step 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:
| Extension | Purpose |
|---|---|
| Solidity | Language support |
| Hardhat | Development framework |
| Prettier | Code formatting |
| GitLens | Version control |
Frameworks
Hardhat
Hardhat is a development environment for Ethereum. It provides tools for compiling, testing, and deploying smart contracts.
Hardhat Features:
| Feature | Description |
|---|---|
| Compilation | Compile Solidity contracts |
| Testing | Write and run tests |
| Deployment | Deploy to any network |
| Debugging | Console.log for Solidity |
| Plugins | Extensible 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:
| Feature | Description |
|---|---|
| Speed | Very fast compilation and testing |
| Forge | Testing framework |
| Cast | Command-line Ethereum tool |
| Anvil | Local 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:
| Feature | Description |
|---|---|
| ERC Standards | ERC-20, ERC-721, ERC-1155 |
| Security | Audited and battle-tested |
| Upgradeable | Proxy patterns |
| Access Control | Ownable, 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:
| Feature | Description |
|---|---|
| Provider | Connect to Ethereum nodes |
| Wallet | Manage private keys |
| Contract | Interact with smart contracts |
| Signer | Sign 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:
| Feature | Description |
|---|---|
| Component-Based | Reusable UI components |
| Virtual DOM | Efficient updates |
| Hooks | State and lifecycle |
| Ecosystem | Vast 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:
| Feature | Description |
|---|---|
| SSR | Server-side rendering |
| Routing | File-based routing |
| API Routes | Backend endpoints |
| Optimization | Performance 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:
| Feature | Description |
|---|---|
| Browser Extension | Chrome, Firefox, Brave |
| Mobile App | iOS and Android |
| Network Switching | Multiple networks |
| Transaction Signing | Secure 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:
| Feature | Description |
|---|---|
| QR Code | Scan to connect |
| Deep Linking | Open in wallet app |
| Multiple Wallets | Rainbow, Trust Wallet |
| Secure | No 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:
| Feature | Description |
|---|---|
| Content Addressing | Access by hash |
| Deduplication | Store once |
| Decentralized | No central server |
| Permanent | If 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:
| Feature | Description |
|---|---|
| Subgraph | Define what data to index |
| GraphQL | Query language |
| Decentralized | Decentralized 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:
| Feature | Description |
|---|---|
| .eth Domains | Human-readable names |
| Resolver | Map names to addresses |
| Reverse Records | Address 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:
| Component | Description | Example |
|---|---|---|
| DEX | Decentralized Exchange for peer-to-peer trading | Uniswap, SushiSwap |
| AMM | Automated Market Maker using algorithms for pricing | Uniswap, Curve |
| Liquidity Pools | Pooled funds that provide liquidity for trading | Uniswap pools |
| Lending | Borrow and lend assets with interest | Aave, Compound |
| Staking | Lock assets to earn rewards | Ethereum 2.0 |
| Yield Farming | Earn rewards by providing liquidity | Yearn Finance |
| Flash Loans | Unc collateralized loans repaid in the same transaction | Aave, dYdX |
| Stablecoins | Cryptocurrencies pegged to stable assets | USDC, 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:
- Order Book DEXs: Match buyers and sellers using an order book (e.g., 0x, dYdX)
- AMM DEXs: Use liquidity pools and algorithms to determine prices (e.g., Uniswap, Curve)
- Aggregators: Find the best prices across multiple DEXs (e.g., 1inch, Paraswap)
Advantages of DEXs:
| Advantage | Description |
|---|---|
| Self-Custody | Users control their funds at all times |
| No KYC | No identity verification required |
| Censorship-Resistant | No central authority can block trades |
| Transparent | All transactions are on-chain |
| Composable | Can 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:
- Liquidity providers deposit equal value of two tokens into a pool
- The pool calculates prices based on the ratio of reserves
- Traders swap tokens, changing the ratio and thus the price
- 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:
- Deposit: LP deposits equal value of two tokens
- LP Tokens: Receives LP tokens representing share of the pool
- Earn Fees: Receives a share of trading fees proportional to their share
- 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:
- Provide Liquidity: Deposit tokens into a liquidity pool
- Receive LP Tokens: Get LP tokens representing your share
- Stake LP Tokens: Stake LP tokens in a farm
- Earn Rewards: Receive additional tokens as rewards
- Compound: Reinvest rewards for higher returns
Example:
- Deposit ETH and USDC into Uniswap pool
- Receive UNI-V2 LP tokens
- Stake LP tokens in a yield farm
- Earn rewards in the farm’s native token
- 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:
- Lock Tokens: Lock up a minimum amount of tokens
- Become Validator/Delegate: Either run a validator node or delegate to one
- Earn Rewards: Receive rewards for helping secure the network
- 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:
- Deposit: User deposits assets into a lending pool
- Earn Interest: Earn interest from borrowers
- Withdraw: Can withdraw anytime
How Borrowing Works:
- Provide Collateral: Deposit assets as collateral (over-collateralized)
- Borrow: Borrow up to a certain percentage of collateral value
- Pay Interest: Pay variable or fixed interest
- 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:
- Borrow: Borrow assets in a single transaction
- Use: Use the assets for arbitrage, refinancing, etc.
- Repay: Repay the loan + fee in the same transaction
- Revert: If repayment fails, the entire transaction reverts
Example:
- Borrow 10,000 DAI
- Use 10,000 DAI to arbitrage between two exchanges
- Profit 100 DAI
- Repay 10,000 DAI + 0.09% fee
- 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:
| Type | Description | Example |
|---|---|---|
| Fiat-Backed | Backed by fiat currency reserves | USDC, USDT |
| Crypto-Backed | Over-collateralized by crypto | DAI |
| Algorithmic | Algorithm controls supply | UST (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:
| Component | Description |
|---|---|
| Token ID | Unique identifier for the NFT |
| Contract Address | The smart contract address |
| Metadata | Name, description, image URI |
| Owner | Current owner address |
| Properties | Attributes 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:
- Create Art/Content: Create the digital asset
- Upload to IPFS: Store the asset and metadata on IPFS
- Deploy Contract: Create an NFT smart contract
- Mint NFT: Call the mint function with metadata URI
- 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:
- Set Royalty: Creator sets royalty percentage (e.g., 10%)
- List NFT: NFT is listed on a marketplace
- Secondary Sale: NFT sells for 1 ETH
- 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:
| Marketplace | Features | Supported Chains |
|---|---|---|
| OpenSea | Largest, broadest selection | Ethereum, Polygon, Solana |
| Rarible | Community-owned | Ethereum, Tezos |
| SuperRare | Curated digital art | Ethereum |
| LooksRare | Token rewards | Ethereum |
| Blur | Professional traders | Ethereum |
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:
- Proposal Creation: Member creates a proposal
- Discussion: Community discusses the proposal
- Voting: Token holders vote (for/against/abstain)
- 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:
| Function | Description |
|---|---|
| Voting | Vote on proposals |
| Delegation | Delegate voting power to others |
| Proposal Creation | Create new proposals |
| Treasury Control | Vote 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:
| Method | Description | Example |
|---|---|---|
| Token-Weighted | One token = One vote | Most DAOs |
| Quadratic | Square root of tokens | Gitcoin |
| Vote Delegation | Delegate votes | Compound |
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:
| Blockchain | TPS | Comparison |
|---|---|---|
| Bitcoin | ~7 | Very limited |
| Ethereum | ~15 | Limited |
| Visa | ~24,000 | Industry 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:
| Type | Description | Example |
|---|---|---|
| Optimistic Rollups | Assume transactions are valid, with fraud proofs | Arbitrum, Optimism |
| ZK Rollups | Use zero-knowledge proofs for validity | zkSync, Starknet |
How Rollups Work:
- Batch Transactions: Collect many transactions off-chain
- Process Off-Chain: Execute transactions off-chain
- Submit Batch: Submit a single batch to main chain
- 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:
| Solution | Description |
|---|---|
| PoS Chain | Sidechain with Ethereum compatibility |
| zkEVM | ZK rollup with full EVM compatibility |
| Miden | STARK-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:
| Type | Description | Example |
|---|---|---|
| Centralized | Trusted bridge | Binance Bridge |
| Decentralized | Trustless bridge | Hop Protocol |
| Light Client | Uses light clients | Cosmos 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
5.7 Chainlink
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:
| Principle | Description |
|---|---|
| Checks-Effects-Interactions | Update state before external calls |
| Fail Early | Validate inputs early |
| Defensive Programming | Assume worst-case |
| Minimal Complexity | Keep 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:
| Vulnerability | Description | Prevention |
|---|---|---|
| Reentrancy | Calling external contract before updating state | Checks-Effects-Interactions pattern |
| Integer Overflow | Numbers exceeding maximum value | SafeMath libraries |
| Access Control | Unauthorized access to functions | OnlyOwner modifier |
| Front Running | Transactions being exploited by miners | Commit-reveal schemes |
| Sandwich Attack | Trading around a user’s transaction | Slippage protection |
| Oracle Manipulation | Manipulating price oracles | Multiple oracle sources |
| Flash Loan Attack | Using flash loans to exploit | Secure 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 Type | Description | Tools |
|---|---|---|
| Unit Testing | Test individual functions | Hardhat, Foundry |
| Integration Testing | Test contract interactions | Hardhat, Foundry |
| Fuzz Testing | Random input testing | Echidna, Foundry |
| Mainnet Fork Testing | Test on a copy of mainnet | Hardhat 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:
| Component | Purpose | Examples |
|---|---|---|
| RPC Providers | Connect to blockchain | Infura, Alchemy |
| Monitoring | Track performance | The Graph |
| Logging | Debug and audit | Contract 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:
| Type | Description |
|---|---|
| Arbitrage | Exploiting price differences |
| Liquidations | Liquidating under-collateralized positions |
| Front Running | Inserting 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:
| Benefit | Description |
|---|---|
| Traceability | Track products from origin |
| Authenticity | Verify product authenticity |
| Efficiency | Reduce 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:
| Element | Description |
|---|---|
| Supply Model | Fixed, inflationary, deflationary |
| Distribution | How tokens are distributed |
| Utility | What tokens are used for |
| Governance | How decisions are made |
10.2 Fundraising Methods
| Method | Description | Example |
|---|---|---|
| ICO | Initial Coin Offering | Ethereum |
| IEO | Initial Exchange Offering | Binance Launchpad |
| IDO | Initial DEX Offering | Uniswap |
| Airdrops | Free token distribution | UNI airdrop |
10.3 Career Paths
| Career | Description | Skills |
|---|---|---|
| Blockchain Developer | Build blockchain applications | Solidity, Web3 |
| Smart Contract Engineer | Write and audit contracts | Solidity, Security |
| Web3 Full-Stack Developer | Build dApps | React, Web3.js |
| Protocol Engineer | Design blockchain protocols | Rust, Go |
| Security Engineer | Audit smart contracts | Solidity, Security |
| Blockchain Researcher | Advance the field | Research, 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()


