$30 off During Our Annual Pro Sale. View Details »

Solidity for NEAR

Arto Bendiken
September 13, 2022

Solidity for NEAR

We present a prototype of a toolchain for compiling Ethereum Virtual Machine (EVM) smart contracts into WebAssembly bytecode for NEAR, and discuss future directions to incorporate this functionality directly into Aurora Engine.

Arto Bendiken

September 13, 2022
Tweet

More Decks by Arto Bendiken

Other Decks in Programming

Transcript

  1. aurora.dev
    2022-09-13
    Solidity for NEAR
    Arto Bendiken

    View Slide

  2. 1. Overview
    2. History
    3. EVM to WebAssembly?
    4. Solidity for NEAR
    5. Future Directions
    Agenda

    View Slide

  3. Overview

    View Slide

  4. Aurora Engine, an L2 for NEAR Protocol
    Aurora Engine
    (EVM)
    NEAR Runtime
    (WebAssembly)
    NEAR Protocol

    View Slide

  5. NEAR Runtime
    (WebAssembly bytecode
    runtime)
    Wasmer
    (WebAssembly→x86-64 JIT)
    SputnikVM
    (EVM bytecode interpreter)
    EVM Interpretation Tower
    x86-64 CPU
    (Intel/AMD μcode JIT)

    View Slide

  6. History

    View Slide

  7. EVM Optimizations in 2021-2022
    Changes to NEAR Protocol
    ● secp256k1 ecrecover host function
    ● ripemd host function
    ● alt_bn128 host function
    ● Decrease in cost per Wasm op code
    ● Decrease in state access cost (caching
    trie nodes)
    ● Increase the per-transaction gas limit
    Changes to Aurora
    ● Cache state access
    ● Optimize for performance instead of
    code size
    Changes to SputnikVM
    ● Implement SIGNEXTEND, MLOAD, and
    MSTORE more eiciently
    ● Specialize the PUSH1 and PUSH2
    implementations (from generic PUSHN)
    ● Structure the interpreter loop more
    eiciently

    View Slide

  8. 11×
    +
    (Single-transaction EVM gas limit 153K → 1.7M)

    View Slide

  9. Kudos!
    Contributors from Aurora
    ● Michael Birch (@birchmd)
    ● Joshua Bouw (@joshuajbouw)
    ● Evgeny Ukhanov (@mrLSD)
    Contributors from NEAR
    ● Aleksey Kladov (@matklad)
    ● Nikolay Igoi (@olonho)
    ● Aleksandr Logunov (@longarithm)

    View Slide

  10. Good News, Bad News
    Averages from a sample of
    all successful transactions

    View Slide

  11. Good News, Bad News
    Averages from a sample
    of expensive (200+ Tgas)
    transactions

    View Slide

  12. EVM to WebAssembly?

    View Slide

  13. // SPDX-License-Identifier: Unlicense
    pragma solidity ^0.8.16;
    contract Counter {
    int private count = 0;
    function increment() public {
    count += 1;
    }
    function decrement() public {
    count -= 1;
    }
    function get() public view returns (int) {
    return count;
    }
    }
    increment:
    JUMPDEST
    POP
    PUSH1 0x01
    PUSH1 0x00
    SLOAD
    ADD
    DUP1
    PUSH1 0x00
    SSTORE
    PUSH1 0x00
    MSTORE
    PUSH1 0x20
    PUSH1 0x00
    RETURN
    STOP
    EVM to WebAssembly (counter.sol ⇒ counter.sol.asm)

    View Slide

  14. increment:
    JUMPDEST
    POP
    PUSH1 0x01
    PUSH1 0x00
    SLOAD
    ADD
    DUP1
    PUSH1 0x00
    SSTORE
    PUSH1 0x00
    MSTORE
    PUSH1 0x20
    PUSH1 0x00
    RETURN
    STOP
    pub fn increment() {
    evm.push1(0x01);
    evm.push1(0x00);
    evm.sload();
    evm.add();
    evm.dup1();
    evm.push1(0x00);
    evm.sstore();
    evm.push1(0x00);
    evm.mstore();
    evm.push1(0x20);
    evm.push1(0x00);
    evm.r#return()
    }
    EVM to WebAssembly (counter.sol.asm ⇒ counter.rs)

    View Slide

  15. (func $increment
    i32.const 1
    call $evm/push1
    i32.const 0
    call $evm/push1
    call $evm/sload
    call $evm/add
    call $evm/dup1
    i32.const 0
    call $evm/push1
    call $evm/sstore
    i32.const 0
    call $evm/push1
    increment:
    JUMPDEST
    POP
    PUSH1 0x01
    PUSH1 0x00
    SLOAD
    ADD
    DUP1
    PUSH1 0x00
    SSTORE
    PUSH1 0x00
    MSTORE
    PUSH1 0x20
    PUSH1 0x00
    RETURN
    STOP
    EVM to WebAssembly (counter.sol.asm ⇒ counter.wat)
    call $evm/mstore
    i32.const 32
    call $evm
    i32.const 0
    call $evm
    call $evm/return
    )

    View Slide

  16. Solidity for NEAR
    (evm2near)

    View Slide

  17. github.com/aurora-is-near/evm2near

    View Slide

  18. // SPDX-License-Identifier: Unlicense
    pragma solidity ^0.8.16;
    contract Calc {
    function multiply(int a, int b) public pure returns (int) {
    return a * b;
    }
    }

    View Slide

  19. % evm2near test/calc.sol -o test.wasm
    % near dev-deploy test.wasm
    % near view dev-1662780277695-66709124501364 \
    multiply '{"a":6, "b":7}'

    View Slide

  20. 15×
    +
    (Benchmark Solidity contract 1500 Tgas → 100 Tgas)

    View Slide

  21. Michael Birch (@birchmd)
    Arto Bendiken (@artob)
    The Compiler Team

    View Slide

  22. We are hiring Junior and Senior Compiler Engineers
    to join this deep-tech R&D team!
    Apply at auroralabs.dev under “Work at Aurora”

    View Slide

  23. Future Directions

    View Slide

  24. Expensive instructions
    ● CODECOPY
    Requires embedding a copy of the original
    EVM bytecode into the output (bloat)
    ● PC
    Requires either instrumenting generated
    code for precise program-counter
    accounting (slowdown), or embedding a
    large lookup table into the output (bloat)
    ● GAS
    Requires instrumenting generated code to
    support precise gas accounting
    (slowdown)
    Unimplemented instructions (7)
    ● CREATE
    ● CALL
    ● CALLCODE
    ● DELEGATECALL
    ● CREATE2
    ● STATICCALL
    ● SELFDESTRUCT
    EVM to WebAssembly: Some challenges

    View Slide

  25. Immediately past the MVP release
    ● Make EVM gas metering optional for a
    nice speedup when it isn’t required for
    full EVM compatibility
    ● Implement a test suite based on popular
    real-world deployed contracts and
    associated transactions, sanity
    checking that for the same inputs we
    get the same known-good outputs
    (including EVM gas metering)
    Future R&D directions past MVP
    ● Inlining EVM opcode calls for certain
    instructions where that would benefit
    ● Applying other standard compiler
    optimizations from the literature for
    leaner and meaner bytecode
    ● Adding NEAR host functions to beer
    support 256-bit machine words without
    the need for expensive bigint arithmetic
    ● Adding NEAR host functions to speed up
    other aspects of execution, based on
    extensive and convincing profiling
    results
    EVM to WebAssembly: Compiler

    View Slide

  26. Dynamically loaded WebAssembly
    embedded inside the Aurora Engine (“JIT”)
    ● Just-in-time compiled WebAssembly
    bytecode automatically deployed to,
    stored in, and maintained by the Aurora
    Engine for “hot” contracts
    ● Trusted-yet-sandboxed bytecode
    deployed reproducibly by trusted parties
    ● Zero EVM compatibility issues, just a
    significant speedup
    ● Requires a NEP process, nearcore
    implementation, and protocol upgrade
    for dynamic bytecode support (6
    months minimum)
    Standalone static NEAR contract
    deployment (“AOT”)
    ● Ahead-of-time compiled WebAssembly
    bytecode manually deployed on-chain
    on NEAR, and authenticated with the
    Aurora Engine registry by the deployer
    ● Untrusted, arbitrary bytecode deployed
    directly by third parties
    ● Some challenges and trade-os for
    interacting with other EVM contracts
    (cross-shard calls)
    ● Doesn’t require anything in particular
    from NEAR and nearcore
    EVM to WebAssembly: Execution models

    View Slide

  27. aurora.dev
    2022-09-13
    See you at NEAR Space in Bogota
    during Devcon, October 13, 2022!
    Thank you!

    View Slide