0
# Hexadecimal Utilities
1
2
Hex string processing including encoding, decoding, prefix handling, and validation. Essential for working with Ethereum's hex-encoded data formats.
3
4
## Capabilities
5
6
### Hex Encoding and Decoding
7
8
Convert between bytes and hex string representations.
9
10
```python { .api }
11
def encode_hex(value) -> str:
12
"""
13
Encode bytes or integer to 0x-prefixed hex string.
14
15
Args:
16
value: Bytes, bytearray, or integer to encode
17
18
Returns:
19
str: 0x-prefixed hex string
20
21
Raises:
22
TypeError: If value cannot be hex-encoded
23
"""
24
25
def decode_hex(value: str) -> bytes:
26
"""
27
Decode hex string to bytes.
28
29
Args:
30
value (str): Hex string (with or without 0x prefix)
31
32
Returns:
33
bytes: Decoded byte data
34
35
Raises:
36
ValidationError: If hex string is invalid
37
"""
38
```
39
40
### Hex String Validation
41
42
Check if values are valid hex strings or contain hex characters.
43
44
```python { .api }
45
def is_hex(value) -> bool:
46
"""
47
Check if value contains only valid hex characters.
48
49
Args:
50
value: Value to check
51
52
Returns:
53
bool: True if value contains only hex characters (0-9, a-f, A-F)
54
"""
55
56
def is_hexstr(value) -> bool:
57
"""
58
Check if value is a valid hex string.
59
60
Args:
61
value: Value to check
62
63
Returns:
64
bool: True if value is a string with valid hex format
65
"""
66
```
67
68
### Hex Prefix Management
69
70
Handle 0x prefix addition and removal.
71
72
```python { .api }
73
def is_0x_prefixed(value: str) -> bool:
74
"""
75
Check if string has 0x prefix.
76
77
Args:
78
value (str): String to check
79
80
Returns:
81
bool: True if string starts with '0x' or '0X'
82
"""
83
84
def add_0x_prefix(value: str) -> str:
85
"""
86
Add 0x prefix to hex string if not present.
87
88
Args:
89
value (str): Hex string
90
91
Returns:
92
str: Hex string with 0x prefix
93
"""
94
95
def remove_0x_prefix(value: str) -> str:
96
"""
97
Remove 0x prefix from hex string.
98
99
Args:
100
value (str): Hex string (with or without 0x prefix)
101
102
Returns:
103
str: Hex string without 0x prefix
104
105
Raises:
106
ValidationError: If string doesn't have 0x prefix
107
"""
108
```
109
110
## Usage Examples
111
112
### Basic Hex Operations
113
114
```python
115
from eth_utils import encode_hex, decode_hex, is_hex, is_hexstr
116
117
# Encode bytes to hex
118
data = b"Hello, World!"
119
hex_string = encode_hex(data)
120
print(hex_string) # 0x48656c6c6f2c20576f726c6421
121
122
# Decode hex back to bytes
123
decoded = decode_hex(hex_string)
124
print(decoded) # b'Hello, World!'
125
126
# Encode integer to hex
127
number = 12345
128
hex_number = encode_hex(number)
129
print(hex_number) # 0x3039
130
131
# Validation
132
print(is_hex("abc123")) # True
133
print(is_hex("xyz")) # False
134
print(is_hexstr("0x123")) # True
135
print(is_hexstr("123")) # True (hex chars, no prefix required)
136
```
137
138
### Working with Transaction Data
139
140
```python
141
from eth_utils import encode_hex, decode_hex, add_0x_prefix
142
143
# Process transaction hash
144
tx_hash_bytes = bytes.fromhex("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
145
tx_hash_hex = encode_hex(tx_hash_bytes)
146
print(tx_hash_hex) # 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
147
148
# Process contract bytecode (might come without prefix)
149
bytecode = "608060405234801561001057600080fd5b50"
150
prefixed_bytecode = add_0x_prefix(bytecode)
151
print(prefixed_bytecode) # 0x608060405234801561001057600080fd5b50
152
153
# Decode for analysis
154
bytecode_bytes = decode_hex(prefixed_bytecode)
155
print(f"Bytecode length: {len(bytecode_bytes)} bytes")
156
```
157
158
### Prefix Management
159
160
```python
161
from eth_utils import is_0x_prefixed, add_0x_prefix, remove_0x_prefix
162
163
def normalize_hex_input(hex_input):
164
"""Ensure hex string has 0x prefix."""
165
if not is_0x_prefixed(hex_input):
166
return add_0x_prefix(hex_input)
167
return hex_input
168
169
def clean_hex_for_storage(hex_input):
170
"""Remove 0x prefix for compact storage."""
171
if is_0x_prefixed(hex_input):
172
return remove_0x_prefix(hex_input)
173
return hex_input
174
175
# Usage examples
176
raw_hex = "1234abcd"
177
normalized = normalize_hex_input(raw_hex)
178
print(normalized) # 0x1234abcd
179
180
prefixed_hex = "0x1234abcd"
181
cleaned = clean_hex_for_storage(prefixed_hex)
182
print(cleaned) # 1234abcd
183
```
184
185
### Data Processing Pipeline
186
187
```python
188
from eth_utils import encode_hex, decode_hex, is_hexstr, ValidationError
189
190
def process_hex_data(data_input):
191
"""Process various hex data formats."""
192
if isinstance(data_input, bytes):
193
# Already bytes, encode to hex for display
194
return encode_hex(data_input)
195
196
elif isinstance(data_input, str) and is_hexstr(data_input):
197
# Hex string, decode and re-encode for normalization
198
try:
199
decoded = decode_hex(data_input)
200
return encode_hex(decoded)
201
except ValidationError:
202
raise ValueError(f"Invalid hex string: {data_input}")
203
204
elif isinstance(data_input, int):
205
# Integer, encode to hex
206
return encode_hex(data_input)
207
208
else:
209
raise TypeError(f"Unsupported data type: {type(data_input)}")
210
211
# Examples
212
print(process_hex_data(b"test")) # 0x74657374
213
print(process_hex_data("0x74657374")) # 0x74657374
214
print(process_hex_data("74657374")) # 0x74657374
215
print(process_hex_data(123)) # 0x7b
216
```
217
218
### Contract Address Generation
219
220
```python
221
from eth_utils import encode_hex, decode_hex, keccak, to_bytes
222
223
def create_contract_address(sender_address, nonce):
224
"""Generate contract address from sender and nonce."""
225
# Remove 0x prefix for processing
226
sender_bytes = decode_hex(sender_address)
227
228
# Encode nonce (simple case for small nonces)
229
if nonce == 0:
230
nonce_bytes = b''
231
else:
232
nonce_bytes = to_bytes(primitive=nonce)
233
234
# RLP encode (simplified for example)
235
rlp_encoded = sender_bytes + nonce_bytes
236
237
# Keccak hash and take last 20 bytes
238
hash_result = keccak(rlp_encoded)
239
contract_address = hash_result[-20:]
240
241
return encode_hex(contract_address)
242
243
# Example usage
244
sender = "0xd3CdA913deB6f67967B99D67aCDFa1712C293601"
245
contract_addr = create_contract_address(sender, 0)
246
print(f"Contract address: {contract_addr}")
247
```
248
249
### Hex String Utilities
250
251
```python
252
from eth_utils import is_hex, is_hexstr, is_0x_prefixed
253
254
def validate_hex_input(hex_string, expected_length=None):
255
"""Validate hex string input with optional length check."""
256
if not isinstance(hex_string, str):
257
raise TypeError("Input must be string")
258
259
if not is_hexstr(hex_string):
260
raise ValueError("Input is not valid hex string")
261
262
# Clean for length check
263
clean_hex = hex_string[2:] if is_0x_prefixed(hex_string) else hex_string
264
265
if expected_length and len(clean_hex) != expected_length:
266
raise ValueError(f"Expected {expected_length} hex chars, got {len(clean_hex)}")
267
268
return True
269
270
def format_hex_display(hex_string, max_length=10):
271
"""Format hex string for display with truncation."""
272
if not is_0x_prefixed(hex_string):
273
hex_string = f"0x{hex_string}"
274
275
if len(hex_string) > max_length:
276
visible_chars = max_length - 6 # Account for "0x" and "..."
277
return f"{hex_string[:2+visible_chars//2]}...{hex_string[-visible_chars//2:]}"
278
279
return hex_string
280
281
# Examples
282
validate_hex_input("0x1234") # True
283
validate_hex_input("1234") # True
284
validate_hex_input("0x1234", 4) # True (4 hex chars)
285
286
print(format_hex_display("0x1234567890abcdef1234567890abcdef")) # 0x12...ef
287
```
288
289
## Common Patterns
290
291
### Safe Hex Processing
292
293
```python
294
from eth_utils import decode_hex, encode_hex, ValidationError
295
296
def safe_hex_decode(hex_input):
297
"""Safely decode hex string with error handling."""
298
try:
299
return decode_hex(hex_input)
300
except ValidationError as e:
301
print(f"Failed to decode hex: {e}")
302
return None
303
304
def ensure_hex_format(data):
305
"""Ensure data is in hex string format."""
306
if isinstance(data, bytes):
307
return encode_hex(data)
308
elif isinstance(data, str) and is_hexstr(data):
309
return add_0x_prefix(data) if not is_0x_prefixed(data) else data
310
else:
311
raise TypeError("Cannot convert to hex format")
312
```
313
314
### Hex Data Comparison
315
316
```python
317
from eth_utils import decode_hex, is_0x_prefixed
318
319
def hex_equal(hex1, hex2):
320
"""Compare two hex strings for equality (prefix-agnostic)."""
321
# Normalize both to bytes
322
bytes1 = decode_hex(hex1)
323
bytes2 = decode_hex(hex2)
324
return bytes1 == bytes2
325
326
# Usage
327
print(hex_equal("0x1234", "1234")) # True
328
print(hex_equal("0x1234", "0x1234")) # True
329
print(hex_equal("1234", "1234")) # True
330
```