Appendix B: Python Environment Setup
This appendix walks you through setting up a complete Python development environment for the code exercises, simulations, and data analysis tasks throughout this textbook. By the end, you will have Python 3.10+, a dedicated virtual environment, all required packages, and Jupyter notebooks ready for interactive work.
B.1 Python Installation
The textbook code requires Python 3.10 or later. Earlier versions lack required syntax features (structural pattern matching, updated type hints) and may have incompatible library versions.
Windows
- Download the latest Python installer from python.org/downloads.
- Run the installer. Check "Add python.exe to PATH" on the first screen before clicking "Install Now."
- Verify the installation:
python --version
# Expected: Python 3.10.x or later
pip --version
# Expected: pip 23.x or later
Troubleshooting: If
pythonopens the Microsoft Store or is not recognized, the PATH was not configured. Search Windows Settings for "Manage app execution aliases" and disable the Python app installers. Then re-run the Python installer and ensure "Add to PATH" is checked.
macOS
The system Python on macOS is typically outdated. Install a current version with Homebrew:
# Install Homebrew if not already present
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Python
brew install python@3.12
# Verify
python3 --version
pip3 --version
Note
On macOS, use python3 and pip3 rather than python and pip to avoid invoking the legacy system Python.
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install python3.12 python3.12-venv python3-pip
# Verify
python3 --version
pip3 --version
For other distributions, use the system package manager (dnf on Fedora, pacman on Arch) or build from source using pyenv:
# Using pyenv (any Linux distribution)
curl https://pyenv.run | bash
# Follow the shell configuration instructions printed by the installer
pyenv install 3.12.2
pyenv global 3.12.2
B.2 Virtual Environment Setup
A virtual environment isolates the textbook's package dependencies from your system Python and other projects. This prevents version conflicts and keeps your global Python installation clean.
Creating the Environment
Navigate to a directory where you want to store the textbook code, then create and activate a virtual environment:
# Create a project directory
mkdir blockchain-textbook
cd blockchain-textbook
# Create the virtual environment
python3 -m venv .venv
Activating the Environment
You must activate the environment each time you open a new terminal session:
| Platform | Shell | Command |
|---|---|---|
| Windows | Command Prompt | .venv\Scripts\activate.bat |
| Windows | PowerShell | .venv\Scripts\Activate.ps1 |
| Windows | Git Bash | source .venv/Scripts/activate |
| macOS / Linux | bash/zsh | source .venv/bin/activate |
When active, your prompt will show (.venv) as a prefix:
(.venv) $ python --version
Python 3.12.2
Deactivating
deactivate
Best Practice: Never install textbook packages globally with
pip installoutside a virtual environment. If you seeWARNING: Running pip as the 'root' user, stop and activate your virtual environment first.
B.3 Required Packages
Core Installation
With the virtual environment activated, install all required packages:
pip install --upgrade pip setuptools wheel
pip install \
web3==7.* \
eth-abi==5.* \
eth-account==0.13.* \
ecdsa==0.19.* \
pycryptodome==3.20.* \
requests==2.32.* \
pandas==2.2.* \
matplotlib==3.9.* \
plotly==5.24.* \
numpy==1.26.* \
jupyter==1.0.* \
notebook==7.* \
python-dotenv==1.0.* \
tqdm==4.66.*
Package Reference
The following table describes each package and the chapters where it is used:
| Package | Purpose | Chapters |
|---|---|---|
hashlib |
SHA-256, Keccak-256 hashing (standard library) | 2, 3, 5, 35 |
ecdsa |
Elliptic curve key generation and signatures | 3, 7 |
pycryptodome |
AES encryption, advanced cryptographic primitives | 3, 18 |
web3 (web3.py) |
Ethereum interaction: transactions, contracts, events | 11, 13, 14, 19, 20, 22, 33, 35 |
eth-abi |
ABI encoding/decoding for Ethereum contracts | 13, 14, 35 |
eth-account |
Ethereum account management and signing | 11, 13, 35 |
requests |
HTTP requests for RPC and API calls | 6, 33, 35 |
pandas |
Data analysis and tabular data manipulation | 27, 33, 34, 35 |
matplotlib |
Static charts and visualizations | 5, 8, 27, 33, 34 |
plotly |
Interactive charts and dashboards | 27, 33, 34 |
numpy |
Numerical computing and array operations | 5, 18, 27, 34 |
jupyter |
Interactive notebook environment | All code chapters |
python-dotenv |
Load environment variables from .env files |
13, 33, 35 |
tqdm |
Progress bars for long-running operations | 5, 35 |
Note
hashlib and secrets are part of Python's standard library and do not require installation.
Freezing Dependencies
After installation, save the exact versions for reproducibility:
pip freeze > requirements.txt
To recreate the environment later or on a different machine:
pip install -r requirements.txt
B.4 Jupyter Notebook Setup
Jupyter notebooks provide an interactive environment for running code cells, viewing output, and experimenting with blockchain concepts. Many textbook exercises are designed for notebook use.
Launching Jupyter
# From within your activated virtual environment
jupyter notebook
This opens a browser window at http://localhost:8888. Navigate to your project directory and create a new Python 3 notebook.
JupyterLab Alternative
JupyterLab provides a more modern interface:
pip install jupyterlab
jupyter lab
Verifying the Kernel
Ensure the notebook is using your virtual environment's Python:
# Run this in the first cell of any notebook
import sys
print(sys.executable)
# Should print a path inside your .venv directory
If the path points to the system Python instead, register the virtual environment as a Jupyter kernel:
pip install ipykernel
python -m ipykernel install --user --name=blockchain --display-name="Python (Blockchain)"
Then select "Python (Blockchain)" from the kernel menu in Jupyter.
Recommended Notebook Settings
Add this cell at the top of your notebooks for consistent output:
# Standard imports and display settings
import warnings
warnings.filterwarnings('ignore')
# Auto-reload modules when changed
%load_ext autoreload
%autoreload 2
# Inline plots
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (10, 6)
plt.rcParams['figure.dpi'] = 100
B.5 Environment Variables and API Keys
Several chapters require API keys for blockchain data providers. Store these securely in a .env file (never commit this to version control):
# Create .env file in your project root
touch .env
Add your keys:
# .env
INFURA_API_KEY=your_infura_project_id
ALCHEMY_API_KEY=your_alchemy_api_key
ETHERSCAN_API_KEY=your_etherscan_api_key
Load them in Python:
from dotenv import load_dotenv
import os
load_dotenv()
infura_key = os.getenv("INFURA_API_KEY")
alchemy_key = os.getenv("ALCHEMY_API_KEY")
Obtaining Free API Keys
| Provider | URL | Free Tier |
|---|---|---|
| Infura | infura.io | 100K requests/day |
| Alchemy | alchemy.com | 300M compute units/month |
| Etherscan | etherscan.io/apis | 5 calls/second |
Security Warning: Add
.envto your.gitignoreimmediately. Never hardcode API keys or private keys in source files.
B.6 Verification Script
Run this script to confirm everything is installed correctly. Save it as verify_setup.py:
#!/usr/bin/env python3
"""
Blockchain Textbook Environment Verification Script
Run: python verify_setup.py
"""
import sys
def check_python_version():
v = sys.version_info
if v.major == 3 and v.minor >= 10:
print(f" [PASS] Python {v.major}.{v.minor}.{v.micro}")
return True
else:
print(f" [FAIL] Python {v.major}.{v.minor}.{v.micro} — need 3.10+")
return False
def check_package(name, import_name=None):
import_name = import_name or name
try:
mod = __import__(import_name)
version = getattr(mod, '__version__', 'installed')
print(f" [PASS] {name} ({version})")
return True
except ImportError:
print(f" [FAIL] {name} — not installed")
return False
def check_hashlib():
import hashlib
test = hashlib.sha256(b"blockchain").hexdigest()
expected = "625da44e4eaf58d61cf048d168aa6f5e492dea166d8bb54f06c3b1f4a001be23"
if test == expected:
print(" [PASS] hashlib SHA-256 — correct output")
return True
else:
print(" [FAIL] hashlib SHA-256 — unexpected output")
return False
def check_web3_provider():
try:
from web3 import Web3
w3 = Web3()
addr = w3.to_checksum_address("0x" + "0" * 40)
print(f" [PASS] web3.py — address utilities working ({addr[:10]}...)")
return True
except Exception as e:
print(f" [FAIL] web3.py — {e}")
return False
def check_ecdsa():
try:
from ecdsa import SigningKey, SECP256k1
sk = SigningKey.generate(curve=SECP256k1)
vk = sk.get_verifying_key()
sig = sk.sign(b"test message")
assert vk.verify(sig, b"test message")
print(" [PASS] ecdsa — key generation and signing working")
return True
except Exception as e:
print(f" [FAIL] ecdsa — {e}")
return False
def check_jupyter():
try:
import notebook
version = notebook.__version__
print(f" [PASS] Jupyter Notebook ({version})")
return True
except ImportError:
print(" [FAIL] Jupyter Notebook — not installed")
return False
def main():
print("\n=== Blockchain Textbook Environment Check ===\n")
results = []
print("[1/7] Python version")
results.append(check_python_version())
print("\n[2/7] Core packages")
for pkg, imp in [
("web3", "web3"),
("eth-abi", "eth_abi"),
("eth-account", "eth_account"),
("ecdsa", "ecdsa"),
("pycryptodome", "Crypto"),
("requests", "requests"),
]:
results.append(check_package(pkg, imp))
print("\n[3/7] Data & visualization packages")
for pkg in ["pandas", "numpy", "matplotlib", "plotly"]:
results.append(check_package(pkg))
print("\n[4/7] Utility packages")
for pkg, imp in [("python-dotenv", "dotenv"), ("tqdm", "tqdm")]:
results.append(check_package(pkg, imp))
print("\n[5/7] Hashlib SHA-256")
results.append(check_hashlib())
print("\n[6/7] Web3 provider utilities")
results.append(check_web3_provider())
print("\n[7/7] ECDSA cryptography")
results.append(check_ecdsa())
passed = sum(results)
total = len(results)
print(f"\n{'='*45}")
print(f"Results: {passed}/{total} checks passed")
if passed == total:
print("Your environment is ready. Start with Chapter 1!\n")
else:
print("Some checks failed. Review the [FAIL] items above.\n")
sys.exit(1)
if __name__ == "__main__":
main()
Run it:
python verify_setup.py
Expected output when everything is configured correctly:
=== Blockchain Textbook Environment Check ===
[1/7] Python version
[PASS] Python 3.12.2
[2/7] Core packages
[PASS] web3 (7.6.0)
[PASS] eth-abi (5.1.0)
...
Results: 16/16 checks passed
Your environment is ready. Start with Chapter 1!
B.7 Troubleshooting Common Issues
"pip: command not found"
Python was installed without pip, or pip is not on the PATH.
# Re-install pip
python3 -m ensurepip --upgrade
"Microsoft Visual C++ 14.0 or greater is required" (Windows)
Some packages (notably pycryptodome) require C compilation tools on Windows.
- Install Microsoft C++ Build Tools.
- In the installer, select "Desktop development with C++."
- Restart your terminal and retry
pip install.
Alternatively, install the pre-built binary wheel:
pip install pycryptodome --only-binary=:all:
"error: externally-managed-environment" (Linux)
Modern Linux distributions (Debian 12+, Ubuntu 23.04+) prevent global pip installs to protect system packages. This is expected and correct. Always use a virtual environment:
python3 -m venv .venv
source .venv/bin/activate
pip install <package>
web3.py Connection Errors
If you see ConnectionError when connecting to an Ethereum node:
- Verify your API key is correct in
.env. - Check the provider URL format:
from web3 import Web3
# Infura
w3 = Web3(Web3.HTTPProvider(f"https://mainnet.infura.io/v3/{infura_key}"))
# Alchemy
w3 = Web3(Web3.HTTPProvider(f"https://eth-mainnet.g.alchemy.com/v2/{alchemy_key}"))
# Local node (Ganache, Hardhat)
w3 = Web3(Web3.HTTPProvider("http://127.0.0.1:8545"))
print(w3.is_connected()) # Should print True
- For chapters using only local simulations (no live network), you do not need an API key.
Jupyter Kernel Dies on Import
If the Jupyter kernel crashes when importing large packages, increase the memory available:
# Set environment variable before launching
export JUPYTER_MEMORY_LIMIT=4096 # MB
jupyter notebook
On Windows (PowerShell):
$env:JUPYTER_MEMORY_LIMIT = "4096"
jupyter notebook
M1/M2/M3 Mac (Apple Silicon) Issues
Some packages may not have pre-built ARM wheels. If installation fails:
# Ensure you're using a native ARM Python (not Rosetta)
python3 -c "import platform; print(platform.machine())"
# Should print: arm64
# If a package fails to build, try:
pip install --no-cache-dir <package>
B.8 Recommended Project Structure
Organize your textbook code as follows:
blockchain-textbook/
.venv/ # Virtual environment (do not commit)
.env # API keys (do not commit)
.gitignore
requirements.txt # Frozen dependencies
verify_setup.py # Verification script
notebooks/
ch02_hashing.ipynb
ch03_keys.ipynb
ch05_mining_sim.ipynb
...
scripts/
mining_simulator.py
merkle_tree.py
...
data/
blocks.csv
transactions.json
...
Create a .gitignore to exclude sensitive and generated files:
.venv/
.env
__pycache__/
*.pyc
.ipynb_checkpoints/
*.egg-info/
dist/
build/
You are now ready to run every Python exercise in this textbook. If you encounter issues not covered here, consult the package documentation linked in the further-reading sections of each chapter, or post a question on the textbook's community forum.