Learning Objectives:

  • Understand Ethereum’s architecture and design principles

  • Master the Ethereum Virtual Machine (EVM) and its operation

  • Analyze Ethereum’s account model and state management

  • Understand gas, transactions, and block structure


4.1.1: Introduction to Ethereum – Beyond Bitcoin

What is Ethereum?

Ethereum is a decentralized, open-source blockchain platform that enables smart contracts and decentralized applications (dApps). Unlike Bitcoin, which was designed primarily as a digital currency, Ethereum is a programmable blockchain that can execute arbitrary code.

 
Ethereum vs Bitcoin Comparison:

┌─────────────────────────────────────────────────────────────────────┐
│                    Ethereum vs Bitcoin                             │
│                                                                   │
│  Bitcoin:                                                         │
│  • Purpose: Digital cash                                         │
│  • Scripting: Limited (non-Turing complete)                      │
│  • State: UTXO model                                             │
│  • Block Time: ~10 minutes                                       │
│  • TPS: ~7                                                       │
│  • Use Cases: Payments, store of value                           │
│                                                                   │
│  Ethereum:                                                        │
│  • Purpose: Programmable blockchain                              │
│  • Scripting: Full (Turing complete)                             │
│  • State: Account model                                          │
│  • Block Time: ~12-15 seconds                                    │
│  • TPS: ~15-30                                                   │
│  • Use Cases: dApps, DeFi, NFTs, DAOs                           │
│                                                                   │
└─────────────────────────────────────────────────────────────────────┘

Key Innovations of Ethereum:

 
 
Innovation Description Impact
Smart Contracts Self-executing code on blockchain Programmable money
Ethereum Virtual Machine (EVM) Decentralized runtime environment Universal execution
Account Model Stateful accounts instead of UTXOs Simpler applications
Gas System Transaction fee mechanism Resource metering
Turing Completeness Full programming language Unlimited applications
ERC Standards Standardized token contracts Interoperability

Ethereum History and Milestones:

 
 
Year Event Significance
2013 Ethereum Whitepaper Vision articulated
2014 Ethereum Crowdsale Fundraising, initial development
2015 Frontier Launch First live Ethereum network
2016 The DAO Hack Security crisis, hard fork
2016 Ethereum Classic Split from main chain
2017 Byzantium Upgrade Performance improvements
2018 Constantinople Upgrade Further improvements
2019 Istanbul Upgrade Performance and security
2020 Beacon Chain Launch Proof of Stake begins
2021 Berlin/London Upgrades EIP-1559, fee market reform
2022 The Merge Transition to Proof of Stake
2023 Shanghai Upgrade Staking withdrawals enabled
2024 Dencun Upgrade EIP-4844, Proto-Danksharding

4.1.2: Ethereum Architecture

Ethereum’s Layered Architecture:

 
Ethereum Architecture Layers:

┌─────────────────────────────────────────────────────────────────────┐
│                    DApp Layer                                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  DeFi Apps  │  │  NFT Apps   │  │  Gaming     │              │
│  │  (Uniswap)  │  │  (OpenSea)  │  │  (Axie)     │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Smart Contract Layer                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Solidity   │  │  Vyper      │  │  Yul        │              │
│  │  Contracts  │  │  Contracts  │  │  Assembly   │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Ethereum Virtual Machine (EVM)                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Opcode     │  │  Stack      │  │  Memory     │              │
│  │  Execution  │  │  Operations │  │  Management │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Blockchain Layer                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Blocks     │  │  Transactions│  │  State Trie │              │
│  │  (Headers)  │  │  (Receipts)  │  │  (Patricia) │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Consensus Layer                                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Proof of   │  │  Validators │  │  Slashing   │              │
│  │  Stake      │  │  (32 ETH)   │  │  Conditions │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Network Layer                                    │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  P2P        │  │  Peer       │  │  RPC        │              │
│  │  Network    │  │  Discovery  │  │  Interface  │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘

4.1.3: Ethereum Virtual Machine (EVM) – Deep Dive

The EVM Overview:

The Ethereum Virtual Machine is the runtime environment for smart contracts on Ethereum. It is a stack-based, Turing-complete virtual machine that executes bytecode.

text
EVM Architecture:

┌─────────────────────────────────────────────────────────────────────┐
│                    EVM Architecture                                │
│                                                                   │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  EVM State                                                  │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │   │
│  │  │  Stack      │  │  Memory     │  │  Storage    │       │   │
│  │  │  (256-bit)  │  │  (byte)     │  │  (key-value)│       │   │
│  │  │  Max 1024   │  │  Expandable │  │  Persistent │       │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘       │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                              │                                    │
│  ┌───────────────────────────▼─────────────────────────────────┐   │
│  │  Execution Context                                          │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │   │
│  │  │  PC         │  │  Gas        │  │  Call       │       │   │
│  │  │  (Program   │  │  Available  │  │  Context    │       │   │
│  │  │  Counter)   │  │  (Gas Left) │  │  (Sender)   │       │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘       │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                              │                                    │
│  ┌───────────────────────────▼─────────────────────────────────┐   │
│  │  World State                                                │   │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │   │
│  │  │  Accounts   │  │  Balances   │  │  Contract   │       │   │
│  │  │  (160-bit)  │  │  (Wei)      │  │  Storage    │       │   │
│  │  └─────────────┘  └─────────────┘  └─────────────┘       │   │
│  └─────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

EVM Execution Components:

 
 
Component Description Characteristics
Stack Word-addressable, 256-bit values Max 1024 items, LIFO
Memory Linear byte-addressable Expandable, non-persistent
Storage Key-value store Persistent, expensive
Program Counter Points to current instruction Increments after each opcode
Gas Counter Tracks remaining gas Deducted for each operation
Call Context Execution environment Sender, value, data

EVM Word Size and Data Types:

EVM Word Size:
- 256 bits (32 bytes)
- Gas-optimized
- Matches SHA-256 output
- Supports big integers

Data Types:
1. uint256: 256-bit unsigned integer
2. int256: 256-bit signed integer
3. address: 160-bit Ethereum address
4. bool: Boolean (true/false)
5. bytes: Arbitrary byte array
6. string: UTF-8 encoded string

EVM Operations Categories:

 
 
Category Opcodes Description
Stack Operations POP, PUSH, DUP, SWAP Manipulate stack
Arithmetic ADD, SUB, MUL, DIV, MOD Integer arithmetic
Comparison LT, GT, EQ, ISZERO Compare values
Bitwise AND, OR, XOR, NOT Bitwise operations
Memory MLOAD, MSTORE, MSTORE8 Memory operations
Storage SLOAD, SSTORE Storage operations
Flow Control JUMP, JUMPI, STOP, RETURN Control execution
Environment CALLER, ADDRESS, BALANCE Environment data
Block BLOCKHASH, TIMESTAMP, NUMBER Block data
Transaction ORIGIN, GASPRICE, GAS Transaction data
System CREATE, CALL, STATICCALL Contract interactions
Logging LOG0-LOG4 Event logging
Extensible SHA3, SELFDESTRUCT Special operations

4.1.4: Ethereum Accounts

Account Types:

Ethereum has two types of accounts that share the same state structure but serve different purposes.

Account Types:

┌─────────────────────────────────────────────────────────────────────┐
│                    Account Types                                   │
│                                                                   │
│  Externally Owned Account (EOA):                                  │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  • Controlled by private key                              │   │
│  │  • Can send transactions                                  │   │
│  │  • Has balance                                            │   │
│  │  • No code                                                │   │
│  │  • Nonce (transaction count)                              │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                   │
│  Contract Account:                                                │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  • Controlled by code (smart contract)                    │   │
│  │  • Can respond to transactions                            │   │
│  │  • Has balance                                            │   │
│  │  • Has code                                                │   │
│  │  • Has storage                                             │   │
│  │  • Has nonce (created contract count)                     │   │
│  └─────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

Account Structure:

 
Account Fields:

1. Nonce (64-bit unsigned integer):
   - For EOA: Number of transactions sent
   - For Contract: Number of contracts created

2. Balance (256-bit unsigned integer):
   - Amount of Wei owned
   - 1 Ether = 10^18 Wei

3. Storage Root (256-bit hash):
   - Root of Merkle Patricia Trie
   - Contains contract storage data
   - Empty for EOAs

4. Code Hash (256-bit hash):
   - Hash of contract code
   - Empty for EOAs
   - Immutable after creation

Ethereum Addresses:

 
Address Generation:

Private Key (256 bits)
     │
     ▼
Elliptic Curve Multiplication (secp256k1)
     │
     ▼
Public Key (64 bytes uncompressed)
     │
     ▼
Keccak-256 Hash (32 bytes)
     │
     ▼
Take Last 20 Bytes
     │
     ▼
Ethereum Address (20 bytes, 40 hex characters)

Address Example: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e

Address Properties:
- 20 bytes (160 bits)
- 40 hexadecimal characters
- Case-insensitive (but checksummed)
- Checksum version: EIP-55 (mixed case)

4.1.5: Transactions in Ethereum

Transaction Structure:

 
Ethereum Transaction Fields:

┌─────────────────────────────────────────────────────────────────────┐
│                    Transaction Fields                              │
│                                                                   │
│  To: 20 bytes (contract address or EOA)                         │
│                                                                   │
│  Value: 256-bit unsigned (amount in Wei)                       │
│                                                                   │
│  Data: Variable length (input data for contract calls)          │
│                                                                   │
│  Nonce: 64-bit unsigned (transaction count)                    │
│                                                                   │
│  Gas Limit: 64-bit unsigned (max gas for this tx)             │
│                                                                   │
│  Gas Price: 256-bit unsigned (price per gas unit)             │
│                                                                   │
│  Signature: (v, r, s) (ECDSA signature)                         │
│                                                                   │
│  Chain ID: Prevents replay attacks on other networks           │
│                                                                   │
└─────────────────────────────────────────────────────────────────────┘

Transaction Types:

 
 
Type Purpose Characteristics
Legacy Original transaction format Gas price, nonce, value
EIP-1559 Fee market reform Base fee + priority fee
EIP-2718 Typed transactions Versioned transaction envelope
EIP-2930 Access list Optimized for complex contracts
EIP-4844 Blob transaction Data availability for rollups

EIP-1559 Transaction Structure:

 
EIP-1559 Transaction:

┌─────────────────────────────────────────────────────────────────────┐
│                    EIP-1559 Transaction Fields                     │
│                                                                   │
│  To: 20 bytes                                                     │
│  Value: 256-bit unsigned                                          │
│  Data: Variable length                                            │
│  Nonce: 64-bit unsigned                                          │
│                                                                   │
│  Max Priority Fee Per Gas: Amount paid to validator              │
│  Max Fee Per Gas: Max total fee (base + priority)               │
│                                                                   │
│  Gas Limit: Max gas for this transaction                         │
│                                                                   │
│  Signature: (v, r, s)                                            │
│  Chain ID: 1 (Mainnet)                                           │
│                                                                   │
└─────────────────────────────────────────────────────────────────────┘

Fee Calculation:
Total Fee = Gas Used × (Base Fee + Priority Fee)

Base Fee: Burned (removed from circulation)
Priority Fee: Paid to validator (tip)

4.1.6: Gas – The Fuel of Ethereum

Gas System Deep-Dive:

Gas is the unit that measures the computational work required to execute operations on Ethereum.

 
Gas Mechanics:

┌─────────────────────────────────────────────────────────────────────┐
│                    Gas Mechanics                                   │
│                                                                   │
│  1. Gas Cost = Amount of gas consumed by operation               │
│                                                                   │
│  2. Gas Price = Amount of ETH per gas unit                       │
│                                                                   │
│  3. Gas Limit = Max gas user is willing to spend                 │
│                                                                   │
│  4. Transaction Fee = Gas Used × Gas Price                      │
│                                                                   │
│  5. Gas Refund = Unused gas refunded to user                    │
│                                                                   │
└─────────────────────────────────────────────────────────────────────┘

Gas Costs for Common Operations:

 
 
Operation Gas Cost Description
Add/Sub/Mul/Div 3-5 Arithmetic operations
Jump/Jumpi 8-10 Flow control
SLoad 2100 Read storage (warm)
SStore 100-20000 Write storage
SHA3 30 Hash computation
CREATE 32000 Contract creation
CALL 10000 Contract call
SELFDESTRUCT 5000 Self-destruct
LOG 375 Log emission

Gas Pricing (EIP-1559):

text
Base Fee:
- Determined by network demand
- Adjusted per block
- Burned (removed from supply)
- Target: 50% block utilization

Priority Fee:
- Optional tip to validators
- Increases inclusion priority
- Competitive market

Fee Calculation:
Total Fee = (Base Fee + Priority Fee) × Gas Used

Block Utilization:
- If >50%: Base fee increases
- If <50%: Base fee decreases
- Adjustment: 12.5% per block

Maximum Base Fee Change: 12.5% per block

Gas Refund Mechanism:

  • Refunds for clearing storage

  • Up to 50% of gas used

  • Encourages state cleanup

4.1.7: Ethereum Blocks

Block Structure:

text
Ethereum Block Structure:

┌─────────────────────────────────────────────────────────────────────┐
│                    Block Header                                    │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  Parent Hash (32 bytes): Previous block hash              │   │
│  │  Ommers Hash (32 bytes): Uncle blocks hash                │   │
│  │  Beneficiary (20 bytes): Miner/validator address          │   │
│  │  State Root (32 bytes): State trie root                  │   │
│  │  Transactions Root (32 bytes): Transaction trie root     │   │
│  │  Receipts Root (32 bytes): Receipt trie root             │   │
│  │  Logs Bloom (256 bytes): Event logs bloom filter         │   │
│  │  Difficulty (256 bits): Mining difficulty (pre-merge)    │   │
│  │  Number (64 bits): Block number                          │   │
│  │  Gas Limit (64 bits): Block gas limit                   │   │
│  │  Gas Used (64 bits): Gas consumed by block              │   │
│  │  Timestamp (64 bits): Block creation time               │   │
│  │  Extra Data (variable): Arbitrary data                  │   │
│  │  Mix Hash (32 bytes): PoW nonce proof (pre-merge)       │   │
│  │  Nonce (8 bytes): PoW nonce (pre-merge)                 │   │
│  │  Base Fee (256 bits): EIP-1559 base fee                 │   │
│  │  Withdrawals Root (32 bytes): Withdrawals root          │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                   │
│  Transactions List:                                               │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  Tx 1: Transaction data                                   │   │
│  │  Tx 2: Transaction data                                   │   │
│  │  ...                                                       │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                   │
│  Uncles List (ommers):                                            │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  Uncle block headers                                       │   │
│  │  (Pre-merge, now removed)                                  │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                   │
│  Withdrawals List (post-merge):                                   │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │  Withdrawal data for stakers                              │   │
│  └─────────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────────┘

Block Time and Finality:

 
 
Metric Value Description
Block Time ~12 seconds Time between blocks
Blocks per Day ~7200 Daily block production
Finality ~15 minutes Time to finality (~64 blocks)
Epoch Length 32 slots (~6.4 minutes) Voting period
Checkpoint Every epoch Finality checkpoints

4.1.8: Ethereum State

State Management:

Ethereum maintains three tries to store state:

 
State Tries:

┌─────────────────────────────────────────────────────────────────────┐
│                    State Tries                                     │
│                                                                   │
│  1. State Trie:                                                    │
│     • Stores account state                                       │
│     • Key: Address (160-bit)                                     │
│     • Value: Account (nonce, balance, storage root, code hash)   │
│     • Root hash in block header                                 │
│                                                                   │
│  2. Transaction Trie:                                             │
│     • Stores transactions                                        │
│     • Key: Transaction index                                     │
│     • Value: Transaction data                                    │
│     • Root hash in block header                                 │
│                                                                   │
│  3. Receipt Trie:                                                 │
│     • Stores transaction receipts                                │
│     • Key: Transaction index                                     │
│     • Value: Receipt data (status, logs, gas used)              │
│     • Root hash in block header                                 │
│                                                                   │
│  All tries use Merkle Patricia Trie (MPT)                        │
└─────────────────────────────────────────────────────────────────────┘

Merkle Patricia Trie (MPT):

MPT Structure:

┌─────────────────────────────────────────────────────────────────────┐
│                    MPT Structure                                   │
│                                                                   │
│  Nodes:                                                           │
│  1. Branch Node: Up to 16 children + value                       │
│  2. Extension Node: Common prefix + next node                    │
│  3. Leaf Node: Key suffix + value                                │
│  4. Null Node: Empty node (placeholder)                          │
│                                                                   │
│  Key Encoding:                                                    │
│  • Hex-prefix encoding                                           │
│  • Compact encoding                                               │
│  • Extended encoding                                             │
│                                                                   │
│  Benefits:                                                        │
│  • Efficient for sparse data                                     │
│  • Cryptographic proofs                                          │
│  • Versioning (historical state)                                │
│  • Verifiable state transitions                                 │
└─────────────────────────────────────────────────────────────────────┘

State Transition:

State Transition Function:

Y(S, T) = S'

Where:
- S: Previous state
- T: Transaction
- S': New state

Process:
1. Validate transaction
2. Execute transaction
3. Update state
4. Generate receipts
5. Update block header

State Root:
- Hash of state trie root
- Included in block header
- Represents entire state
- Enables light client verification

4.1.9: Ethereum Clients

Major Ethereum Clients:

 
 
Client Language Maintainer Features
Geth Go Ethereum Foundation Most popular, full node
Besu Java Hyperledger Enterprise, permissioned
Nethermind C# Nethermind Performance-oriented
Erigon Go Erigon Archive node optimized
Reth Rust Paradigm High performance

Node Types:

 
 
Type Storage Function Use Case
Archive Node Full history All historical states DApps, research
Full Node Recent history Validate blocks Validators, dApps
Light Node Headers only Verify with proofs Mobile wallets
Validator Node Full node + consensus Validate blocks Staking

4.1.10: Ethereum Improvement Proposals (EIPs)

EIP Process:

text
EIP Lifecycle:

1. Draft:
   - Idea proposal
   - Initial specification
   - Community discussion

2. Review:
   - Technical review
   - Security analysis
   - Implementation discussion

3. Last Call:
   - Final review period
   - Community feedback
   - Consensus building

4. Final:
   - Approved EIP
   - Ready for implementation
   - Activated on network

5. Core EIPs: Network upgrades
6. Standards EIPs: ERC standards
7. Networking EIPs: Protocol improvements

Important EIPs:

 
 
EIP Title Impact
EIP-20 ERC-20 Token Standard Fungible tokens
EIP-721 ERC-721 Token Standard NFTs
EIP-1155 ERC-1155 Multi-Token Multi-token standard
EIP-1559 Fee Market Change Gas fee reform
EIP-3675 Proof of Stake Merge consensus
EIP-4844 Proto-Danksharding Data availability

 

1. EVM Opcode Details

EVM Opcode Table (Selected):

0x00 STOP: Halt execution
0x01 ADD: Addition (a+b)
0x02 MUL: Multiplication (a*b)
0x03 SUB: Subtraction (a-b)
0x04 DIV: Integer division (a/b)
0x05 SDIV: Signed division (a/b)
0x06 MOD: Modulo (a%b)
0x07 SMOD: Signed modulo (a%b)
0x08 ADDMOD: Modulo addition (a+b)%N
0x09 MULMOD: Modulo multiplication (a*b)%N
0x0A EXP: Exponentiation (a^b)
0x10 LT: Less than (a<b)
0x11 GT: Greater than (a>b)
0x12 SLT: Signed less than (a<b)
0x13 SGT: Signed greater than (a>b)
0x14 EQ: Equality (a==b)
0x15 ISZERO: Is zero (a==0)
0x16 AND: Bitwise AND
0x17 OR: Bitwise OR
0x18 XOR: Bitwise XOR
0x19 NOT: Bitwise NOT
0x20 BYTE: Extract byte
0x30 ADDRESS: Get current address
0x31 BALANCE: Get address balance
0x32 ORIGIN: Get transaction origin
0x33 CALLER: Get caller address
0x34 CALLVALUE: Get transaction value
0x35 CALLDATALOAD: Load calldata
0x36 CALLDATASIZE: Get calldata size
0x37 CALLDATACOPY: Copy calldata to memory
0x38 CODESIZE: Get code size
0x39 CODECOPY: Copy code to memory
0x3A GASPRICE: Get gas price
0x3B EXTCODESIZE: Get external code size
0x3C EXTCODECOPY: Copy external code
0x3D RETURNDATASIZE: Get return data size
0x3E RETURNDATACOPY: Copy return data
0x3F EXTCODEHASH: Get external code hash

2. Gas Cost Details

 
Gas Cost Breakdown:

Basic Operations:
- ADD/SUB: 3
- MUL: 5
- DIV: 5
- SDIV: 5
- MOD: 5
- SMOD: 5
- EXP: 10 + 50 per byte
- LT/GT: 3
- EQ: 3
- AND/OR/XOR: 3

Memory Operations:
- MLOAD: 3
- MSTORE: 3
- MSTORE8: 3
- Memory expansion: 3 per word

Storage Operations:
- SLOAD: 100 (warm), 2100 (cold)
- SSTORE: 100-20000 (see rules)
- SSTORE refund: Up to 4800

Contract Operations:
- CREATE: 32000
- CALL: 10000
- STATICCALL: 10000
- DELEGATECALL: 10000
- SELFDESTRUCT: 5000
- LOG0: 375 + 375 per topic
- LOG1: 375 + 375 per topic
- LOG2: 375 + 375 per topic
- LOG3: 375 + 375 per topic
- LOG4: 375 + 375 per topic

3. Merkle Patricia Trie Details

text
MPT Node Types:

1. Branch Node:
   [ 16 children ] + [ value ]
   Children: 16 x 32 bytes
   Value: up to 32 bytes

2. Extension Node:
   [ key_prefix ] + [ next_node_hash ]
   Key prefix: variable length
   Next node: 32 bytes

3. Leaf Node:
   [ key_suffix ] + [ value ]
   Key suffix: variable length
   Value: up to 32 bytes

4. Null Node:
   Empty placeholder
   32 bytes of zeros

4. Ethereum Economics

Ethereum Supply:

Ether Unit:
1 Ether = 10^18 Wei
1 Wei = 1

Supply Metrics:
- Genesis: 72,009,990 ETH
- Current: ~120M ETH
- Annual Issuance: ~0.5-1%
- Max Supply: No hard cap
- Staking: ~30M ETH

Deflationary Mechanism:
- EIP-1559 base fee burn
- Reduced issuance (PoS)
- Net effect varies
- Possible deflation

Inflation Rate:
- Pre-Merge (PoW): ~4.5% annually
- Post-Merge (PoS): ~0.5% annually
- Post-Merge + Burn: Variable (0-0.5%)

 

MODULE 4: ETHEREUM AND SMART CONTRACT DEVELOPMENT (Continued)


 

Lesson 4.5: ERC Token Standards

Learning Objectives:

  • Master the ERC-20 fungible token standard

  • Understand ERC-721 and ERC-1155 for NFTs

  • Learn about other token standards (ERC-4626, ERC-777)

  • Analyze token economics and security


4.5.1: ERC-20 Token Standard

ERC-20 Overview:

ERC-20 is the most widely used token standard for fungible tokens on Ethereum.

text
ERC-20 Interface:

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

Complete ERC-20 Implementation:

text
ERC-20 Implementation:

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000000 * 10**decimals());
    }
    
    function decimals() public view virtual override returns (uint8) {
        return 18;  // Standard for most tokens
    }
}

ERC-20 with Minting and Burning:

text
Custom ERC-20:

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyToken is ERC20, ERC20Burnable, Ownable {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000000 * 10**decimals());
    }
    
    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
    
    function burn(uint256 amount) public {
        _burn(msg.sender, amount);
    }
}

ERC-20 with Pausable:

text
ERC-20 with Emergency Stop:

import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";

contract MyToken is ERC20, ERC20Pausable, Ownable {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000000 * 10**decimals());
    }
    
    function pause() public onlyOwner {
        _pause();
    }
    
    function unpause() public onlyOwner {
        _unpause();
    }
    
    function transfer(address recipient, uint256 amount) 
        public 
        override 
        whenNotPaused 
        returns (bool) 
    {
        return super.transfer(recipient, amount);
    }
}

4.5.2: ERC-721 (Non-Fungible Tokens)

ERC-721 Overview:

ERC-721 is the standard for non-fungible tokens (NFTs), where each token is unique.

text
ERC-721 Interface:

interface IERC721 {
    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function setApprovalForAll(address operator, bool approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    
    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);
}

Complete ERC-721 Implementation:

text
ERC-721 NFT Implementation:

import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    uint256 public tokenCounter;
    mapping(uint256 => string) private _tokenURIs;
    
    constructor() ERC721("MyNFT", "MNFT") {
        tokenCounter = 0;
    }
    
    function mint(address to, string memory uri) public onlyOwner {
        uint256 tokenId = tokenCounter;
        _safeMint(to, tokenId);
        _setTokenURI(tokenId, uri);
        tokenCounter++;
    }
    
    function tokenURI(uint256 tokenId) 
        public 
        view 
        override 
        returns (string memory) 
    {
        return super.tokenURI(tokenId);
    }
}

ERC-721 with Metadata:

text
NFT with On-Chain Metadata:

contract OnChainNFT is ERC721 {
    struct NFTMetadata {
        string name;
        string description;
        string image;
        uint256 attributes;
    }
    
    mapping(uint256 => NFTMetadata) public metadata;
    
    function mint(
        address to,
        uint256 tokenId,
        string memory name,
        string memory description,
        string memory image
    ) public {
        _safeMint(to, tokenId);
        metadata[tokenId] = NFTMetadata(name, description, image, 0);
    }
    
    function tokenURI(uint256 tokenId) 
        public 
        view 
        override 
        returns (string memory) 
    {
        NFTMetadata storage meta = metadata[tokenId];
        return string(
            abi.encodePacked(
                'data:application/json,{"name":"',
                meta.name,
                '","description":"',
                meta.description,
                '","image":"',
                meta.image,
                '"}'
            )
        );
    }
}

4.5.3: ERC-1155 (Multi-Token)

ERC-1155 Overview:

ERC-1155 supports both fungible and non-fungible tokens in a single contract.

text
ERC-1155 Interface:

interface IERC1155 {
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) 
        external view returns (uint256[] memory);
    function setApprovalForAll(address operator, bool approved) external;
    function isApprovedForAll(address account, address operator) external view returns (bool);
    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;
    
    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);
}

Complete ERC-1155 Implementation:

text
ERC-1155 Implementation:

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyMultiToken is ERC1155, Ownable {
    uint256 public constant GOLD = 0;
    uint256 public constant SILVER = 1;
    uint256 public constant WEAPON = 2;
    
    constructor() ERC1155("https://example.com/{id}.json") {
        _mint(msg.sender, GOLD, 1000, "");
        _mint(msg.sender, SILVER, 5000, "");
        _mint(msg.sender, WEAPON, 100, "");
    }
    
    function mint(address to, uint256 id, uint256 amount) public onlyOwner {
        _mint(to, id, amount, "");
    }
    
    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts) public onlyOwner {
        _mintBatch(to, ids, amounts, "");
    }
}

4.5.4: ERC-4626 (Tokenized Vaults)

ERC-4626 Overview:

ERC-4626 is a standard for yield-bearing vaults.

text
ERC-4626 Interface:

interface IERC4626 {
    function asset() external view returns (address);
    function totalAssets() external view returns (uint256);
    function convertToShares(uint256 assets) external view returns (uint256);
    function convertToAssets(uint256 shares) external view returns (uint256);
    function maxDeposit(address receiver) external view returns (uint256);
    function previewDeposit(uint256 assets) external view returns (uint256);
    function deposit(uint256 assets, address receiver) external returns (uint256);
    function maxMint(address receiver) external view returns (uint256);
    function previewMint(uint256 shares) external view returns (uint256);
    function mint(uint256 shares, address receiver) external returns (uint256);
    function maxWithdraw(address owner) external view returns (uint256);
    function previewWithdraw(uint256 assets) external view returns (uint256);
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256);
    function maxRedeem(address owner) external view returns (uint256);
    function previewRedeem(uint256 shares) external view returns (uint256);
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256);
    
    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);
}

4.5.5: Token Economics

Token Distribution:

text
Token Distribution Models:

1. Fair Launch:
   - No pre-mine
   - Equal opportunity
   - Community-driven

2. Private Sale:
   - Early investors
   - Discounts
   - Lock-up periods

3. Public Sale (ICO/IDO):
   - Public participation
   - Crowdfunding
   - Regulatory considerations

4. Airdrop:
   - Free distribution
   - Community building
   - Marketing

5. Staking Rewards:
   - Lock tokens
   - Earn yield
   - Long-term alignment

Token Economics Considerations:

text
Economic Design:

1. Supply:
   - Max supply: Hard cap
   - Circulating supply: Available
   - Total supply: Including locked

2. Distribution:
   - Team allocation
   - Investor allocation
   - Community allocation
   - Treasury allocation

3. Incentives:
   - Staking rewards
   - Liquidity mining
   - Governance participation

4. Utility:
   - Governance rights
   - Fee reduction
   - Access to services
   - Voting power

5. Value Accrual:
   - Fee sharing
   - Buyback and burn
   - Revenue distribution

4.5.6: Token Security

Token Security Considerations:

text
Token Security Checklist:

☐ Reentrancy protection
☐ Access control
☐ Overflow protection
☐ Pausable for emergencies
☐ Upgrade path (if needed)
☐ Audit completed
☐ Bug bounty active
☐ Test coverage > 95%
☐ Documentation complete
☐ Emergency withdrawal

ADDITIONAL DEEP TECHNICAL NOTES:

1. Token Standards Comparison

 
 
Standard Type Use Cases Key Features
ERC-20 Fungible Cryptocurrencies, governance Transfer, approval, allowance
ERC-721 Non-fungible NFTs, digital art Unique IDs, ownership
ERC-1155 Multi-token Gaming, collectibles Batch transfers, gas efficient
ERC-4626 Vault Yield-bearing assets Deposit, withdraw
ERC-777 Enhanced ERC-20 Advanced tokens Hooks, improved security
ERC-3643 Security Token Regulated tokens Compliance, KYC

2. Token Implementation Tips

text
Best Practices:

1. Use OpenZeppelin libraries
2. Implement proper error handling
3. Add events for all important actions
4. Consider upgradeability
5. Add pause functionality
6. Multiple independent audits
7. Limit admin privileges
8. Use timelocks for sensitive operations
9. Monitor for suspicious activity
10. Regular security updates

Lesson 4.6: Web3 Development and dApps

Learning Objectives:

  • Understand Web3 architecture and tools

  • Master frontend interaction with smart contracts

  • Learn about wallets and providers

  • Build complete dApp workflows


4.6.1: Web3 Architecture

Web3 Stack:

text
Web3 Architecture:

┌─────────────────────────────────────────────────────────────────────┐
│                    Frontend (UI/UX)                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  React/Vue  │  │  Web3.js    │  │  Ethers.js  │              │
│  │  Components │  │  Library    │  │  Library    │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Wallet/Provider Layer                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  MetaMask   │  │  WalletConnect│ │  Coinbase   │              │
│  │             │  │             │  │  Wallet     │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    RPC Layer                                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Infura     │  │  Alchemy    │  │  QuickNode  │              │
│  │  (RPC)      │  │  (RPC)      │  │  (RPC)      │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────────────────────────────────────────────┐
│                    Blockchain Layer                                │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │  Ethereum   │  │  Polygon    │  │  Arbitrum   │              │
│  │  Mainnet    │  │             │  │             │              │
│  └─────────────┘  └─────────────┘  └─────────────┘              │
└─────────────────────────────────────────────────────────────────────┘

4.6.2: Web3.js/Ethers.js Fundamentals

Ethers.js Setup:

text
Ethers.js Installation:

npm install ethers

// Import
const { ethers } = require('ethers');
// Or
import { ethers } from 'ethers';

Connecting to a Provider:

text
Provider Connection:

// Using a local node
const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545');

// Using a public RPC
const provider = new ethers.providers.InfuraProvider('mainnet', INFURA_KEY);
const provider = new ethers.providers.AlchemyProvider('mainnet', ALCHEMY_KEY);

// MetaMask provider
const provider = new ethers.providers.Web3Provider(window.ethereum);

// Get signer
const signer = provider.getSigner();

Reading Contract Data:

text
Reading from a Contract:

// Contract ABI and address
const abi = [...] // Contract ABI
const address = '0x...'

// Create contract instance
const contract = new ethers.Contract(address, abi, provider);

// Read functions
const balance = await contract.balanceOf('0x...');
const totalSupply = await contract.totalSupply();

// View functions with parameters
const allowance = await contract.allowance(owner, spender);

Writing to a Contract:

text
Writing to a Contract:

// With signer
const contractWithSigner = contract.connect(signer);

// Send transaction
const tx = await contractWithSigner.transfer(to, amount);

// Wait for confirmation
const receipt = await tx.wait();

// Check transaction status
if (receipt.status === 1) {
    console.log('Transaction successful');
} else {
    console.log('Transaction failed');
}

4.6.3: Smart Contract Interaction Example

Complete Contract Interaction:

text
Ethers.js Complete Example:

import { ethers } from 'ethers';

class TokenClient {
    constructor(contractAddress, abi) {
        this.provider = new ethers.providers.Web3Provider(window.ethereum);
        this.signer = this.provider.getSigner();
        this.contract = new ethers.Contract(contractAddress, abi, this.provider);
        this.contractWithSigner = this.contract.connect(this.signer);
    }
    
    async connectWallet() {
        await window.ethereum.request({ method: 'eth_requestAccounts' });
    }
    
    async getBalance(address) {
        return await this.contract.balanceOf(address);
    }
    
    async transfer(to, amount) {
        const tx = await this.contractWithSigner.transfer(to, amount);
        const receipt = await tx.wait();
        return receipt;
    }
    
    async getTransactionReceipt(txHash) {
        return await this.provider.getTransactionReceipt(txHash);
    }
    
    async listenForEvents() {
        this.contract.on('Transfer', (from, to, value) => {
            console.log(`Transfer: ${from} -> ${to} (${value})`);
        });
    }
}

4.6.4: Wallets and Authentication

Connecting to MetaMask:

text
MetaMask Connection:

const connectWallet = async () => {
    try {
        // Check if MetaMask is installed
        if (typeof window.ethereum === 'undefined') {
            throw new Error('MetaMask not installed');
        }
        
        // Request accounts
        const accounts = await window.ethereum.request({
            method: 'eth_requestAccounts'
        });
        
        // Get connected account
        const account = accounts[0];
        console.log('Connected:', account);
        
        // Get network
        const chainId = await window.ethereum.request({
            method: 'eth_chainId'
        });
        console.log('Chain ID:', chainId);
        
        return { account, chainId };
    } catch (error) {
        console.error('Connection error:', error);
    }
};

// Listen for account changes
window.ethereum.on('accountsChanged', (accounts) => {
    console.log('Account changed:', accounts[0]);
});

// Listen for chain changes
window.ethereum.on('chainChanged', (chainId) => {
    console.log('Chain changed:', chainId);
});

4.6.5: Complete dApp Example

React dApp Example:

javascript
import React, { useState, useEffect } from 'react';
import { ethers } from 'ethers';
import { ContractABI } from './ContractABI';

function App() {
    const [account, setAccount] = useState(null);
    const [balance, setBalance] = useState('0');
    const [loading, setLoading] = useState(false);
    const [contract, setContract] = useState(null);
    
    const CONTRACT_ADDRESS = '0x...';
    
    useEffect(() => {
        init();
    }, []);
    
    const init = async () => {
        if (typeof window.ethereum !== 'undefined') {
            const provider = new ethers.providers.Web3Provider(window.ethereum);
            const signer = provider.getSigner();
            const contract = new ethers.Contract(CONTRACT_ADDRESS, ContractABI, signer);
            setContract(contract);
        }
    };
    
    const connectWallet = async () => {
        try {
            const accounts = await window.ethereum.request({
                method: 'eth_requestAccounts'
            });
            setAccount(accounts[0]);
            await updateBalance(accounts[0]);
        } catch (error) {
            console.error('Connection error:', error);
        }
    };
    
    const updateBalance = async (address) => {
        if (contract) {
            const balance = await contract.balanceOf(address);
            setBalance(ethers.utils.formatEther(balance));
        }
    };
    
    const transfer = async () => {
        if (!contract) return;
        setLoading(true);
        
        try {
            const tx = await contract.transfer(toAddress, amount);
            await tx.wait();
            await updateBalance(account);
        } catch (error) {
            console.error('Transfer error:', error);
        }
        
        setLoading(false);
    };
    
    return (
        <div>
            {!account ? (
                <button onClick={connectWallet}>Connect Wallet</button>
            ) : (
                <div>
                    <p>Connected: {account}</p>
                    <p>Balance: {balance} ETH</p>
                    <button onClick={transfer} disabled={loading}>
                        {loading ? 'Processing...' : 'Transfer'}
                    </button>
                </div>
            )}
        </div>
    );
}

4.6.6: Gas Optimization in dApps

Gas Estimation:

text
Gas Estimation:

// Estimate gas
const gasEstimate = await contract.estimateGas.transfer(to, amount);

// Get gas price
const gasPrice = await provider.getGasPrice();

// Calculate total cost
const totalCost = gasEstimate.mul(gasPrice);
console.log('Estimated cost:', ethers.utils.formatEther(totalCost), 'ETH');

// Send with custom gas
const tx = await contractWithSigner.transfer(to, amount, {
    gasLimit: gasEstimate.mul(1.1),
    gasPrice: gasPrice
});

Batching Transactions:

text
Transaction Batching:

// Batch multiple transfers
const batchTransfer = async (recipients, amounts) => {
    const tx = await contract.batchTransfer(recipients, amounts);
    await tx.wait();
};

// EIP-2718: Typed transactions
// EIP-1559: Dynamic fee market

ADDITIONAL DEEP TECHNICAL NOTES:

1. Web3 Provider Comparison

 
 
Provider Pros Cons Use Case
MetaMask Popular, user-friendly Browser-dependent General dApps
WalletConnect Mobile support QR codes Mobile dApps
Infura Reliable, easy Rate limited Server-side
Alchemy Fast, feature-rich Cost Production dApps
Local Node Full control Maintenance Development

2. Error Handling

text
Error Handling Patterns:

try {
    const tx = await contract.function();
    await tx.wait();
} catch (error) {
    // Check for user rejection
    if (error.code === 4001) {
        console.log('Transaction rejected by user');
    }
    
    // Check for network error
    if (error.code === -32000) {
        console.log('Network error:', error.message);
    }
    
    // Check for contract revert
    if (error.reason) {
        console.log('Revert reason:', error.reason);
    }
    
    // Generic error
    console.error('Error:', error.message);
}

Lesson 4.7: Testing and Deployment

Learning Objectives:

  • Master smart contract testing strategies

  • Understand deployment pipelines and tools

  • Learn about mainnet deployment and verification


4.7.1: Testing Frameworks

Hardhat Testing:

text
Hardhat Test Setup:

// test/MyContract.test.js
const { expect } = require('chai');
const { ethers } = require('hardhat');

describe('MyContract', function () {
    let MyContract;
    let myContract;
    let owner;
    let addr1;
    let addr2;
    
    beforeEach(async function () {
        [owner, addr1, addr2] = await ethers.getSigners();
        MyContract = await ethers.getContractFactory('MyContract');
        myContract = await MyContract.deploy();
        await myContract.deployed();
    });
    
    describe('Deployment', function () {
        it('Should set the right owner', async function () {
            expect(await myContract.owner()).to.equal(owner.address);
        });
    });
    
    describe('Functions', function () {
        it('Should allow owner to set value', async function () {
            await myContract.setValue(42);
            expect(await myContract.value()).to.equal(42);
        });
        
        it('Should not allow non-owner to set value', async function () {
            await expect(myContract.connect(addr1).setValue(42))
                .to.be.revertedWith('Not owner');
        });
    });
});

Foundry Testing:

text
Foundry Test Setup:

// test/MyContract.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";
import "../src/MyContract.sol";

contract MyContractTest is Test {
    MyContract public myContract;
    address public owner;
    address public addr1;
    
    function setUp() public {
        owner = address(this);
        addr1 = makeAddr("addr1");
        myContract = new MyContract();
    }
    
    function testDeployment() public {
        assertEq(myContract.owner(), owner);
    }
    
    function testSetValue() public {
        myContract.setValue(42);
        assertEq(myContract.value(), 42);
    }
    
    function testFuzzValue(uint256 value) public {
        myContract.setValue(value);
        assertEq(myContract.value(), value);
    }
}

4.7.2: Deployment Workflow

Hardhat Deployment:

text
Hardhat Deploy Script:

// scripts/deploy.js
const hre = require('hardhat');

async function main() {
    // Get deployer
    const [deployer] = await hre.ethers.getSigners();
    console.log('Deploying with:', deployer.address);
    
    // Deploy contract
    const MyContract = await hre.ethers.getContractFactory('MyContract');
    const myContract = await MyContract.deploy();
    await myContract.deployed();
    
    console.log('MyContract deployed to:', myContract.address);
    
    // Verify on Etherscan (if on mainnet)
    if (hre.network.name === 'mainnet') {
        await hre.run('verify:verify', {
            address: myContract.address,
            constructorArguments: [],
        });
    }
}

main()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

Network Configuration:

text
Hardhat Config:

// hardhat.config.js
require('@nomiclabs/hardhat-waffle');
require('@nomiclabs/hardhat-etherscan');
require('hardhat-deploy');

module.exports = {
    solidity: '0.8.20',
    networks: {
        hardhat: {
            chainId: 1337
        },
        localhost: {
            url: 'http://127.0.0.1:8545'
        },
        goerli: {
            url: process.env.GOERLI_RPC_URL,
            accounts: [process.env.PRIVATE_KEY]
        },
        mainnet: {
            url: process.env.MAINNET_RPC_URL,
            accounts: [process.env.PRIVATE_KEY]
        }
    },
    etherscan: {
        apiKey: process.env.ETHERSCAN_API_KEY
    }
};

4.7.3: Contract Verification

Etherscan Verification:

text
Verification Process:

1. Flatten the contract
2. Upload to Etherscan
3. Verify on-chain code matches

// Hardhat verification
npx hardhat verify --network mainnet 0x123... "constructor args"

// Using Etherscan API
npx hardhat run scripts/verify.js

// Manual verification
// 1. Go to Etherscan
// 2. Click "Verify and Publish"
// 3. Paste flattened code
// 4. Submit

4.7.4: Upgradeable Contracts

Proxy Deployment:

text
Proxy Deployment Pattern:

// Deploy implementation
const Implementation = await ethers.getContractFactory('Implementation');
const implementation = await Implementation.deploy();
await implementation.deployed();

// Deploy proxy
const Proxy = await ethers.getContractFactory('Proxy');
const proxy = await Proxy.deploy(implementation.address);
await proxy.deployed();

// Interact via proxy
const proxyContract = Implementation.attach(proxy.address);

OpenZeppelin Upgrades:

text
Using OpenZeppelin Upgrades:

const { upgrades } = require('hardhat');

// Deploy upgradeable contract
const MyContract = await ethers.getContractFactory('MyContract');
const myContract = await upgrades.deployProxy(MyContract, []);
await myContract.deployed();

// Upgrade contract
const MyContractV2 = await ethers.getContractFactory('MyContractV2');
const upgraded = await upgrades.upgradeProxy(myContract.address, MyContractV2);

4.7.5: Testing Best Practices

Test Coverage:

text
Test Coverage Requirements:

1. Positive Tests:
   - Normal operation
   - Expected outcomes

2. Negative Tests:
   - Revert conditions
   - Edge cases

3. Edge Cases:
   - Zero values
   - Maximum values
   - Boundary conditions

4. Security Tests:
   - Reentrancy
   - Access control
   - Overflow/Underflow

5. Integration Tests:
   - Contract interactions
   - Multiple contracts
   - External calls

ADDITIONAL DEEP TECHNICAL NOTES:

1. Deployment Checklist

text
Pre-Deployment Checklist:

☐ All tests passing
☐ Test coverage > 95%
☐ Security audit completed
☐ Contract verified on testnet
☐ Gas optimization done
☐ Documentation complete
☐ Upgrade path planned
☐ Emergency procedures documented
☐ Monitoring setup configured
☐ Bug bounty program ready

☐ Dry run on testnet
☐ Gradual deployment on mainnet
☐ Monitor for issues
☐ Backup plan prepared

2. Monitoring and Maintenance

text
Post-Deployment:

1. Transaction Monitoring:
   - Failed transactions
   - Suspicious activity
   - Gas price spikes

2. Contract Monitoring:
   - State changes
   - Events
   - Balance changes

3. Security Monitoring:
   - Attack attempts
   - Unusual patterns
   - Vulnerability alerts

4. Performance Monitoring:
   - Gas costs
   - Response times
   - Network congestion

Lesson 4.8: Gas Optimization and Auditing

Learning Objectives:

  • Master gas optimization techniques

  • Understand auditing processes and tools

  • Learn about security best practices

  • Analyze common vulnerabilities and fixes


4.8.1: Gas Optimization Techniques

Storage Optimization:

text
Storage Optimization Patterns:

1. Pack Variables:
// Bad: 3 slots
uint256 a;  // Slot 0
uint256 b;  // Slot 1
uint256 c;  // Slot 2

// Good: 2 slots
uint128 a;  // Slot 0 (16 bytes)
uint128 b;  // Slot 0 (16 bytes)
uint256 c;  // Slot 1

2. Use uint256 for operations:
// Bad: Requires conversions
uint8 a = 10;
uint8 b = 20;
uint256 result = a + b;  // Conversion overhead

// Good: Use same type
uint256 a = 10;
uint256 b = 20;
uint256 result = a + b;

Function Optimization:

text
Function Optimization:

1. Use external for read-only:
function externalRead() external view returns (uint256) {
    // Cheaper than public
}

2. Use calldata for read-only inputs:
function processData(bytes calldata data) public {
    // Cheaper than memory
}

3. Use view/pure modifiers:
function getValue() public view returns (uint256) {
    // No gas for reading
}

4. Avoid unnecessary storage reads:
uint256 temp = value;  // Read once
// Use temp multiple times

Loop Optimization:

text
Loop Optimization:

1. Cache loop bounds:
uint256 length = array.length;
for (uint256 i = 0; i < length; i++) {
    // Use length
}

2. Use unchecked for safe increments:
for (uint256 i = 0; i < length; ) {
    // Body
    unchecked { i++; }
}

3. Avoid dynamic array inside loops:
// Bad: Dynamic array in loop
for (uint256 i = 0; i < array.length; i++) {
    uint256 temp = array[i];  // Re-reads length
}

// Good: Cache array element
for (uint256 i = 0; i < length; i++) {
    uint256 temp = array[i];  // Only reads once
}

Assembly Optimization:

text
Assembly Optimization:

assembly {
    // Packed storage
    let slot := sload(0x00)  // Read 256 bits
    
    // Extract values
    let a := and(slot, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)  // Lower 128 bits
    let b := shr(128, slot)  // Upper 128 bits
    
    // Pack and store
    let packed := or(a, shl(128, b))
    sstore(0x00, packed)
}

4.8.2: Audit Process

Audit Stages:

text
Comprehensive Audit Process:

1. Pre-Audit Preparation:
   - Code documentation
   - Architecture overview
   - Security assumptions

2. Manual Code Review:
   - Logic analysis
   - Security patterns
   - Access control
   - Business logic

3. Automated Analysis:
   - Static analysis (Slither)
   - Security scanning (Mythril)
   - Formal verification

4. Security Testing:
   - Unit tests
   - Fuzzing
   - Penetration testing

5. Reporting:
   - Vulnerability classification
   - Risk assessment
   - Recommendations
   - Remediation validation

4.8.3: Common Vulnerabilities and Fixes

Vulnerability Matrix:

 
 
Vulnerability Severity Prevention
Reentrancy Critical Checks-effects-interactions
Access Control Critical Role-based access
Integer Overflow High SafeMath (pre-0.8.0)
Front-Running Medium Commit-reveal
Denial of Service High Avoid unbounded loops
Oracle Manipulation High Multiple oracles
Logic Errors Critical Comprehensive testing
Gas Limit Medium Optimization

4.8.4: Security Tools Guide

Slither Configuration:

text
Slither Analysis:

# Install
pip3 install slither-analyzer

# Basic analysis
slither contracts/

# Detailed report
slither contracts/ --print human-summary

# Security checks
slither contracts/ --detect-all

# Custom detectors
slither contracts/ --detect reentrancy,unchecked-call

Mythril Analysis:

text
Mythril Scanning:

# Install
pip3 install mythril

# Scan contract
myth analyze 0x123... --solv 0.8.0

# Full analysis
myth analyze contracts/ --all

# Gas analysis
myth analyze contracts/ --gas

4.8.5: Security Best Practices

Development Best Practices:

text
Security Best Practices:

1. Use Battle-Tested Libraries:
   - OpenZeppelin contracts
   - Chainlink oracles
   - Standard patterns

2. Follow Checks-Effects-Interactions:
   - Validate inputs first
   - Update state
   - Make external calls

3. Implement Access Control:
   - Ownable for simple
   - AccessControl for complex
   - Role-based permissions

4. Add Emergency Features:
   - Pausable
   - Emergency withdraw
   - Upgrade path

5. Use SafeMath:
   - Pre-0.8.0: Use SafeMath
   - 0.8.0+: Automatic checks
   - Use unchecked for optimization

6. Implement Circuit Breakers:
   - Limit exposure
   - Gradual deployment
   - Monitoring alerts

7. Use Multi-Sig:
   - Critical functions
   - Admin privileges
   - Fund management

8. Regular Security Audits:
   - Multiple firms
   - Independent review
   - Continuous monitoring

ADDITIONAL DEEP TECHNICAL NOTES:

1. Gas Optimization Summary

text
Gas Cost Comparison:

| Operation | Gas Cost | Optimization |
|-----------|----------|--------------|
| Storage Write | 20,000 | Cache, pack |
| Storage Read | 2,100 | Cache, reduce |
| Memory Write | 3 | Use memory |
| Memory Read | 3 | Use memory |
| External Call | 10,000 | Reduce calls |
| Internal Call | ~50 | Use internal |
| Arithmetic | 3-5 | Use unchecked |
| Loop | Variable | Limit length |

2. Audit Report Format

text
Audit Report Structure:

1. Executive Summary:
   - Overall findings
   - Risk level
   - Recommendation

2. Detailed Findings:
   - Vulnerability description
   - Code location
   - Impact assessment
   - Recommended fix

3. Code Quality:
   - Code quality assessment
   - Maintainability
   - Best practices

4. Test Coverage:
   - Coverage percentage
   - Missing tests
   - Recommendations

5. Gas Analysis:
   - Gas usage
   - Optimization opportunities
   - Cost estimates

6. Final Recommendations:
   - Prioritized fixes
   - Timeline
   - Validation process

MODULE 4 SUMMARY COMPLETE

You now have comprehensive notes for Module 4: Ethereum and Smart Contract Development covering all 8 lessons:

Lesson 4.1: Ethereum Architecture and the EVM

  • Ethereum overview and history

  • EVM architecture and opcodes

  • Account model and transactions

  • Gas system and blocks

  • State management and clients

Lesson 4.2: Solidity Smart Contract Fundamentals

  • Language basics and syntax

  • Data types and variables

  • Functions and modifiers

  • Error handling and events

Lesson 4.3: Advanced Solidity Concepts

  • Advanced data structures

  • Function overloading

  • Fallback/receive functions

  • Contract interactions

  • Factories and proxies

  • Upgrade patterns

Lesson 4.4: Smart Contract Security

  • Common vulnerabilities

  • Reentrancy attacks

  • Access control

  • Front-running prevention

  • DoS protection

  • Oracle security

  • Flash loan protection

Lesson 4.5: ERC Token Standards

  • ERC-20 fungible tokens

  • ERC-721 NFTs

  • ERC-1155 multi-tokens

  • ERC-4626 vaults

  • Token economics

Lesson 4.6: Web3 Development and dApps

  • Web3 architecture

  • Ethers.js fundamentals

  • Contract interaction

  • Wallet integration

  • Complete dApp example

Lesson 4.7: Testing and Deployment

  • Testing frameworks (Hardhat, Foundry)

  • Deployment workflow

  • Contract verification

  • Upgradeable contracts

  • Best practices

Lesson 4.8: Gas Optimization and Auditing

  • Gas optimization techniques

  • Audit process

  • Common vulnerabilities

  • Security tools

  • Best practices


Ready to continue with Module 5? Module 5 covers DeFi (Decentralized Finance) Protocols and Applications. Please let me know when you’re ready!

This response is AI-generated, for reference only.