Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
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
- Host: GitHub
- URL: https://github.com/takenobu-hs/haskell-ethereum-assembly
- Owner: takenobu-hs
- License: bsd-3-clause
- Created: 2018-03-23T13:37:15.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2018-07-22T11:55:33.000Z (over 6 years ago)
- Last Synced: 2024-09-30T06:04:39.209Z (4 months ago)
- Topics: assembly-language, ethereum, ethereum-virtual-machine, evm, haskell
- Language: Haskell
- Homepage:
- Size: 43 KB
- Stars: 67
- Watchers: 6
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: ChangeLog.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ethereum-virtual-machine - HAseembly-evm
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 projectFeature:
* Composable assembly
* User definable functions
* Purely functional implementation
* Simple and slow implementation for readability
* Only a few dependent libraries and GHC extensionsLimitation:
* Weak error detection and cheap error implementation
* Jump size is limited to 2 bytesRun
---#### 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 prog1prog1 :: EvmAsm
prog1 = do
push1 0x10
push1 0x20
add
```#### Composable:
```Haskell
prog2 :: EvmAsm
prog2 = do
prog2a
prog2bprog2a = do
push1 0x40
mloadprog2b = 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 jumppush1 (_progSize prog4) -- program size
_pushlabel "top1" -- push label
_dest "target2" -- jump targetprog4 :: 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
mulprog6 = do
mload
shiftL 16 -- using
push1 0x1
addstring "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 typeadd2(num1, num2) -- functional syntax
add2(ref factor1, num1)
add
add2(value user1, const 3)
memory(factor1) <== mul -- assignment syntaxstorage(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)