Skip to content

evmdasm assembler

tintin edited this page Oct 20, 2018 · 6 revisions

EvmProgram - assembler interface

Easily compile and manipulate evm bytecode using the EvmProgram interface. There's two ways to add instructions. Either via high-level abstractions that automatically pushes call args on the stack or the low level interface.

high-level interface

p = EvmProgram()
p.push(<data>)  # will create matching PUSHx instructions
p.call(arg1,arg2,arg2,...)  # will push the args to stack and then create a CALL instruction

low-level interface

p = EvmProgram()
p.op("PUSH1")  # does not set the operand
p.op("JUMPDEST")
p.op("JUMPDEST").op("JUMPDEST").op("JUMPDEST")

p._program[0].operand = "1"  # set the operand of the first instruction (PUSH1)

example

p = EvmProgram()
p.push(1)
p.push(0x0101)
p.op("JUMPDEST")
p.push(0xc0fefe)
#call.args: T.Gas("gas"), T.Address("address"), T.CallValue("value"), T.MemOffset("inOffset"), T.Length("inSize"), T.MemOffset("retOffset"), T.Length("retSize")
p.call(1,2,3,4,5,6,7)

# access and manipulate instructions
p._program  # EvmInstructions([ Instruction(name=PUSH, ...), ...])

# assemble the program 
assembled = p.assemble()  # EvmBytecode() 

# print as hexstring
assembled.as_hexstring  # "60016101015b62c0fefe6001600260036004600560066007f1"

# disassemble the the bytecode
disassembled = assembled.disassemble()   #  EvmInstructions([Instruction, ...])

# print the listing
disassembled.as_string

"""
    PUSH1 01
    PUSH2 0101
    JUMPDEST 
    PUSH3 c0fefe
    PUSH1 01
    PUSH1 02
    PUSH1 03
    PUSH1 04
    PUSH1 05
    PUSH1 06
    PUSH1 07
    CALL
"""

Clone this wiki locally