Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/takenobu-hs/haskell-ethereum-assembly

EVM (Ethereum virtual machine) Assembly on Haskell DSL
https://github.com/takenobu-hs/haskell-ethereum-assembly

assembly-language ethereum ethereum-virtual-machine evm haskell

Last synced: 4 months ago
JSON representation

EVM (Ethereum virtual machine) Assembly on Haskell DSL

Awesome Lists containing this project

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:

```bash
$ runghc -isrc app/Main.hs
601060200100
```

Code example
------------

#### Basic:

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

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

#### Composable:

```Haskell
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

```Haskell
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):

```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:

```Haskell
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)

```Haskell
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)

```Haskell
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](https://github.com/ethereum/go-ethereum) of go-ethereum project or some tools.

Execute bytecode by evm command:

```bash
$ evm --code "601060200100" --debug run
```
Disasemble bytecode by evm command:

```bash
$ evm disasm sample.bytecode
```

Listing and pretty printing
---------------------------

#### Simple listing:

Use `pprList` function:

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

prog1 :: EvmAsm
prog1 = do ...
```

Output example:

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

Under implementation ...
------------------------

#### Pretty-print for Solidity:

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

#### Stack hight checking:

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

See also
--------

* [Ethereum Yellow Paper](https://github.com/ethereum/yellowpaper)
* [Go Ethereum](https://github.com/ethereum/go-ethereum)
* [The Solidity Contract-Oriented Programming Language](https://github.com/ethereum/solidity)
* [Ethereum EVM illustrated](https://github.com/takenobu-hs/ethereum-evm-illustrated)