CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-eth-utils

Common utility functions for python code that interacts with Ethereum

Pending
Overview
Eval results
Files

hexadecimal-utilities.mddocs/

Hexadecimal Utilities

Hex string processing including encoding, decoding, prefix handling, and validation. Essential for working with Ethereum's hex-encoded data formats.

Capabilities

Hex Encoding and Decoding

Convert between bytes and hex string representations.

def encode_hex(value) -> str:
    """
    Encode bytes or integer to 0x-prefixed hex string.
    
    Args:
        value: Bytes, bytearray, or integer to encode
        
    Returns:
        str: 0x-prefixed hex string
        
    Raises:
        TypeError: If value cannot be hex-encoded
    """

def decode_hex(value: str) -> bytes:
    """
    Decode hex string to bytes.
    
    Args:
        value (str): Hex string (with or without 0x prefix)
        
    Returns:
        bytes: Decoded byte data
        
    Raises:
        ValidationError: If hex string is invalid
    """

Hex String Validation

Check if values are valid hex strings or contain hex characters.

def is_hex(value) -> bool:
    """
    Check if value contains only valid hex characters.
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value contains only hex characters (0-9, a-f, A-F)
    """

def is_hexstr(value) -> bool:
    """
    Check if value is a valid hex string.
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is a string with valid hex format
    """

Hex Prefix Management

Handle 0x prefix addition and removal.

def is_0x_prefixed(value: str) -> bool:
    """
    Check if string has 0x prefix.
    
    Args:
        value (str): String to check
        
    Returns:
        bool: True if string starts with '0x' or '0X'
    """

def add_0x_prefix(value: str) -> str:
    """
    Add 0x prefix to hex string if not present.
    
    Args:
        value (str): Hex string
        
    Returns:
        str: Hex string with 0x prefix
    """

def remove_0x_prefix(value: str) -> str:
    """
    Remove 0x prefix from hex string.
    
    Args:
        value (str): Hex string (with or without 0x prefix)
        
    Returns:
        str: Hex string without 0x prefix
        
    Raises:
        ValidationError: If string doesn't have 0x prefix
    """

Usage Examples

Basic Hex Operations

from eth_utils import encode_hex, decode_hex, is_hex, is_hexstr

# Encode bytes to hex
data = b"Hello, World!"
hex_string = encode_hex(data)
print(hex_string)  # 0x48656c6c6f2c20576f726c6421

# Decode hex back to bytes
decoded = decode_hex(hex_string)
print(decoded)  # b'Hello, World!'

# Encode integer to hex
number = 12345
hex_number = encode_hex(number)
print(hex_number)  # 0x3039

# Validation
print(is_hex("abc123"))      # True
print(is_hex("xyz"))         # False
print(is_hexstr("0x123"))    # True
print(is_hexstr("123"))      # True (hex chars, no prefix required)

Working with Transaction Data

from eth_utils import encode_hex, decode_hex, add_0x_prefix

# Process transaction hash
tx_hash_bytes = bytes.fromhex("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
tx_hash_hex = encode_hex(tx_hash_bytes)
print(tx_hash_hex)  # 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

# Process contract bytecode (might come without prefix)
bytecode = "608060405234801561001057600080fd5b50"
prefixed_bytecode = add_0x_prefix(bytecode)
print(prefixed_bytecode)  # 0x608060405234801561001057600080fd5b50

# Decode for analysis
bytecode_bytes = decode_hex(prefixed_bytecode)
print(f"Bytecode length: {len(bytecode_bytes)} bytes")

Prefix Management

from eth_utils import is_0x_prefixed, add_0x_prefix, remove_0x_prefix

def normalize_hex_input(hex_input):
    """Ensure hex string has 0x prefix."""
    if not is_0x_prefixed(hex_input):
        return add_0x_prefix(hex_input)
    return hex_input

def clean_hex_for_storage(hex_input):
    """Remove 0x prefix for compact storage."""
    if is_0x_prefixed(hex_input):
        return remove_0x_prefix(hex_input)
    return hex_input

# Usage examples
raw_hex = "1234abcd"
normalized = normalize_hex_input(raw_hex)
print(normalized)  # 0x1234abcd

prefixed_hex = "0x1234abcd"
cleaned = clean_hex_for_storage(prefixed_hex)
print(cleaned)  # 1234abcd

Data Processing Pipeline

from eth_utils import encode_hex, decode_hex, is_hexstr, ValidationError

def process_hex_data(data_input):
    """Process various hex data formats."""
    if isinstance(data_input, bytes):
        # Already bytes, encode to hex for display
        return encode_hex(data_input)
    
    elif isinstance(data_input, str) and is_hexstr(data_input):
        # Hex string, decode and re-encode for normalization
        try:
            decoded = decode_hex(data_input)
            return encode_hex(decoded)
        except ValidationError:
            raise ValueError(f"Invalid hex string: {data_input}")
    
    elif isinstance(data_input, int):
        # Integer, encode to hex
        return encode_hex(data_input)
    
    else:
        raise TypeError(f"Unsupported data type: {type(data_input)}")

# Examples
print(process_hex_data(b"test"))           # 0x74657374
print(process_hex_data("0x74657374"))      # 0x74657374
print(process_hex_data("74657374"))        # 0x74657374
print(process_hex_data(123))               # 0x7b

Contract Address Generation

from eth_utils import encode_hex, decode_hex, keccak, to_bytes

def create_contract_address(sender_address, nonce):
    """Generate contract address from sender and nonce."""
    # Remove 0x prefix for processing
    sender_bytes = decode_hex(sender_address)
    
    # Encode nonce (simple case for small nonces)
    if nonce == 0:
        nonce_bytes = b''
    else:
        nonce_bytes = to_bytes(primitive=nonce)
    
    # RLP encode (simplified for example)
    rlp_encoded = sender_bytes + nonce_bytes
    
    # Keccak hash and take last 20 bytes
    hash_result = keccak(rlp_encoded)
    contract_address = hash_result[-20:]
    
    return encode_hex(contract_address)

# Example usage  
sender = "0xd3CdA913deB6f67967B99D67aCDFa1712C293601"
contract_addr = create_contract_address(sender, 0)
print(f"Contract address: {contract_addr}")

Hex String Utilities

from eth_utils import is_hex, is_hexstr, is_0x_prefixed

def validate_hex_input(hex_string, expected_length=None):
    """Validate hex string input with optional length check."""
    if not isinstance(hex_string, str):
        raise TypeError("Input must be string")
    
    if not is_hexstr(hex_string):
        raise ValueError("Input is not valid hex string")
    
    # Clean for length check
    clean_hex = hex_string[2:] if is_0x_prefixed(hex_string) else hex_string
    
    if expected_length and len(clean_hex) != expected_length:
        raise ValueError(f"Expected {expected_length} hex chars, got {len(clean_hex)}")
    
    return True

def format_hex_display(hex_string, max_length=10):
    """Format hex string for display with truncation."""
    if not is_0x_prefixed(hex_string):
        hex_string = f"0x{hex_string}"
    
    if len(hex_string) > max_length:
        visible_chars = max_length - 6  # Account for "0x" and "..."
        return f"{hex_string[:2+visible_chars//2]}...{hex_string[-visible_chars//2:]}"
    
    return hex_string

# Examples
validate_hex_input("0x1234")        # True
validate_hex_input("1234")          # True
validate_hex_input("0x1234", 4)     # True (4 hex chars)

print(format_hex_display("0x1234567890abcdef1234567890abcdef"))  # 0x12...ef

Common Patterns

Safe Hex Processing

from eth_utils import decode_hex, encode_hex, ValidationError

def safe_hex_decode(hex_input):
    """Safely decode hex string with error handling."""
    try:
        return decode_hex(hex_input)
    except ValidationError as e:
        print(f"Failed to decode hex: {e}")
        return None

def ensure_hex_format(data):
    """Ensure data is in hex string format."""
    if isinstance(data, bytes):
        return encode_hex(data)
    elif isinstance(data, str) and is_hexstr(data):
        return add_0x_prefix(data) if not is_0x_prefixed(data) else data
    else:
        raise TypeError("Cannot convert to hex format")

Hex Data Comparison

from eth_utils import decode_hex, is_0x_prefixed

def hex_equal(hex1, hex2):
    """Compare two hex strings for equality (prefix-agnostic)."""
    # Normalize both to bytes
    bytes1 = decode_hex(hex1)
    bytes2 = decode_hex(hex2)
    return bytes1 == bytes2

# Usage
print(hex_equal("0x1234", "1234"))     # True
print(hex_equal("0x1234", "0x1234"))   # True
print(hex_equal("1234", "1234"))       # True

Install with Tessl CLI

npx tessl i tessl/pypi-eth-utils

docs

abi-processing.md

address-operations.md

crypto-functions.md

currency-units.md

data-conversions.md

data-formatting.md

functional-programming.md

hexadecimal-utilities.md

index.md

logging-debugging.md

network-information.md

type-checking.md

tile.json