Common utility functions for python code that interacts with Ethereum
—
Ethereum network data including chain IDs, network names, and metadata for all major Ethereum networks and testnets.
Retrieve network information by chain ID.
def network_from_chain_id(chain_id: int) -> Network:
"""
Get complete network object from chain ID.
Args:
chain_id (int): Ethereum chain ID
Returns:
Network: Network object with chain_id, name, shortName, symbol
Raises:
KeyError: If chain ID is not found
"""
def name_from_chain_id(chain_id: int) -> str:
"""
Get network name from chain ID.
Args:
chain_id (int): Ethereum chain ID
Returns:
str: Network name
Raises:
KeyError: If chain ID is not found
"""
def short_name_from_chain_id(chain_id: int) -> str:
"""
Get network short name from chain ID.
Args:
chain_id (int): Ethereum chain ID
Returns:
str: Network short name
Raises:
KeyError: If chain ID is not found
"""Network information data classes and constants.
class Network:
"""Ethereum network information dataclass."""
chain_id: int
name: str
shortName: str
symbol: str
# Network data constants
networks: List[Network] # List of all known networks
networks_by_id: Dict[int, Network] # Chain ID to Network mapping
network_names_by_id: Dict[int, str] # Chain ID to name mapping
network_short_names_by_id: Dict[int, str] # Chain ID to short name mappingfrom eth_utils import network_from_chain_id, name_from_chain_id, short_name_from_chain_id
# Get complete network information
mainnet = network_from_chain_id(1)
print(f"Network: {mainnet.name}") # Ethereum Mainnet
print(f"Symbol: {mainnet.symbol}") # ETH
print(f"Short name: {mainnet.shortName}") # eth
# Get specific network properties
polygon_name = name_from_chain_id(137)
print(polygon_name) # Polygon Mainnet
arbitrum_short = short_name_from_chain_id(42161)
print(arbitrum_short) # arb1from eth_utils import networks_by_id, network_from_chain_id
def is_supported_network(chain_id):
"""Check if chain ID is supported."""
return chain_id in networks_by_id
def get_network_info(chain_id):
"""Safely get network information."""
try:
return network_from_chain_id(chain_id)
except KeyError:
return None
def validate_chain_id(chain_id):
"""Validate and get chain information."""
if not isinstance(chain_id, int):
raise TypeError("Chain ID must be integer")
if chain_id <= 0:
raise ValueError("Chain ID must be positive")
if not is_supported_network(chain_id):
raise ValueError(f"Unsupported chain ID: {chain_id}")
return network_from_chain_id(chain_id)
# Examples
print(is_supported_network(1)) # True (Ethereum Mainnet)
print(is_supported_network(99999)) # False (Unknown network)
network = get_network_info(1)
if network:
print(f"Found network: {network.name}")
try:
validate_chain_id(1) # Success
validate_chain_id(99999) # Raises ValueError
except ValueError as e:
print(f"Validation error: {e}")from eth_utils import network_from_chain_id
class NetworkConfig:
"""Network-specific configuration."""
def __init__(self, chain_id):
self.network = network_from_chain_id(chain_id)
self.chain_id = chain_id
@property
def is_mainnet(self):
return self.chain_id == 1
@property
def is_testnet(self):
testnet_ids = {3, 4, 5, 42, 11155111} # Common testnets
return self.chain_id in testnet_ids
@property
def block_time(self):
"""Average block time in seconds."""
block_times = {
1: 12, # Ethereum Mainnet
137: 2, # Polygon
56: 3, # BSC
42161: 1, # Arbitrum One
}
return block_times.get(self.chain_id, 12) # Default to 12s
@property
def native_currency(self):
"""Get native currency symbol."""
return self.network.symbol
def get_explorer_url(self, tx_hash=None, address=None):
"""Get block explorer URL."""
explorers = {
1: "https://etherscan.io",
137: "https://polygonscan.com",
56: "https://bscscan.com",
42161: "https://arbiscan.io"
}
base_url = explorers.get(self.chain_id)
if not base_url:
return None
if tx_hash:
return f"{base_url}/tx/{tx_hash}"
elif address:
return f"{base_url}/address/{address}"
else:
return base_url
# Usage
config = NetworkConfig(1) # Ethereum Mainnet
print(f"Network: {config.network.name}")
print(f"Is mainnet: {config.is_mainnet}")
print(f"Block time: {config.block_time}s")
print(f"Currency: {config.native_currency}")
print(f"Explorer: {config.get_explorer_url()}")from eth_utils import networks, network_from_chain_id
class MultiChainSupport:
"""Multi-chain application support."""
def __init__(self, supported_chains=None):
if supported_chains:
self.supported_networks = [
network_from_chain_id(chain_id)
for chain_id in supported_chains
]
else:
# Default to major networks
major_chains = [1, 137, 56, 42161, 10, 8453] # ETH, Polygon, BSC, Arbitrum, Optimism, Base
self.supported_networks = [
network_from_chain_id(chain_id)
for chain_id in major_chains
if chain_id in networks_by_id
]
def is_supported(self, chain_id):
"""Check if chain is supported."""
return any(network.chain_id == chain_id for network in self.supported_networks)
def get_supported_networks(self):
"""Get list of supported networks."""
return [(net.chain_id, net.name) for net in self.supported_networks]
def validate_network(self, chain_id):
"""Validate network is supported."""
if not self.is_supported(chain_id):
supported = [net.chain_id for net in self.supported_networks]
raise ValueError(f"Chain {chain_id} not supported. Supported: {supported}")
return network_from_chain_id(chain_id)
# Usage
multi_chain = MultiChainSupport()
print("Supported networks:")
for chain_id, name in multi_chain.get_supported_networks():
print(f" {chain_id}: {name}")
# Validate network
try:
network = multi_chain.validate_network(1) # Success
print(f"Using network: {network.name}")
except ValueError as e:
print(f"Network error: {e}")from eth_utils import networks, networks_by_id
def list_all_networks():
"""List all known networks."""
print("All known networks:")
for network in sorted(networks, key=lambda n: n.chain_id):
print(f" {network.chain_id:6d}: {network.name} ({network.shortName})")
def find_networks_by_name(search_term):
"""Find networks by name substring."""
matches = []
search_lower = search_term.lower()
for network in networks:
if (search_lower in network.name.lower() or
search_lower in network.shortName.lower()):
matches.append(network)
return matches
def get_testnet_networks():
"""Get all testnet networks."""
testnets = []
testnet_keywords = ['test', 'goerli', 'sepolia', 'ropsten', 'kovan', 'rinkeby']
for network in networks:
name_lower = network.name.lower()
if any(keyword in name_lower for keyword in testnet_keywords):
testnets.append(network)
return testnets
def get_layer2_networks():
"""Get Layer 2 networks."""
layer2_ids = {
137: "Polygon",
42161: "Arbitrum One",
10: "Optimism",
8453: "Base",
324: "zkSync Era"
}
layer2_networks = []
for chain_id, description in layer2_ids.items():
if chain_id in networks_by_id:
layer2_networks.append(networks_by_id[chain_id])
return layer2_networks
# Examples
list_all_networks()
ethereum_networks = find_networks_by_name("ethereum")
print(f"\nFound {len(ethereum_networks)} Ethereum networks")
testnets = get_testnet_networks()
print(f"Found {len(testnets)} testnet networks")
layer2_nets = get_layer2_networks()
print(f"Found {len(layer2_nets)} Layer 2 networks")from eth_utils import network_from_chain_id
class RPCConfig:
"""RPC configuration helper using network information."""
# Common RPC endpoints (example - use your own)
DEFAULT_RPCS = {
1: ["https://mainnet.infura.io/v3/YOUR-PROJECT-ID"],
137: ["https://polygon-rpc.com"],
56: ["https://bsc-dataseed.binance.org"],
42161: ["https://arb1.arbitrum.io/rpc"]
}
def __init__(self, chain_id, custom_rpc=None):
self.network = network_from_chain_id(chain_id)
self.chain_id = chain_id
self.custom_rpc = custom_rpc
def get_rpc_urls(self):
"""Get RPC URLs for this network."""
if self.custom_rpc:
return [self.custom_rpc]
return self.DEFAULT_RPCS.get(self.chain_id, [])
def get_chain_config(self):
"""Get complete chain configuration."""
return {
"chainId": self.chain_id,
"chainName": self.network.name,
"nativeCurrency": {
"name": self.network.symbol,
"symbol": self.network.symbol,
"decimals": 18
},
"rpcUrls": self.get_rpc_urls(),
"blockExplorerUrls": [self.get_explorer_url()] if self.get_explorer_url() else []
}
def get_explorer_url(self):
"""Get block explorer URL."""
explorers = {
1: "https://etherscan.io",
137: "https://polygonscan.com",
56: "https://bscscan.com",
42161: "https://arbiscan.io"
}
return explorers.get(self.chain_id)
# Usage
config = RPCConfig(1) # Ethereum Mainnet
chain_config = config.get_chain_config()
print(f"Chain config for {chain_config['chainName']}:")
print(f" Chain ID: {chain_config['chainId']}")
print(f" Currency: {chain_config['nativeCurrency']['symbol']}")
print(f" RPC URLs: {chain_config['rpcUrls']}")The eth-utils package includes comprehensive network information for major Ethereum networks including:
The complete list is available through the networks constant and can be explored programmatically.