CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyevmasm

Ethereum Virtual Machine (EVM) assembler and disassembler library for working with EVM bytecode and assembly instructions

Pending
Overview
Eval results
Files

assembly.mddocs/

Assembly Operations

Convert EVM assembly language to bytecode with comprehensive support for individual instructions, multiple instruction sequences, and complete programs. Supports all Ethereum hard forks and provides both binary and hexadecimal output formats.

Capabilities

Single Instruction Assembly

Assemble a single EVM instruction from its textual representation, with support for operands and program counter positioning.

def assemble_one(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> Instruction:
    """
    Assemble one EVM instruction from its textual representation.

    Parameters:
    - asmcode (str): Assembly code for one instruction (e.g., "PUSH1 0x40", "ADD")
    - pc (int, optional): Program counter of the instruction. Default: 0
    - fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")

    Returns:
    Instruction: An Instruction object with complete metadata

    Raises:
    AssembleError: If assembly fails due to invalid instruction or operand
    """

Usage Examples:

from pyevmasm import assemble_one

# Simple instruction without operand
add_instr = assemble_one("ADD")
print(f"Opcode: 0x{add_instr.opcode:02x}")  # 0x01

# Instruction with operand
push_instr = assemble_one("PUSH1 0x40")
print(f"Operand: 0x{push_instr.operand:x}")  # 0x40
print(f"Bytes: {push_instr.bytes.hex()}")     # 6040

# With program counter
jump_instr = assemble_one("JUMPI", pc=100)
print(f"PC: {jump_instr.pc}")  # 100

Multiple Instruction Assembly

Assemble a sequence of EVM instructions from multiline assembly code, returning a generator of Instruction objects.

def assemble_all(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK):
    """
    Assemble a sequence of textual representation of EVM instructions.

    Parameters:
    - asmcode (str): Assembly code for any number of instructions, separated by newlines
    - pc (int, optional): Program counter of the first instruction. Default: 0
    - fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")

    Returns:
    Generator[Instruction]: A generator of Instruction objects

    Raises:
    AssembleError: If assembly fails for any instruction
    """

Usage Examples:

from pyevmasm import assemble_all

# Assemble multiple instructions
assembly_code = '''
PUSH1 0x80
PUSH1 0x40
MSTORE
PUSH1 0x4
CALLDATASIZE
LT
'''

instructions = list(assemble_all(assembly_code))
for instr in instructions:
    print(f"{instr.pc:08x}: {instr}")

# With custom starting PC
instructions = list(assemble_all(assembly_code, pc=0x1000))
print(f"First instruction PC: 0x{instructions[0].pc:x}")  # 0x1000

Binary Assembly

Assemble EVM assembly code directly to binary bytecode format.

def assemble(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> bytes:
    """
    Assemble an EVM program to binary bytecode.

    Parameters:
    - asmcode (str): An EVM assembler program
    - pc (int, optional): Program counter of the first instruction. Default: 0
    - fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")

    Returns:
    bytes: The binary representation of the bytecode

    Raises:
    AssembleError: If assembly fails
    """

Hexadecimal Assembly

Assemble EVM assembly code to hexadecimal string representation, the most common format for EVM bytecode.

def assemble_hex(asmcode: str, pc: int = 0, fork: str = DEFAULT_FORK) -> str:
    """
    Assemble an EVM program to hexadecimal bytecode.

    Parameters:
    - asmcode (str): An EVM assembler program
    - pc (int, optional): Program counter of the first instruction. Default: 0
    - fork (str, optional): Fork name. Default: DEFAULT_FORK ("istanbul")

    Returns:
    str: The hex representation of the bytecode (prefixed with "0x")

    Raises:
    AssembleError: If assembly fails
    """

Usage Examples:

from pyevmasm import assemble, assemble_hex

assembly_code = '''
PUSH1 0x60
PUSH1 0x40
MSTORE
PUSH1 0x2
PUSH2 0x100
'''

# Get binary bytecode
binary_code = assemble(assembly_code)
print(f"Binary length: {len(binary_code)} bytes")

# Get hex bytecode (most common)
hex_code = assemble_hex(assembly_code)
print(f"Hex: {hex_code}")  # "0x606040526002610100"

# Can also assemble from instruction list
from pyevmasm import assemble_all
instructions = list(assemble_all(assembly_code))
hex_from_list = assemble_hex(instructions)
print(f"Same result: {hex_code == hex_from_list}")  # True

Assembly Syntax

PyEVMAsm supports standard EVM assembly syntax:

  • Instructions: Standard EVM mnemonics (ADD, SUB, PUSH1, etc.)
  • Operands: Hexadecimal values with 0x prefix (PUSH1 0x40)
  • Line separation: Newlines separate instructions
  • Comments: Not supported in assembly input
  • Case sensitivity: Mnemonics are case-insensitive but conventionally uppercase

Fork-Specific Assembly

Different Ethereum forks support different instruction sets. PyEVMAsm handles this automatically:

from pyevmasm import assemble_hex

# This works in byzantium and later
code = assemble_hex("RETURNDATASIZE", fork="byzantium")

# This would fail in earlier forks
try:
    code = assemble_hex("RETURNDATASIZE", fork="frontier")
except AssembleError:
    print("RETURNDATASIZE not available in frontier fork")

# Constantinople introduced new shift operations
code = assemble_hex("SHL", fork="constantinople")  # Works

Install with Tessl CLI

npx tessl i tessl/pypi-pyevmasm

docs

assembly.md

disassembly.md

fork-management.md

index.md

instruction-analysis.md

tile.json