takenobu-hs
haskell-ethereum-assembly
Haskell

EVM (Ethereum virtual machine) Assembly on Haskell DSL

Last updated Apr 3, 2026
66
Stars
4
Forks
0
Issues
0
Stars/day
Attention Score
28
Language breakdown
Haskell 100.0%
Files click to expand
README

HAssembly-evm =============

EVM (Ethereum virtual machine) Assembly on Haskell DSL

This is a bytecode generator from EVM assembly on Haskell DSL.

Warning: * A big WIP * No guarantee and under testing * Experimental and conceptual project

Feature: * Composable assembly * User definable functions * Purely functional implementation * Simple and slow implementation for readability * Only a few dependent libraries and GHC extensions

Limitation: * Weak error detection and cheap error implementation * Jump size is limited to 2 bytes

Run


Command:

GHC: * $ runghc -isrc app/Main.hs

Stack: * $ stack runghc -- -isrc app/Main.hs or * $ stack build; stack exec hassembly-evm

Cabal: * $ cabal run

Example:

$ runghc -isrc app/Main.hs
  601060200100

Code example


Basic:

main :: IO ()
  main = putStrLn $ codegen prog1

prog1 :: EvmAsm prog1 = do push1 0x10 push1 0x20 add

Composable:

prog2 :: EvmAsm
  prog2 = do
      prog2a
      prog2b

prog2a = do push1 0x40 mload

prog2b = do push1 0x20 add

Pseudo instruction and built-in function:

* dest : pseudo instruction for jump destination (jump and _jumpi) * label : pseudo instruction for push with symbol (pushlabel) * jump and jumpi : jump instruction with symbol * _pushlabel : push instruction with symbol * _push : push instruction with automatic length adjustment * _raw : pseudo instruction for raw byte * _progSize : built-in function for program size * _genUniqLabel : built-in function to generate unique label

prog3 :: EvmAsm
  prog3 = do
      push1 0x60
      push1 0x40
      mstore
      _jump "target2"            -- symbol jump

push1 (_progSize prog4) -- program size _pushlabel "top1" -- push label _dest "target2" -- jump target

prog4 :: EvmAsm prog4 = do _label "top1" -- label _push 0x11234456788 -- multi length push _raw 0x7 -- raw byte _raw 0x8

Using host language (Haskell):

prog5 = do
      if isBizantinum          -- if expression on Haskell
          then prog_header1
          else prog_header2
      push1 0x60
      push1 0x40
      mstore

User defined functions and syntax:

Example1:
shiftL nbit = do    -- user defined function
      push1 nbit
      push1 2
      exp
      mul

prog6 = do mload shiftL 16 -- using push1 0x1 add

string "OK" >> log1

Example2: (examples/userSyntax.hs)

prog7 = do
      let num1 = const 0x10      -- let syntax
      let num2 = const 0x20
      let factor1 = ptr 0x05     -- memory type
      let user1   = key 0x100    -- storage type

add2(num1, num2) -- functional syntax add2(ref factor1, num1) add add2(value user1, const 3) memory(factor1) <== mul -- assignment syntax

storage(user1) <== mul2(num2, (add2(const 4, ref factor1)))

Example3: (examples/userFlow.hs)

prog8 = do
      _if (iszero) (do -- then
            push1 0x01
            push1 0x02
            add
        ) (do -- else
            push1 0x01
            push1 0x02
            sub
        )

Execute bytecode


If you need to execute a generated bytecode, please use the evm command of go-ethereum project or some tools.

Execute bytecode by evm command:

$ evm --code "601060200100" --debug run
Disasemble bytecode by evm command:
$ evm disasm sample.bytecode

Listing and pretty printing


Simple listing:

Use pprList function:

main :: IO ()
  main = putStrLn $ pprList prog1   -- using pprList

prog1 :: EvmAsm prog1 = do ...

Output example:

$ runghc -isrc examples/pprList.hs
  000000: push1 0x10
  000002: push1 0x20
  000004: add
  000005: stop

Under implementation ...


Pretty-print for Solidity:

$ runghc -isrc examples/PprSol.hs
  {
      0x10
      0x20
      add
      stop
      pop
  }

Stack hight checking:

$ runghc -isrc examples/StackCheck.hs
  Final stack-hight: 0

See also


* Ethereum Yellow Paper * Go Ethereum * The Solidity Contract-Oriented Programming Language * Ethereum EVM illustrated

© 2026 GitRepoTrend · takenobu-hs/haskell-ethereum-assembly · Updated daily from GitHub