Glaze

Posted on Nov 05, 2023Read on Mirror.xyz

Blockchain ❤️ WASM: Chapter Arbitrum

Arbitrum recently announced Stylus VM upgrade. It claims to have the following feature:

  • Support more languages

  • Lower fee, lower memory consumption

  • Custom pre-compilers

  • Interoperability with EVM

All these features are brought by the integration of WASM. WASM has lots of advantages and is widely used in the cloud native scenario. We will expand the story of WASM in the later sections.

Pioneers

Arbitrum is not the first one to bring WASM on-chain. Before Arbitrum, Polkadot enabled users to write WASM smart contracts. It provides two languages to write WASM smart contracts, one assembly scripts like embedding DSL and another is Rust-like language ink!.

Cosmos also employs CosmWasm as its smart contract runtime. Developer's can use Rust to write smart contracts.

Before diving deep into why blockchain ❤️ WASM, let's see how Cosmos and Polkadot explains their choice to WASM.

Cosmos claims WASM can bring the following benefits:

  • Compatible with Rust libraries

  • Diverse dev community

  • Security, prevent reentrancy attacks

  • Easy test

  • High performance

Polkadot’s WASM runtime has the following features:

  • High performance

  • Interoperability with EVM

  • Platform agnostic

  • Small size

  • Support Rust and Assembly Script(Typescript style)

There are some advantages shared across Polkadot, Cosmos and Arbitrum brought by WASM, but there is something unique for Arbitrum. We will cover more details about Arbitrum and Cosmos in the last part.

WASM

What is WASM

To understand why blockchain x WASM, we need to understand what is WASM and the initiative behind WASM.

WebAssembly (WASM) is a binary format that allows code to run at near-native speed in web browsers. It's a compilation target for languages like C and Rust, designed to be fast, efficient, and secure. WASM bridges the gap between web and system-level programming, enhancing web performance and capabilities.

WASM get name Web because it can run in JS, commonly browser environment. In JS, developers can access full WASM API. WASM also got full Web API supports. In WASM, developers can control the Web behavior.

WASM History

WASM is designed with the principle of writing once and running anywhere.

Back in 2016, lots of programs released new functions through Domain Specific Language(DSL). Making a DSL needs to make tradeoff between maintenance, efficiency and safety. However people are looking for a new way to deliver new functions to countless servers which needs maintenance, efficiency and safety.

They examine different solutions from top to bottom. Here are people’s concerns about these solutions:

  • System Virtual Machines

    • Too much overhead for spinning up/down frequently

    • Lack visibility into code for ensuring safety

    • Too abstracted/high level for the performance needs

  • Containers

    • Lack of visibility into code for ensuring safety

    • Too high level/abstracted for performance needs

    • much overhead for spinning up/down frequently

  • Language-level virtual machine

    • Frequent VM modifications required for safety

    • Overhead of embedding VMs like V8

    • Slow to adapt new languages to the VM's security model

    • Still high level

  • Instruction set architectures (ISAs)

    • Very difficult to modify ISA code for sandboxing efficiently

    • Prior project at Google moved away from it to WASM

    • Lacked mature implementations to use

This is the background for WASM to be true. People start to develop WASM compiler till 2018. WASM developers expand the idea of write once and run anywhere. They would like to run on different architectures, run in servers and embedded hardware, even other languages. They don’t want to make another Java, which sacrifices safety.

In 2019, the component model was created to wrap WASM modules and raise their interfaces to a higher level, enabling cross-language interoperability between components. For example, this allowed them to write an HTTP library once and share it across languages. The component model solved long-standing problems in a novel way.

Till know, WASM has lots of cool features. WASM now is heavily used in the cloud native scenario. Blockchain somehow is also one use case under cloud native. WASM has following advantages:

  • High performance

  • Low binary size

  • Portability: WASM provides portability at the instruction set level, allowing the same bytecode to run across any WASM runtime.

  • Support C/C++, Rust, AssemblyScript, C#, Dart, F#, Go, Kotlin, Swift. D, ascal, Zig, Grain

  • Run in JS engine

  • Sandbox: WASM provides a much stronger sandbox by default, with limitations on memory, CPU, etc. to prevent access outside of its sandbox.

  • WASM has very fast startup, often milliseconds or less.

The WASM community is still working hard to bring more integration and cross-language performance.

Stylus

After thinking about the initiative of WASM and WASM applications on other blockchains, let’s go back and think about Arbitrum Stylus’s limitation.

How Stylus works

  1. The developer compiles their smart contract to WASM using an off-the-shelf WASM compiler like Clang or Rustc.

  2. The WASM bytecode is uploaded to the Arbitrum chain in compressed form.

  3. The contract owner calls the compileProgram method of the ArbWasm precompile, which instruments the WASM for security, meters it for gas costs, and compiles it to native code optimized for the validator's hardware.

  4. When the contract is called, it runs on a WASM runtime like Wasmer much faster than the EVM, saving gas costs.

The third steps looks extra, but it is necessary to build for performance and security reason. Compile WASM code to native machine code can speed up the execution. Adding extra compilation step can also avoid compile bomb.

A "compile bomb" is a type of malicious code that is designed to consume excessive resources during the compilation process, causing the compiler to crash or hang. It is a form of denial-of-service attack that can be used to disrupt software development processes.

Popular concern about Stylus

Language Support

Stylus can help Arbitrum to expand their dev community to C++ and Rust while it still cannot reach the most popular dev community nowadays. It opens up the door for smart contracts executed in the browser environment, but JS and Python is still not supported.

There are early stage projects bring Python and JS to WASM, but it is not ready for massive adoptions because of garbage collection objects implementation and performance issue.

Language Compatibility

Stylus current supports C/C++ and Rust SDK. It works well with these languages tools. Developers can also bring some third party libraries, like some native cryptography implementation while building smart contracts. The only limit for these is gas cost.

The Rust SDK is still in the early stage. There are some missing features for Rust and C SDK. C SDK does not support ABI export function. Modifiers are not supported in both SDK.

Local Stylus test environment is not supported yet, but developers can directly run test in SDKs. To run smart contracts in Stylus, testnet is the only way. Smart contract verification is not supported by the testnet yet.

People is bringing differet ERC token and Uniswap V2 to Stylus.

Language Choice

Use DSL, embedding DSL or general programming language is a hard choice. Developers need to make tradeoff between building close to the metal for control or higher level abstractions that are easier to use but limit flexibility.

Building a brand new DSL also takes time to develop toolchains and ecosystem. eDSL is a sublanguage of a general programming language, sharing same semantics and syntax. With eDSL, it can leverage existing language and tools, lower learning curve compared learning a new DSL, good Interoperability between DSL and general purpose code. For example, for reaching the most developers, making a JS, Python eDSL make sense. General programming languages require developers to use SDK to make development. This introduces extra tooling, more verbosity, less expressiveness and length API call and object operations.

Picking a right language and make an eDSL may be a right mix. It attracts people from popular dev community and provide easy-to-use tools. From the data below, we see the top crypto developer community is still Ethereum. Polkadot, Cosmos and Solana, which use Rust for smart contract also attract well amount of people. They also have a really fast growing speed on total developers

Performance

WASM can greatly increase the execution speed and decrease the bundle size. Although Stylus is not on mainnet yet, we can see benchmark on other network as reference.

The execution time is shorten 4-8x. The compiled size is reduced by 2x.

There is currently a limit on the size of Stylus contracts, around 128KB uncompressed. It will be difficult to port very large smart contracts from other languages like Solidity. You can find in the Stylus codebase.

// arbos/programs/programs.go

const MaxWasmSize = 128 * 1024
const initialFreePages = 2
const initialPageGas = 1000
const initialPageRamp = 620674314 // targets 8MB costing 32 million gas, minus the linear term
const initialPageLimit = 128      // reject wasms with memories larger than 8MB
const initialInkPrice = 10000     // 1 evm gas buys 10k ink
const initialCallScalar = 8

Notice that WASM has some overhead on spinning on and off. If you are coding something really light, EVM may be cheaper than WASM.

Interoperability with EVM

EVM and WASM shares the same storage slots and state tire. Stylus has interoperability with EVM because there are EVM API implemented in WASM. This is done through the popular Host I/O mode in WASM. Here is a full supported list for EVM API in WASM. It looks like the interoperability is fully supported.

read_args
write_result
storage_load_bytes32
storage_store_bytes32
call_contract
delegate_call_contract
static_call_contract
do_call
create1
create2
do_create
read_return_data
return_data_size
emit_log
account_balance
account_codehash
evm_gas_left
evm_ink_left
block_basefee
block_coinbase
block_gas_limit
block_number
block_timestamp
chainid
contract_address
msg_reentrant
msg_sender
msg_value
native_keccak256
tx_gas_price
tx_ink_price
tx_prigin
memoery_grow
console_log_text
console_log
console_tee

Custom Precompiles

This one is more exciting. Noone has done this before. We can bring more crypto primitives on-chain with a much lower execution cost. For on-chain ML, we can bring tensor computation as precompiles to lower the inference cost. However, I do not see any relevant code about custom precompiles. We see the precompiles for the EVM part, but is not hot swappable.

I believe these part are stilling implemented with the power of WASM. EVM can call functions written in WASM which can be compiled down to machine code.

Reentrant

Unlike CosmWasm which uses an actor model to provide contract call and does not provide reentrant functionality, Stylus Rust SDK set reentry as a feature flag and it is default set as off. Developers can manually enable the reentry functionality.

Introducing reentrancy with the default feature flags on will change the API a bit, since developers have to be careful to flush the storage cache when making calls, among other safety considerations.

Conclusion

WASM is an emerging technology gaining traction in the cloud-native space. Numerous blockchains are integrating WASM for their smart contract runtimes. While Arbitrum is not the first to do so, it could be the most significant. WASM cannot completely change the blockchain world and substitute EVM, but WASM has the potential to enhance Arbitrum's competitiveness against upcoming zk-rollups. I like how Arbitrum call this EVM+. EVM is the floor for smart contract runtime and WASM can bring some extra power for Arbitrum.

Arbitrum