Chapter 34: Exercises
Blockchain Fundamentals for Prediction Markets
Exercise 1: Block Hash Verification
Write a Python function using web3.py that takes a block number and verifies that the block's parentHash field matches the hash of the previous block. Connect to any Ethereum-compatible chain (you may use a public RPC endpoint). Print both hashes and confirm they match.
Difficulty: Easy
Exercise 2: Chain Integrity Check
Extend Exercise 1 to check a range of consecutive blocks (e.g., 10 blocks). Verify the parent hash chain for each pair of adjacent blocks. Report any breaks in the chain (there should be none on a healthy chain).
Difficulty: Easy
Exercise 3: Gas Price Analysis
Write a script that queries the last 100 blocks on Ethereum mainnet and computes: - The average base fee per gas - The minimum and maximum base fee - The standard deviation of base fees - The median base fee
Plot the base fee over time using matplotlib.
Difficulty: Easy
Exercise 4: ERC-20 Token Explorer
Write a Python class TokenExplorer that, given a token contract address and an Ethereum-compatible RPC URL, can:
- Return the token's name, symbol, decimals, and total supply
- Check the balance of any address
- List the last N transfer events
Test it with USDC on Ethereum mainnet (0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48).
Difficulty: Easy
Exercise 5: Account Nonce Tracker
Write a function that takes an Ethereum address and returns its current nonce (transaction count). Then, fetch the last 5 transactions sent from that address using event logs or transaction scanning. Explain what the nonce represents and why it matters for transaction ordering.
Difficulty: Easy
Exercise 6: Wallet Generator
Write a Python script that generates 5 Ethereum wallets (address and private key pairs) using the eth_account library. For each wallet:
- Print the address
- Print the private key (in a real application, you would store these securely)
- Verify that the address can be derived from the private key
Difficulty: Easy
Exercise 7: Unit Conversion Utility
Write a utility class EthUnits that converts between wei, gwei, finney, and ether. Include the following methods:
- wei_to_ether(wei)
- ether_to_wei(ether)
- gwei_to_ether(gwei)
- ether_to_gwei(ether)
- format_value(wei) that returns a human-readable string (e.g., "1.5 ETH" or "50 gwei")
Difficulty: Easy
Exercise 8: Transaction Cost Calculator
Write a function that estimates the cost of a prediction market transaction in USD, given: - Gas units consumed - Base fee (in gwei) - Priority fee (in gwei) - ETH price in USD
Calculate the cost for the following scenarios: - Simple token transfer: 65,000 gas - Market bet placement: 200,000 gas - Market creation: 1,500,000 gas - Market settlement: 500,000 gas
Use a base fee of 25 gwei, priority fee of 2 gwei, and ETH price of $3,000.
Difficulty: Easy
Exercise 9: Block Time Analysis
Query the last 1,000 blocks on Polygon and compute: - Average block time (seconds between consecutive blocks) - Distribution of block times - The longest and shortest gaps between blocks
Compare this with Ethereum mainnet's block time. Discuss the implications for prediction market user experience.
Difficulty: Medium
Exercise 10: Merkle Proof Simulator
Implement a simple Merkle tree in Python. Given a list of transactions (strings), build the tree by hashing pairs of nodes up to the root. Then implement a function that generates a Merkle proof for a given transaction and a function that verifies the proof against the root hash. Use SHA-256 as the hash function.
Difficulty: Medium
Exercise 11: Multi-Chain Connection Manager
Write a Python class ChainManager that manages connections to multiple chains (Ethereum, Polygon, Arbitrum, Optimism, Base). The class should:
- Accept a dictionary of chain names to RPC URLs
- Provide a method to get the latest block number on each chain
- Provide a method to check the connection health of each chain
- Provide a method to get the native token balance of an address on each chain
Difficulty: Medium
Exercise 12: Event Decoder
Write a Python function that takes raw event log data (from w3.eth.get_logs()) and an event ABI definition, and decodes the log into a human-readable dictionary. Handle both indexed and non-indexed parameters. Test with Transfer events from an ERC-20 contract.
Difficulty: Medium
Exercise 13: Gas Estimator
Write a function that estimates the gas required for a contract function call using w3.eth.estimate_gas(). Create a wrapper that:
- Estimates gas for a given function call
- Adds a safety margin (e.g., 20%)
- Calculates the estimated cost in ETH and USD
- Handles estimation failures gracefully
Test with read and write operations on a public contract.
Difficulty: Medium
Exercise 14: Transaction Receipt Analyzer
Write a Python function analyze_receipt(receipt) that takes a transaction receipt and extracts:
- Whether the transaction succeeded or failed
- Gas used vs. gas limit (efficiency percentage)
- Number of events emitted
- Contract address (if it was a contract deployment)
- Total cost in ETH
Apply this to 10 different transactions and present the results in a formatted table.
Difficulty: Medium
Exercise 15: Token Approval Manager
Write a Python class ApprovalManager that can:
- Check the current approval amount for a given token, owner, and spender
- Approve a specific amount (not unlimited)
- Revoke an approval (set to 0)
- List all known approvals for an address (given a list of token contracts to check)
Include a safety check that warns if an approval exceeds a configurable threshold.
Difficulty: Medium
Exercise 16: Simple Prediction Market Simulator
Without connecting to a real blockchain, simulate a prediction market smart contract in Python. Implement:
- create_market(question, outcomes) - creates a new market
- buy_shares(market_id, outcome, amount) - buys outcome shares
- resolve_market(market_id, winning_outcome) - resolves the market
- claim_payout(market_id, user) - calculates and returns payout
Use the same logic as the SimpleBet contract from Section 34.4, but in pure Python. Track all state in dictionaries.
Difficulty: Medium
Exercise 17: Block Explorer CLI
Build a command-line block explorer that accepts commands:
- block <number> - shows block details
- tx <hash> - shows transaction details
- address <addr> - shows address balance and transaction count
- token <addr> <wallet> - shows ERC-20 token balance
Use argparse for command-line argument parsing and web3.py for blockchain queries.
Difficulty: Medium
Exercise 18: Transaction Monitor
Write a Python script that monitors pending transactions for a given address. Use the pending block filter or poll for new transactions. When a new transaction is detected:
- Print the transaction details
- Track time until confirmation
- Report final gas used
Run this on a testnet and send a test transaction to observe the lifecycle.
Difficulty: Medium
Exercise 19: Historical Gas Price Oracle
Write a Python class that provides historical gas price recommendations based on recent blocks. The class should: - Sample gas prices from the last N blocks - Calculate percentiles (25th, 50th, 75th, 90th) - Recommend a gas price for "slow" (25th percentile), "standard" (50th), "fast" (75th), and "instant" (90th) speed tiers - Cache results for a configurable TTL (time-to-live)
Difficulty: Medium
Exercise 20: Smart Contract Event Aggregator
Write a script that aggregates Transfer events from a specific ERC-20 token over a time period. Compute: - Total number of transfers - Total value transferred - Unique senders and receivers - Largest single transfer - Most active sender and receiver - Transfer volume by hour of day
Difficulty: Medium
Exercise 21: ABI Encoder/Decoder
Write Python functions that manually encode and decode ABI-formatted function calls, without using web3.py's built-in ABI encoding. Implement:
- Computing the function selector (first 4 bytes of keccak256 of the function signature)
- Encoding uint256, address, bool, and string parameters
- Decoding return values
Verify your results against web3.py's encode_abi and decode_abi.
Difficulty: Hard
Exercise 22: Reentrancy Detector
Write a Python analysis tool that reads a Solidity smart contract source file and flags potential reentrancy vulnerabilities. Check for:
- External calls (.call, .transfer, .send) followed by state changes
- State changes that should occur before external calls
- Use of the Checks-Effects-Interactions pattern
This is a simplified static analysis; it does not need to be comprehensive.
Difficulty: Hard
Exercise 23: Multi-Outcome Market Token Tracker
Write a Python class that tracks ERC-1155 token balances for a multi-outcome prediction market. Given a Conditional Token Framework (CTF) contract address: - Track balances for multiple outcome tokens - Calculate the implied probability for each outcome based on token prices - Monitor changes in the token distribution over time - Alert when the implied probability crosses configurable thresholds
Difficulty: Hard
Exercise 24: Layer 2 Cost Comparator
Write a script that queries the current transaction costs on Ethereum L1, Polygon, Arbitrum, Optimism, and Base. For each chain: - Get the current gas price or base fee - Estimate the cost of a standard swap transaction (150,000 gas) - Convert costs to USD using a price feed - Present results in a comparison table - Calculate the savings ratio (L1 cost / L2 cost)
Difficulty: Hard
Exercise 25: Deterministic Address Calculator
Implement the algorithm for computing the deployment address of a smart contract from the deployer's address and nonce, and for CREATE2 (which uses a salt and init code hash). Write functions:
- compute_create_address(deployer, nonce) using RLP encoding and keccak256
- compute_create2_address(deployer, salt, init_code_hash) per EIP-1014
Verify your implementations against known contract addresses.
Difficulty: Hard
Exercise 26: Transaction Simulation Engine
Build a Python class that simulates Ethereum transactions using eth_call before submitting them. The class should:
- Accept a transaction dictionary
- Simulate execution using eth_call
- Decode revert reasons from failed simulations
- Estimate gas usage
- Return a detailed simulation report
- Only submit the actual transaction if simulation succeeds
Difficulty: Hard
Exercise 27: On-Chain Prediction Market Dashboard
Build a data pipeline that reads on-chain prediction market data and computes: - Active markets count - Total value locked (TVL) - 24-hour trading volume (from Transfer events) - Top markets by volume - Price history for a specific market (from trade events)
Output the results as a formatted report. Use Polygon and target Polymarket's contract addresses (you may use simplified mock data if live contract ABIs are unavailable).
Difficulty: Hard
Exercise 28: MEV Protection Wrapper
Write a Python wrapper for sending transactions that implements basic MEV protection: - Simulate the transaction first to check for sandwich attack vulnerability - Set a maximum slippage tolerance - Use a private mempool endpoint (e.g., Flashbots) if available - Implement deadline-based transaction expiry - Log all protection checks performed
Difficulty: Hard
Exercise 29: Cross-Chain Balance Aggregator
Write a Python tool that, given an Ethereum address and a list of token addresses, queries the user's balances across multiple chains (Ethereum, Polygon, Arbitrum, Optimism, Base). Aggregate the results into a portfolio view showing: - Token balances per chain - Total value per token (across all chains) - Portfolio allocation percentages
Use concurrent connections (asyncio or threading) for performance.
Difficulty: Hard
Exercise 30: Full Transaction Lifecycle Logger
Build a comprehensive transaction logger that tracks every stage of a transaction's lifecycle: 1. Transaction construction (parameters, estimated gas) 2. Signing (signature components v, r, s) 3. Broadcasting (timestamp, initial response) 4. Mempool status (check if pending) 5. Block inclusion (block number, position in block) 6. Confirmation depth (track additional blocks) 7. Final status (success/revert, gas used, events emitted)
Log all information to a structured JSON file. Test on a testnet.
Difficulty: Hard