This is solang, a new proof of concept solidity compiler. The existing solidity compiler is a huge C++ code base which implements its own parser, optimizer and handling of binary files.
The idea here is that we use standard tooling like a parser generator, llvm for its optimizer and handling of wasm binary files and use rust. As result, only the compiler frontend needs to be written. This will be a much smaller codebase which is hopefully more maintainable than the existing solidity compiler.
In addition we will have a solidity compiler which supports wasm, which allows the ethereum community to move away from the EVM. This, in turn, allows us to improve the solidity language in ways not easily implemented in EVM, like string concatenation or string formatting.
This is really just a starting point. So far, we can compile the following solidity contract:
```solidity contract test3 { function foo(uint32 a) returns (uint32) { uint32 b = 50 - a; uint32 c; c = 100 * b; c += 5; return a * 1000 + c; }
function bar(uint32 b, bool x) returns (uint32) {
uint32 i = 1;
if (x) {
do {
i += 10;
}
while (b-- > 0);
} else {
uint32 j;
for (j=2; j<100; j++) {
i *= 3;
}
}
return i;
}
function baz(uint32 x) returns (uint32) {
for (uint32 i = 0; i<100; i++) {
x *= 7;
if (x > 200) {
break;
}
x++;
}
return x;
}
} ```
The parser is fairly complete. The resolve/annotate stage and LLVM IR conversion stage need work.
Required: - rust 1.33.0 or higher - llvm libraries with the WebAssembly target enabled.
To check if your llvm installation has the WebAassmebly backend, run
llc --version
. It should list the wasm32 target.
sudo dnf install cargo llvm-static llvm-devel zlib-devel clang glibc-devel.i686
sudo apt install curl llvm git zlib1g-dev
Then use rustup to install the latest stable rust.
You will need the llvm libs, compiled with the WebAssembly backend/target.
The output of llc --version
must include wasm32 - WebAssembly 32-bit
. If
it does, then cargo build
will suffice. If not, then follow the steps
below.
The Fedora 29 and Ubuntu 18.04 llvm package does not include this; on Ubuntu 18.10 you are in luck, and you should not need to build your own llvm libraries.
You need the following dependencies on Ubuntu:
sudo apt install cmake ninja-build subversion build-essential
You can run the build-llvm.sh
shell script to download llvm, compile it and
then build solang. This will place the built llvm in the llvm/ directory.
Once you have the llvm libraries built, make sure you have llvm-config in your path whenever you execute a cargo command. This will ensure that the right version is used.
For now, solang just parses each command line argument as a solidity file and produces a contractname.wasm for each contract in all solidity files specified.
Run:
cargo run test/compiles.sol
This compiles this contract:
```solidity contract test3 { function foo(uint32 a) returns (uint32) { uint32 b = 50 - a; uint32 c; c = 100 * b; c += 5; return a * 1000 + c; }
function bar(uint32 b, bool x) returns (uint32) {
uint32 i = 1;
if (x) {
do {
i += 10;
}
while (b-- > 0);
} else {
uint32 j;
for (j=2; j<100; j++) {
i *= 3;
}
}
return i;
}
function baz(uint32 x) returns (uint32) {
for (uint32 i = 0; i<100; i++) {
x *= 7;
if (x > 200) {
break;
}
x++;
}
return x;
}
} ```
And you will have a test3.wasm file generated for the test3 contract in this solidity contract.
``` $ wasm-objdump -d test3.wasm
Code Disassembly:
test3.wasm: file format wasm 0x1
Code Disassembly:
00006c
assembly {}
statements,
these will most likely never be implemented. llvm does support inline assembly,
so we can (in theory) support wasm inline assembly.Have a look at our TODO or find us on the burrow channel on Hyperledger Chat.