Documentation Index
Fetch the complete documentation index at: https://mintlify.com/eco/eco-routes/llms.txt
Use this file to discover all available pages before exploring further.
The AddressConverter library provides utility functions for converting between Ethereum address (20 bytes) and bytes32 (32 bytes) types. This is commonly needed when working with cross-chain messaging protocols that use bytes32 for addresses.
Overview
Ethereum addresses are 20 bytes, while many cross-chain protocols use bytes32 for standardized addressing across different chains. This library handles the conversion between these formats safely and efficiently.
Functions
toBytes32
Converts an Ethereum address to bytes32 format.
function toBytes32(address addr) internal pure returns (bytes32)
Parameters:
addr: The Ethereum address to convert (20 bytes)
Returns: The bytes32 representation of the address (32 bytes, zero-padded)
Implementation:
The function converts the address by:
- Casting to
uint160 (20 bytes)
- Casting to
uint256 (32 bytes, zero-padded on left)
- Casting to
bytes32
Example:
import "./libs/AddressConverter.sol";
contract Example {
using AddressConverter for address;
function convertAddress(address user) public pure returns (bytes32) {
// Convert address to bytes32
bytes32 userBytes = AddressConverter.toBytes32(user);
return userBytes;
}
// Or using library syntax
function convertAddressAlt(address user) public pure returns (bytes32) {
return user.toBytes32();
}
}
toAddress
Converts bytes32 back to an Ethereum address.
function toAddress(bytes32 b) internal pure returns (address)
Parameters:
b: The bytes32 value to convert (32 bytes)
Returns: The Ethereum address extracted from the bytes32 value
Reverts:
InvalidAddress(bytes32): If the bytes32 value cannot be safely converted to an address (top 12 bytes are not zero)
Implementation:
The function:
- Validates that the bytes32 can be safely converted using
isValidAddress()
- Converts by casting to
uint256, then uint160, then address
Example:
import "./libs/AddressConverter.sol";
contract Example {
using AddressConverter for bytes32;
function convertBytes(bytes32 addressBytes) public pure returns (address) {
// Convert bytes32 to address (reverts if invalid)
address user = AddressConverter.toAddress(addressBytes);
return user;
}
// Or using library syntax
function convertBytesAlt(bytes32 addressBytes) public pure returns (address) {
return addressBytes.toAddress();
}
}
isValidAddress
Checks if a bytes32 value can be safely converted to an Ethereum address.
function isValidAddress(bytes32 b) internal pure returns (bool)
Parameters:
b: The bytes32 value to validate
Returns: true if the bytes32 can be safely converted to an address, false otherwise
Validation:
For a bytes32 to represent a valid Ethereum address:
- The top 12 bytes (96 bits) must be zero
- Only the bottom 20 bytes (160 bits) should contain data
Example:
import "./libs/AddressConverter.sol";
contract Example {
using AddressConverter for bytes32;
function validateAndConvert(bytes32 addressBytes) public pure returns (address) {
// Check if valid before converting
if (AddressConverter.isValidAddress(addressBytes)) {
return AddressConverter.toAddress(addressBytes);
} else {
revert("Invalid address bytes");
}
}
function checkValidity(bytes32 value) public pure returns (bool) {
return value.isValidAddress();
}
}
Errors
InvalidAddress
Thrown when attempting to convert an invalid bytes32 value to an address.
error InvalidAddress(bytes32 value);
Parameters:
value: The invalid bytes32 value that was attempted to be converted
When it occurs:
- When calling
toAddress() with a bytes32 value where the top 12 bytes are not zero
Usage Patterns
Basic Conversion
import "./libs/AddressConverter.sol";
contract CrossChainMessenger {
using AddressConverter for address;
using AddressConverter for bytes32;
function sendMessage(address recipient, bytes memory data) external {
// Convert address to bytes32 for cross-chain message
bytes32 recipientBytes = recipient.toBytes32();
// Send message with bytes32 recipient
_sendCrossChainMessage(recipientBytes, data);
}
function receiveMessage(bytes32 senderBytes, bytes memory data) external {
// Convert bytes32 back to address
address sender = senderBytes.toAddress();
// Process message from sender
_processMessage(sender, data);
}
function _sendCrossChainMessage(bytes32 recipient, bytes memory data) internal {
// Implementation
}
function _processMessage(address sender, bytes memory data) internal {
// Implementation
}
}
Safe Conversion with Validation
import "./libs/AddressConverter.sol";
contract SafeConverter {
using AddressConverter for bytes32;
event AddressConverted(bytes32 indexed input, address indexed output);
function safeConvert(bytes32 addressBytes) external returns (address) {
// Validate before converting
require(
addressBytes.isValidAddress(),
"Invalid address format"
);
address converted = addressBytes.toAddress();
emit AddressConverted(addressBytes, converted);
return converted;
}
function batchConvert(bytes32[] calldata addressesBytes)
external
pure
returns (address[] memory)
{
address[] memory addresses = new address[](addressesBytes.length);
for (uint256 i = 0; i < addressesBytes.length; i++) {
// Will revert on invalid address
addresses[i] = addressesBytes[i].toAddress();
}
return addresses;
}
}
Integration with Cross-Chain Protocols
import "./libs/AddressConverter.sol";
contract CrossChainBridge {
using AddressConverter for address;
using AddressConverter for bytes32;
struct CrossChainTransfer {
bytes32 recipient; // bytes32 for cross-chain compatibility
uint256 amount;
uint256 destinationChainId;
}
function initiateTransfer(
address recipient,
uint256 amount,
uint256 destinationChainId
) external {
// Convert local address to bytes32 for cross-chain transfer
CrossChainTransfer memory transfer = CrossChainTransfer({
recipient: recipient.toBytes32(),
amount: amount,
destinationChainId: destinationChainId
});
_processTransfer(transfer);
}
function completeTransfer(CrossChainTransfer calldata transfer) external {
// Convert bytes32 back to local address
address localRecipient = transfer.recipient.toAddress();
// Transfer tokens to local recipient
_transferTokens(localRecipient, transfer.amount);
}
function _processTransfer(CrossChainTransfer memory transfer) internal {
// Implementation
}
function _transferTokens(address to, uint256 amount) internal {
// Implementation
}
}
TypeScript Equivalent
The TypeScript SDK provides equivalent functionality. See TypeScript SDK Utilities for the TypeScript implementation.
import { TypeCasts } from './utils/typeCasts'
// Same functionality in TypeScript
const bytes32 = TypeCasts.addressToBytes32('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb')
const address = TypeCasts.bytes32ToAddress(bytes32)
Gas Optimization
All functions in this library are marked as internal pure, meaning:
- No state is read or modified
- Functions are inlined during compilation (no JUMP operations)
- Minimal gas cost (just the type conversions)
Best Practices
- Always validate when converting from bytes32 to address using external input
- Use library syntax for cleaner code:
address.toBytes32() instead of AddressConverter.toBytes32(address)
- Handle errors appropriately when
toAddress() might revert
- Batch conversions when possible to optimize gas in loops