Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation on Binaryen and Wabt #141

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ You don't need any special infrastructure to transact on the Ewasm testnet. You

Voila! You're now ready to transact on the testnet.

## Writing and compiling smart contracts
## Writing, compiling, and deploying smart contracts

### Solidity/EVM

Expand Down Expand Up @@ -95,6 +95,12 @@ At present, we've developed support for the following languages and toolchains:

If you're interested in adding support for another language, framework, or toolset, see the Contributing section above and reach out.

### Deploying contracts to the testnet

Ewasm contracts can be deployed using [ewasm studio](http://ewasm.ethereum.org/studio/), which requires the contract code in WebAssembly Text Format. If you want to deploy a Wasm binary, [this guide](./wasm-engines.md) explains how to use Binaryen or Wabt to disassemble WebAssembly Binary Format (`wasm`) into WebAssembly Text Format (`wast`).

Once the contract is in `wast` format you can deploy it using ewasm studio: the field `Destination Address` should be blank, set any value in the `Value (Wei)` field, and paste the `wast` code in the `Contract Code (WAST)` field. Then hit "SUBMIT TRANSACTION" to deploy.

## Running a testnet node locally

The testnet currently only supports the [go-ethereum](https://github.com/ethereum/go-ethereum) (geth) client. Support for aleth (formerly, cpp-ethereum) is a work in progress and more information may be found [here](aleth.md).
Expand Down
216 changes: 216 additions & 0 deletions wasm-engines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
# Wasm Engines

[Binaryen](https://github.com/WebAssembly/binaryen.git) and
[Wabt](https://github.com/WebAssembly/wabt.git) are two [official WebAssembly
Projects](https://github.com/WebAssembly/) providing a set of tools to interact
with WebAssembly.

Wabt's focus is on the manipulation of WebAssembly binary files (`wasm`) and
text format (`wast`) and conversion between the two formats. Binaryen provides a
compiler and toolchain infrastructure library for WebAssembly. It aims to make
compiling to WebAssembly easy and provides a C API, internal IR, and optimizer.
Similar to Wabt, binaryen also provides a set of tools to interact with
WebAssembly binary files and WebAssembly in
[text format](https://github.com/WebAssembly/design/blob/master/TextFormat.md).
The rest of this document explains how to use these tools to work with Ewasm
contracts.

By default, [Hera](https://github.com/ewasm/hera) ships with binaryen support,
hugo-dc marked this conversation as resolved.
Show resolved Hide resolved
but it can also be compiled with wabt support. See
[build options](https://github.com/ewasm/hera#build-options) for more information.

Binaryen's and Wabt's WebAssembly text formats are not fully compatible with each
other, so if you decompile a `wasm` contract using `wasm-dis` (binaryen) you may
not be able to compile the resulting `wast` back to `wasm` using `wat2wasm`
(Wabt). For compatibility purposes, the same wasm engine used by Hera should be
used to generate the `wasm` or `wast` files.

# Binaryen

## Getting and compiling binaryen

Make sure development tools are already installed (cmake, make, C++ compiler).
Instructions can be found [here](./README.md#manual-configuration).

Clone the official binaryen repository:

```
git clone https://github.com/WebAssembly/binaryen.git
```

Move to the new `binaryen` directory and run this command to build the tools:
hugo-dc marked this conversation as resolved.
Show resolved Hide resolved

```
cmake . && make
```

Now you have the following binaryen tools compiled in the `bin/` directory. A
description of each tool can be found
[here](https://github.com/WebAssembly/binaryen#tools).

More information on how to build binaryen can be found in the [master repository](https://github.com/WebAssembly/binaryen#building).

## Using binaryen tools

In this section we show how to use some of the binaryen tools:

### wasm-as

This tool allows to compile WebAssembly Text Format (wast) to
WebAssembly Binary Format (wasm). Example: We have a file called
`contract.wast` containing this wast code:

```wast
(module
(import "ethereum" "storageStore" (func $storageStore (param i32 i32)))
(import "ethereum" "getCodeSize" (func $getCodeSize (result i32)))
(memory 1)
(export "main" (func $main))
(export "memory" (memory 0))
(func $main
(i32.store (i32.const 32) (call $getCodeSize))
(call $storageStore (i32.const 0) (i32.const 32))))
```

Running `./wasm-as contract.wast` will generate a `contract.wasm` file.

### wasm-dis

You can take `contract.wasm` or any other `.wasm` file generated by another
compiler and convert it to WebAssembly Text format (`wast`). Example: running
`./wasm-dis contract.wasm -o new_contract.wast` will create the following wast
code:

```wast
(module
(type $0 (func (param i32 i32)))
(type $1 (func (result i32)))
(type $2 (func))
(import "ethereum" "storageStore" (func $fimport$0 (param i32 i32)))
(import "ethereum" "getCodeSize" (func $fimport$1 (result i32)))
(memory $0 1)
(export "main" (func $0))
(export "memory" (memory $0))
(func $0 (; 2 ;) (type $2)
(i32.store
(i32.const 32)
(call $fimport$1)
)
(call $fimport$0
(i32.const 0)
(i32.const 32)
)
)
)
```

Note it is not _exactly_ the same code we wrote in the first place, it is more
verbose and the variable names have changed as it was generated based on the wasm binary file.

### wasm-shell

This tool allows you to execute wast files.

Example: This WebAssembly program contains two functions, `main` and `sum`.
`sum` receives two parameters `$a` and `$b` and returns the sum of both
parameters. `main` calls `sum` using `2` and `3` as parameters, then calls a
`wasm-shell` provided function called `$print` to show the result.

```wast
(module
(import "spectest" "print" (func $print (param i32)))
(memory 1)
(export "main" (func $main))
(export "memory" (memory 0))
(func $main
(call $print (call $sum (i32.const 2) (i32.const 3))))
(func $sum (param $a i32) (param $b i32) (result i32)
(return (i32.add (get_local $a) (get_local $b)))))
```

You can execute this code by calling the command: `./wasm-shell --entry main
mycode.wast`, and you will get the following result:

```
BUILDING MODULE [line: 1]
(i32.const 5)
```

Note that you cannot currently execute ewasm contracts using `wasm-shell` because the
`ethereum` namespace is not provided.

# Wabt

## Getting and compiling wabt

Clone the wabt repository and its submodules:

```
git clone --recursive https://github.com/WebAssembly/wabt.git
cd wabt
```

Execute `make`

```
make
```

After successfully executing this command, a new `bin` directory is created
containing the wabt tools. A description of the wabt tools can be found [here](https://github.com/WebAssembly/wabt#wabt-the-webassembly-binary-toolkit).

## Using Wabt tools

### wat2wasm

Similar to `wasm-as`, above, `wat2wasm` can be used to compile wast code to a wasm binary.

Consider this ewasm contract:

```wast
(module
(import "ethereum" "storageStore" (func $storageStore (param i32 i32)))
(import "ethereum" "getCodeSize" (func $getCodeSize (result i32)))
(memory 1)
(export "main" (func $main))
(export "memory" (memory 0))
(func $main
(i32.store (i32.const 32) (call $getCodeSize))
(call $storageStore (i32.const 0) (i32.const 32))))
```

Running `./wat2wasm contract.wast` generates a new binary file called `contract.wasm`.

### wasm2wat

Similar to `wasm-dis`, above, this tool allows us to decompile the wasm file back into text format:

```
./wasm2wat contract.wasm -o my_contract.wat
```

In this case we specify an output file `my_contract.wat` in order to not
overwrite the original `wast` file.

This is the content of the new generated wast code:

```wast
(module
(type (;0;) (func (param i32 i32)))
(type (;1;) (func (result i32)))
(type (;2;) (func))
(import "ethereum" "storageStore" (func (;0;) (type 0)))
(import "ethereum" "getCodeSize" (func (;1;) (type 1)))
(func (;2;) (type 2)
i32.const 32
call 1
i32.store
i32.const 0
i32.const 32
call 0)
(memory (;0;) 1)
(export "main" (func 2))
(export "memory" (memory 0)))
```

As with `wasm-dis`, note this is not _exactly_ the same code we wrote as it was generated based on the wasm binary file.