diff --git a/README.md b/README.md index 8f31a7f..624f5e4 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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). diff --git a/wasm-engines.md b/wasm-engines.md new file mode 100644 index 0000000..7509675 --- /dev/null +++ b/wasm-engines.md @@ -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, +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: + +``` +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.