Python API Reference¶
Complete API reference for the Python bindings.
Installation¶
Or after building the library:
EVM Class¶
Constructor¶
Create a new EVM instance.
Methods¶
destroy¶
Destroy EVM and free resources.
Warning
Always call destroy() when done to prevent memory leaks.
reset¶
Reset execution state (keeps accounts).
set_gas_limit¶
Set the maximum gas for execution.
set_block_number¶
Set the current block number.
set_timestamp¶
Set the block timestamp.
set_chain_id¶
Set the chain ID.
set_coinbase¶
Set the coinbase address.
set_address¶
Set the current contract address.
set_caller¶
Set the caller address (msg.sender).
set_origin¶
Set the transaction origin (tx.origin).
set_value¶
Set the call value in wei.
set_balance¶
Set an account's balance.
Parameters: - address: Account address (hex string or bytes) - balance: Balance in wei
set_code¶
Set an account's bytecode.
set_storage¶
Set a storage slot value.
get_storage¶
Get a storage slot value.
Returns: 32-byte value
execute¶
Execute EVM bytecode.
Parameters: - code: EVM bytecode - calldata: Optional input data
Returns: EVMResult with execution results
get_return_data¶
Get return data from last execution.
get_logs¶
Get logs emitted during execution.
Properties¶
gas_used¶
Gas used in last execution.
gas_remaining¶
Gas remaining after last execution.
stack_depth¶
Current stack depth.
memory_size¶
Current memory size in bytes.
Debugging Methods¶
stack_peek¶
Peek at stack value without removing.
Parameters: - index: Stack index (0 = top)
Returns: 32-byte value or None
memory_read¶
Read bytes from memory.
EVMResult¶
@dataclass
class EVMResult:
success: bool
error_code: int
error_name: str
gas_used: int
gas_remaining: int
return_data: bytes
reverted: bool
| Field | Type | Description |
|---|---|---|
success | bool | Whether execution succeeded |
error_code | int | Error code (0 = success) |
error_name | str | Human-readable error name |
gas_used | int | Gas consumed |
gas_remaining | int | Gas remaining |
return_data | bytes | Data from RETURN opcode |
reverted | bool | Whether REVERT was called |
Log¶
| Field | Type | Description |
|---|---|---|
address | bytes | 20-byte contract address |
topics | list[bytes] | 0-4 topics (32 bytes each) |
data | bytes | Log data |
Batch / Parallel Execution¶
The Python wrapper (bindings/python/zigevm/__init__.py) only exposes EVM, EVMResult, EVMError, and Log. Batch execution is implemented in the C ABI (batch_create, batch_execute, etc. in include/zigevm.h) but is not yet surfaced through the Python bindings. To use parallel execution today, call the C ABI directly via ctypes or use the C FFI Reference.
Examples¶
Basic Execution¶
from zigevm import EVM
evm = EVM()
evm.set_gas_limit(100000)
# PUSH1 3, PUSH1 5, ADD, STOP
code = bytes([0x60, 0x03, 0x60, 0x05, 0x01, 0x00])
result = evm.execute(code)
print(f"Success: {result.success}")
print(f"Gas used: {result.gas_used}")
evm.destroy()
Working with Storage¶
from zigevm import EVM
evm = EVM()
evm.set_gas_limit(100000)
address = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
evm.set_address(address)
# Set storage
evm.set_storage(address, 0, 42)
# SLOAD slot 0
code = bytes([0x60, 0x00, 0x54, 0x00])
result = evm.execute(code)
# Check stack
value = evm.stack_peek(0)
print(f"Value: {int.from_bytes(value, 'big')}") # 42
evm.destroy()
Reading Logs¶
from zigevm import EVM
evm = EVM()
evm.set_gas_limit(100000)
# Execute code that emits logs
result = evm.execute(code)
for log in evm.get_logs():
print(f"Address: 0x{log.address.hex()}")
for i, topic in enumerate(log.topics):
print(f" Topic {i}: 0x{topic.hex()}")
print(f" Data: 0x{log.data.hex()}")
evm.destroy()
Error Handling¶
from zigevm import EVM
evm = EVM()
evm.set_gas_limit(100) # Very low gas
try:
result = evm.execute(expensive_code)
if not result.success:
if result.error_code == EVMError.OUT_OF_GAS:
print("Increase gas limit")
elif result.reverted:
print(f"Reverted: {result.return_data}")
else:
print(f"Error: {result.error_code}") # IntEnum, str() yields name
except Exception as e:
print(f"FFI error: {e}")
finally:
evm.destroy()
Address and Value Formats¶
The current Python wrapper expects:
- Addresses as raw 20-byte
bytes(usebytes.fromhex("aaaa...")) - Balances / values as Python
int(converted to 32-byte big-endian internally) - Storage keys / values as 32-byte
bytes(shorter values are left-padded with zeros by_to_bytes32)