1. Who am I?
● Sean Young
● Maintainer of Burrow at Monax
● Maintainer of consumer IR and DVB in linux kernel
● Interested in compilers and reverse engineering
Compiling Solidity to WASM
using solang
2. Solidity/EVM today
EVM is the Virtual Machine, Solidity the source language
Simple high-level language inspired by JavaScript
All arithmetic and memory operations are 256 bit
Only Solidity supports EVM, no other languages
string/per-byte processing difficult
More accurate gas cost
Not amenable to JIT function foo(string owner) {
if (owner == "root") {
// does not compile
}
if (sha256(owner) == sha256("root")) {
// recommended solution
}
}
3. WASM
WASM is a general, low-level virtual machine
Ability to JIT and great implementations exist
Arithmetic is 32 and 64 bit
Memory can be accessed in all the usual ways
32 bit and 64 floats do exist – not deterministic
Has fantastic tooling available
4. Why have Smart Contracts in WASM?
Support for languages other than Solidity
Linking Solidity with other languages:
Cryptography in Smart Contracts
Re-use existing libraries (e.g. BPM)
Efficient data structures
Improving the Solidity Language
Re-use existing tooling (llvm compiler kit)
How to do 256 integer arithmetic on 64 bit VM?
5. Existing Solidity compiler
Huge C++ project
Handwritten lexer/parser
Handwritten optimiser (YUL)
EVM output is not optimal
6. What is solang?
Small, clean implementation of Solidity
Written in rust
Generated lexer and parser
Use llvm:
Wonderful optimiser
Writes wasm binary format
Solves 256 bit integer problem
Includes linker (e.g. C or rust modules)
Fraction of the code base
Proper string processing and string formatting possible
7. Where is solang today?
$ cargo install solang
Hyperledger Labs project
Incomplete Solidity language support
Supports intN, uintN, bool, enum types
Supports if/else, for, while
Supports contract storage
ABI compatible with Solidity/EVM
Supported in Hyperledger Burrow 0.27.0
8. Running solang with Burrow today
Install burrow 0.27.0
Install solang (cargo install solang)
When deploying contracts, specify –wasm
Entirely transparent: solang will be used instead solc and
WASM VM rather EVM
burrow deploy –wasm -v Root_0 deploy.yaml
9. Solang implementation
Traditional compiler construction. The stages are:
1)Lexer and parser produces Abstract Syntax Tree (AST)
2)AST is decorated (resolved) and transformed into Control
Flow Graph (CFG)
3)CFG is mapped to LLVM IR
4)Call LLVM optimiser and generate and link
10. 1) Lexer and parse stage
Parser is generated from Solidity grammar using lalrpop
Outputs AST tree, with symbols locations so we can
provide locations on error and warning messages
Mostly generated
11. 2) Resolve and Control Flow Graph
Walks the contracts in the AST
Generates CFG for statements
Resolves variables, functions
and types (e.g. enums)
# solang –emit-cfg
foo:
x = 100
y = bar * 100
C = y > 100
brcond c, bar1, bar2
bar1:
a = y + 200
return a
bar2:
b = y << 4
return b
12. 3) Translate to LLVM IR
Intermediate Representation of
code used LLVM
Mapping from CFG to LLVM IR
should be mostly 1-to-1
Also generates ABI
encoder/decoder
solang –emit-llvm
solang –-emit-llvm foo.sol
; ModuleID = 'bar'
target triple = "wasm32-unknown-unknown-wasm"
define i32 @foo(i32, i32) {
entry:
%2= add i32 %0, 100
%3= icmp sgt i32 %1, 0
br i1 %3, label %then, label %else
then: ; preds = %entry
%4= mul i32 %1, 100
%5= add i32 %2, %4
br label %endif
else: ; preds= %entry
%6= add i32 %1, 10
br label %endif
endif: ; preds= %else, %then
%x= phi i32 [ %5, %then ], [ %6, %else ]
reti32 %x
}
13. 4) LLVM generate and link
Call LLVM optimizating passes
Call LLVM code generate
Result: WASM object file
Need to link into final contract
Currently done in rust, can be done by LLVM linker too
solang --no-link
14. Future: solang linking against C, etc
LLVM LTO linker can link against wasm objects:
C:
clang --target=wasm32 -c -O3 -Wall foo.c
solang contract.sol –link foo.o
15. Next steps for solang
Make compatible with eWASM
More data types: string, bytes, struct, mapping, arrays
Other language features: modifiers, external calls, imports,
interfaces
Testcases
Get involved!