Interacting with multiple networks
The provider trait is generic over the network type, Provider<N: Network = Ethereum>, with the default network set to Ethereum.
The Network generic helps the provider to accomodate various network types with different transaction and RPC response types seamlessly.
The Network trait
This removes the need for implementing the Provider trait for each network type you want to interact with. Instead, we just need to implement the Network trait.
Following is the Ethereum network implementation which defines the structure of the network and its RPC types.
impl Network for Ethereum {
type TxType = alloy_consensus::TxType;
type TxEnvelope = alloy_consensus::TxEnvelope;
type UnsignedTx = alloy_consensus::TypedTransaction;
type ReceiptEnvelope = alloy_consensus::ReceiptEnvelope;
type Header = alloy_consensus::Header;
type TransactionRequest = alloy_rpc_types_eth::transaction::TransactionRequest;
type TransactionResponse = alloy_rpc_types_eth::Transaction;
type ReceiptResponse = alloy_rpc_types_eth::TransactionReceipt;
type HeaderResponse = alloy_rpc_types_eth::Header;
type BlockResponse = alloy_rpc_types_eth::Block;
}Choosing the wrong network type can lead to unexpected deserialization errors due to differences in RPC types. For example, the using an Ethereum network provider to get a full block with transactions can result in the following error:
let provider = ProviderBuilder::new()
.network::<Ethereum>()
.connect_http("https://base-sepolia.ithaca.xyz/".parse()?);
// Yields: Error: deserialization error: data did not match any variant of untagged enum BlockTransactions
let block_with_txs = provider.get_block(25508329.into()).full().await?;This is due to the Deposit transaction type which is not supported by Ethereum network. This can be fixed in two ways either by using the catch-all AnyNetwork type or by using the dedicated Optimism network implementation from op-alloy-network.
Catch-all network: AnyNetwork
The Provider defaults to the ethereum network type, but one can easily switch to another network while building the provider like so:
let provider = ProviderBuilder::new()
.network::<AnyNetwork>()
.connect_http("http://localhost:8545");The AnyNetwork type is a catch-all network allowing you to interact with any network type, in case you don't want to roll your own network type.
Custom Network: Optimism
The Optimism network type has been created to interact with OP-stack chains such as Base.
impl Network for Optimism {
type TxType = OpTxType;
type TxEnvelope = op_alloy_consensus::OpTxEnvelope;
type UnsignedTx = op_alloy_consensus::OpTypedTransaction;
type ReceiptEnvelope = op_alloy_consensus::OpReceiptEnvelope;
type Header = alloy_consensus::Header;
type TransactionRequest = op_alloy_rpc_types::OpTransactionRequest;
type TransactionResponse = op_alloy_rpc_types::Transaction;
type ReceiptResponse = op_alloy_rpc_types::OpTransactionReceipt;
type HeaderResponse = alloy_rpc_types_eth::Header;
type BlockResponse =
alloy_rpc_types_eth::Block<Self::TransactionResponse, Self::HeaderResponse>;
}let provider = ProviderBuilder::new()
.network::<op_alloy_network::Optimism>()
.connect_http("http://localhost:8545");