Martin Becze github.com/wanderer
Alex Beregszaszi github.com/axic
A generality in software development is axiom or low level feature that can be used to implement two or more desired high level features
You know you have a useful generality when axiom or set of axiom not only encompasses the desired high level features but also reduces implementation complexity
Potential new precompiles in Metropolis (hard fork):
Later hard forks:
Also SHA3 as an instruction and not as a precompile
Current IPC methods:
Upcoming new IPC methods:
Current arithmetics:
Upcoming arithmetics:
Big Trusted Computing bases are really bad for symmetric computation platform
Footnote: Interesting read "Big Ball of Mud" on Wikipedia.
WebAssembly or wasm is a new, portable, size- and load-time-efficient binary format that aims to execute at native speed by taking advantage of common hardware capabilities available on a wide range of platforms.
www.w3.org/community/webassembly
(module (import $useGas "ethereum" "useGas" (param i32)) (memory 1) (export "memory" memory) (export "main" $main) (func $main (local $sp i32) (local $jump_dest i32) (set_local $sp (i32.const -32)) (set_local $jump_dest (i32.const -1)) (loop $done $loop (block $1 (block $0 (br_table $0 (if (i32.eq (get_local $jump_dest) (i32.const -1)) (then (i32.const 0)) (else (unreachable))))) (call_import $useGas (i32.const 6)) (if (i32.gt_s (get_local $sp) (i32.const 32672)) (then (unreachable))) (call $PUSH (i64.const 0) (i64.const 0) (i64.const 0) (i64.const 96) (get_local $sp)) (set_local $sp (i32.add (get_local $sp) (i32.const 32))) (call $PUSH (i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0) (get_local $sp)) (set_local $sp (i32.add (get_local $sp) (i32.const 32)))))))
0061 736d 0b00 0000 0474 7970 6500 0140 0201 0101 0108
6675 6e63 7469 6f6e 0001 0002 0665 7870 6f72 7400 0100
0206 6164 6454 776f 0463 6f64 6500 0100 0014
0000000: 0061 736d ; WASM_BINARY_MAGIC 0000004: 0b00 0000 ; WASM_BINARY_VERSION ; section "type" 0000008: 04 ; string length 0000009: 7479 7065 ; section id: "type" 000000d: 00 ; section size (guess) 000000e: 01 ; num types ; type 0 000000f: 40 ; function form 0000010: 02 ; num params 0000011: 01 ; param type 0000012: 01 ; param type 0000013: 01 ; num results 0000014: 01 ; result_type ; section "function" 0000015: 08 ; string length 0000016: 6675 6e63 7469 6f6e ; section id: "function" 000001e: 00 ; section size (guess) 000001f: 01 ; num functions 0000020: 00 ; function 0 signature index 000001e: 02 ; FIXUP section size ; section "export" 0000021: 06 ; string length 0000022: 6578 706f 7274 ; section id: "export" 0000028: 00 ; section size (guess) 0000029: 01 ; num exports 000002a: 00 ; export func index 000002b: 06 ; string length 000002c: 6164 6454 776f ; export name ; section "code" 0000032: 04 ; string length 0000033: 636f 6465 ; section id: "code" 0000037: 00 ; section size (guess) 0000038: 01 ; num functions ; function body 0 0000039: 00 ; func body size (guess) 000003a: 00 ; local decl count 000003b: 14 ; OPCODE_GET_LOCAL
e^WASM
Metering is decoupled from the VM
st=>start: raw wasm
e=>end: run
op=>operation: Validate
op2=>operation: Injection Metering
cond=>condition: Yes or No?
st->op->op2->e
Gas cost is based on the cycle count of the instructions.
"Gas cost oracle": The gas cost table is stored in a contract.
SHA256 performance (of 8kb data):
Glueing all this together
Defines the Ethereum blockchain methods for contracts:
A total of 32 methods.
(call_import $storageLoad (i32.const 0) (i32.const 32))
;; ^ key offset in memory
;; ^ result offset in memory
Simples.
Defines the format of contracts:
Drumroll:
(module
(memory 1
(segment 0 "Hello World!")
)
(import $return "ethereum" "return" (param i32 i32))
(export "main" $main)
(func $main
(call_import $return (i32.const 0) (i32.const 12))
)
)
Sentinel
evm2wasm!
EVM1 precompiled contracts
Only 3 new rules for a client:
Check contract code for eWASM signature
Use evm2wasm to transcompile if needed
Use sentinel contract during contract creation
ewasm-kernel
Hera
clang & ewasm-libc
#include "ethereum.h"
#define BASE_FEE 60
#define WORD_FEE 12
void main() {
size_t datasize = ethereum_calldatasize();
unsigned char data[datasize];
unsigned char ret[32] = { 0 };
ethereum_calldatacopy(data, 0, datasize);
ethereum_usegas(BASE_FEE + (((datasize + 31) / 32) * WORD_FEE));
mbedtls_sha256(data, datasize, ret, 0);
ethereum_return(ret, 32);
}
Input:
contract A {
function a() {
throw;
}
function b() payable returns (uint64) {
uint64 x = 42;
return x;
}
}
Output:
;; Contract: A
(module
(import $callDataCopy "ethereum" "callDataCopy" (param i32 i32 i32))
(import $getCallValue "ethereum" "getCallValue" (param i32))
(import $return "ethereum" "return" (param i32))
(memory 1 1)
(export "memory" memory)
(export "main" $main)
(func $main
(call_import $callDataCopy (i32.const 0) (i32.const 0) (i32.const 4))
(call $dispatcher (i32.load (i32.const 0)))
(unreachable)
)
(func $ensureNotPayable
(call_import $getCallValue (i32.const 0))
(if (i64.ne (i64.const 0) (i64.load (i32.const 0)) (unreachable))
(if (i64.ne (i64.const 0) (i64.load (i32.const 8)) (unreachable))
)
(func $dispatcher
(param $sig i32)
(if (i32.eq (get_local $sig) (i32.const 0x0dbe671f)) (then (call $__0dbe671f)))
(if (i32.eq (get_local $sig) (i32.const 0x4df7e3d0)) (then (call $__4df7e3d0)))
(unreachable)
)
;; function: a()
(func $__0dbe671f
(call $ensureNotPayable)
(block
(unreachable)
)
)
;; function: b() payable
(func $__4df7e3d0
(block
(local $x (param i64))
(set_local $x (i64.const 42))
(i64.store (i32.const 0) (i64.const 0))
(i64.store (i32.const 8) (i64.const 0))
(i64.store (i32.const 16) (i64.const 0))
(i64.store (i32.const 24) (get_local $x))
(call_import $return (i32.const 0) (i32.const 32))
)
)
)
See more awesome details at https://github.com/ewasm
Error: Out-Of-Gas!