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 |
BatchExecutor¶
For parallel transaction execution.
BatchConfig¶
@dataclass
class BatchConfig:
max_threads: int = 8
enable_parallel: bool = True
enable_speculation: bool = False
chain_id: int = 1
block_number: int = 0
block_timestamp: int = 0
block_gas_limit: int = 30000000
coinbase: str | bytes = None
BatchTransaction¶
@dataclass
class BatchTransaction:
from_addr: str | bytes
to_addr: str | bytes = None
value: int | bytes = 0
data: bytes = b""
gas_limit: int = 21000
gas_price: int | bytes = 0
nonce: int = None
BatchStats¶
@dataclass
class BatchStats:
total_transactions: int
successful_transactions: int
failed_transactions: int
reverted_transactions: int
total_gas_used: int
execution_time_ns: int
parallel_waves: int
max_parallelism: int
Methods¶
Constructor¶
set_account¶
def set_account(self, address: str | bytes, balance: int = 0,
nonce: int = 0, code: bytes = None) -> None
Set account state.
set_storage¶
Set storage slot.
execute¶
Execute transactions in parallel.
get_results¶
Get individual transaction results.
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()
Parallel Execution¶
from zigevm import BatchExecutor, BatchConfig, BatchTransaction
config = BatchConfig(
max_threads=8,
enable_parallel=True,
chain_id=1,
block_number=12345678,
)
executor = BatchExecutor(config)
# Set up accounts
for i in range(10):
executor.set_account(
address=f"0x{'%040x' % i}",
balance=100 * 10**18,
)
# Create transactions
transactions = [
BatchTransaction(
from_addr=f"0x{'%040x' % (i % 10)}",
to_addr=f"0x{'%040x' % ((i + 1) % 10)}",
value=1 * 10**18,
gas_limit=21000,
)
for i in range(1000)
]
# Execute
stats = executor.execute(transactions)
print(f"Transactions: {stats.total_transactions}")
print(f"Parallel waves: {stats.parallel_waves}")
print(f"Speedup: {stats.max_parallelism}x")
# Check results
for result in executor.get_results():
if not result.success:
print(f"Tx {result.tx_index} failed: {result.error_code}")
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 == 1: # OutOfGas
print("Increase gas limit")
elif result.reverted:
print(f"Reverted: {result.return_data}")
else:
print(f"Error: {result.error_name}")
except Exception as e:
print(f"FFI error: {e}")
finally:
evm.destroy()
Address Formats¶
Addresses can be specified in multiple formats:
# Hex string with 0x prefix
evm.set_address("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
# Hex string without 0x
evm.set_address("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
# bytes
evm.set_address(bytes.fromhex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
Value Formats¶
Values can be specified as: