Decoding the Engines of Decentralization

A Comparison of EVM and WASM

 

Blockchains and their virtual machines go together like gears and engines — each powers and defines the performance, capabilities, and efficiency of the other. But not all engines are created equal.

The concept of a virtual machine was pioneered with the introduction of the Ethereum Virtual Machine (EVM) in 2013. To this day, the EVM still remains the most popular smart contract execution environment, but the tides have shifted considerably. Notably, the EVM carries inherent flaws and limitations that have provoked developers to create alternative VMs designed to address and rectify many of these issues. As a result, some of these alternative VMs continue to slowly but surely chip away at the EVM’s market share.

The decentralized computing space is evolving even more rapidly than ever, and it’s crucial to understand the functionalities and limitations of different VM architectures. A good place to start is to compare the Ethereum Virtual Machine to WebAssembly and its own VM variant.

The EVM: Features and Limitations

The EVM is the most popular and widely-known smart contract execution environment. First introduced by Ethereum, it soon became adopted by numerous other blockchains wanting to build out a comprehensive creator toolchain and garner a community of smart contract developers. However, despite its many innovations, it comes with some inherent challenges and functional limitations. This is especially important in today’s ecosystems where growing demand for more advanced and scalable dApps is the norm.

To understand where these limitations begin, we must understand the EVM’s fundamental architecture. From a design standpoint, the EVM is a stack-based state machine that interprets and executes bytecode instructions. As it processes smart contract code, the EVM uses the data stack to hold operands and operation results in real time. One of the EVM’s primary issues, however, is that it is subject to specific stack constraints.

The EVM stack has a maximum depth of 1024 items and a native data size of 256-bit words. This native data size means that all data items on the stack are represented as 256-bit integers, which does not take into account instances where the actual data might be smaller. This architectural flaw leads to the idea of stack overflow. The limited stack depth of 1024 items significantly affects the complexity of smart contracts that can be run, as these contracts often rely on multiple layers of function calls, each of which may require pushing data onto the stack.

Take recursive functions, for instance. When a recursive function is executed on the EVM, each recursive call pushes new items onto the stack, such as the return address, local variables, and any intermediate results. If the recursion depth is too high, these items can quickly fill up the stack. Once the stack reaches its limit, no more items can be added, leading to a stack overflow, which causes the transaction to fail with an out-of-gas error or an invalid opcode error. Consider a simple recursive function that calculates the factorial of a number — each recursive call multiplies the current number by the factorial of the number minus one. As the recursion deepens, each call adds more data to the stack. If the number is large enough, the EVM will exhaust its 1024-item stack capacity, resulting in a stack overflow and transaction failure.

 

Recursive Factorial Operation on the Data Stack (source: Lucila M. | LinkedIn)

 

Moreover, there’s another architectural issue present here. The 256-bit word size is functionally incompatible with most modern CPUs, which are usually designed with word sizes of 32 or 64 bits. When a processor needs to handle data larger than its native word size (including the EVM’s 256-bit words), it’s forced to break this task down into smaller components. For example, a 64-bit processor would typically break down a 256-bit operation into four separate 64-bit parts to tackle one-by-one. The issue here, of course, is the significant increase in computational overhead required. Not only does this result in greater computational effort, but also longer execution times and higher resource consumption, all of which ultimately translate into excessive fees and longer wait times for users.

Even more importantly, the arithmetic overflow or underflow from this issue can create serious smart contract vulnerabilities. Looking at Ethereum’s history, there are numerous instances where malicious entities exploited these vulnerabilities, resulting in substantial losses in user funds.

Interpretation Over Compilation

When we look at smart contract execution specifically, the EVM functions as an interpreter for EVM bytecode, representing another significant drawback to the system. In contrast to a compiler, which translates the entire source code into machine code before execution, an interpreter executes code directly by reading and performing each instruction line by line without converting it to machine code ahead of time. With a compiler method, the program would convert the bytecode into native machine code, making it directly executable by the CPU of the host machine. Instead, the EVM reads each opcode, translates it into a series of lower-level operations, and then executes these operations using the host machine’s resources. Once again, the problem here is that this interpretation process adds significant overhead and is slower in its execution compared to a native compiler program.

 

Compiler vs. Interpreter Models (source: HomeTown)

 

Gas is Fee, Fee is Key

Because running EVM nodes is computationally expensive, Ethereum users must compensate network validators for every resource they consume. The EVM uses a gas cost table that defines each opcode’s gas fee. Because it’s built into the Ethereum protocol, it ensures consistent gas calculations across all nodes. The model itself is brilliant because it allows for Turing-complete computation on a fully decentralized VM. Turing-completeness in this sense refers to the ability of a system to perform any computation that can be defined algorithmically (given enough time and resources). By attaching a cost to each operation, the EVM gas model ensures that all units of computational effort have a predictable cost while allowing all algorithmic logic to be executed.

Despite its robust framework, the model has some challenges. Each opcode performs tasks with varying levels of computational complexity and resource demands, making it difficult to design an accurate gas computation method for different EVM opcodes. As a result, the gas cost calculation in the EVM is suboptimal, with users paying only an approximate estimate of the actual resources consumed during execution.

Flexibility Constraints

Lastly, one of the EVM’s biggest functional limitations is its lack of flexibility. The EVM includes fixed precompiles that are hardcoded into the system. These precompiles enhance computational efficiency, particularly for tasks like cryptographic operations (hashing). However, the downside is that these precompiles cannot be easily updated, extended, or replaced with newer, more efficient algorithms. This inflexibility limits developers to using the existing set of operations, which can hinder innovation and adaptation to changing computational needs. Modifying or adding new precompiles in the EVM requires a hard fork, requiring consensus among the entire Ethereum community.

WebAssembly (WASM)

In light of the EVM’s limitations, there are now numerous computational models that boast promising improvements. One such model is WebAssembly (WASM).

At its core, WASM is a binary instruction format designed to execute code at near-native speeds. The beauty of WASM is that it can be run independently of the programming languages used to create it, allowing it to run efficiently on different platforms. Simply put, it enables high-level languages to be run on any platform that supports the WASM runtime.

With respect to the actual virtual machine, a clarification should be made here. WASM itself is the format for compiled code that is executed. The format provides a way to package and deliver binary instructions, which can then be run on any environment that is WASM-compatible. This differs conceptually from a WASM VM, which is the actual runtime model (the virtual machine) that executes the respective WASM code.

Design and Execution Model

With the EVM, the instruction set is relatively high-level. Many of its operations are tackled through more complex instructions that require additional computational overhead to decode and execute. In contrast, WASM is designed as a low-level, highly efficient format that aligns more closely with the machine code used by modern CPUs. This lower-level design minimizes the overhead associated with decoding and executing instructions, as the translation from bytecode to hardware-level commands is much simpler and more direct. As a result, WASM VMs can run code at speeds close to native execution; this speed is crucial for the performance-intensive demands of blockchain applications.

There’s also a clear advantage to the WebAssembly execution model. Unlike the EVM, which processes each instruction in the bytecode sequentially (interpretive execution), WASM VMs can take advantage of Just-In-Time (JIT) and Ahead-Of-Time (AOT) compilation. These compilation methods transform WASM bytecode into native machine code dynamically at runtime. This approach can significantly boost execution speed compared to the step-by-step (line-by-line) interpretation used by the EVM. What’s more, JIT and AOT compilation enables the WASM VM to implement runtime optimizations, fine-tuning the machine code for the specific hardware it’s running on. This leads to even greater execution efficiency, a result the interpretive nature of the EVM cannot achieve.

Bit Size Matters

In contrast to the EVM’s 256-bit native word size, WASM VMs utilize the more standard 32 and 64-bit word sizes. This means that these virtual machines match the capabilities of modern processors, allowing them to leverage the full power of the host’s CPU rather than dividing computations into groups like an EVM machine would require. This also solves the stack overflow (or underflow) issue and ultimately results in faster and more efficient smart contract execution.

Performance isn’t the only area that matters, though. Robust support for multiple high-level languages is a key characteristic that gives WASM another edge over the EVM. This capability stems from WebAssembly’s design as a compilation target for multiple high-level programming languages. Most popular languages can be compiled to WASM using modern compiler infrastructures, creating a flexibility that allows a broader range of developers to enter the blockchain space, as they can use languages they are already familiar with. For example, C and C++ can be compiled to WASM using Emscripten, a useful compiling tool.

The Interoperability Promise

Perhaps most significant, WASM offers notable advantages over the EVM in terms of interoperability. This is primarily due to its platform and language-agnostic design. In the context of a blockchain, the WASM VM allows for the compilation of smart contracts that can theoretically operate across any environment (with minimal modifications) as long as it supports the WASM runtime.

Take Polkadot, for example. It leverages a WASM-based VM to execute smart contracts on its parachains, while still allowing each parachain to customize its own VM settings. This happens even while all parachains are unified by WASM as the common execution layer. This setup enables smart contracts created for one parachain to be easily adapted and deployed on another.

 

Polkadot Parachains and WASM Execution (source: Polkadot)

 

Polkadot’s architecture showcases how parachains are interconnected through the Relay Chain and share a common execution environment provided by WASM. This allows parachains to maintain their own unique characteristics while benefiting from the security, interoperability, and scalability of the broader Polkadot network. The use of WASM as the execution layer is crucial because it allows for flexibility and compatibility across different programming languages and platforms. It makes it easier to deploy and run smart contracts across these various parachains with minimal modifications.

The Path Forward

As the most widely adopted virtual machine, the EVM has pioneered decentralized computing from its initiation. While powerful, it has shown its limitations in performance, scalability, and flexibility. These constraints have driven the development and adoption of many alternative VMs like WebAssembly, which boast their own unique advantages.

WASM VMs stand ahead due to their high efficiency and flexibility, delivering performance that is close to native execution speeds while supporting a wide range of high-level languages. This combination has made WASM particularly appealing for several emerging blockchain projects that prioritize both high performance and cross-platform compatibility. Additionally, WASM’s low-level architecture is well-suited to modern CPU designs. This minimizes computational overhead and boosts execution efficiency.

As blockchain technology continues to evolve, we’ll no doubt continue to see the development of new and innovative VMs. This will be crucial in pushing the boundaries of what decentralized technologies can achieve. Future machines are likely to focus on enhancing performance, scalability, and security, while also broadening support for diverse programming languages and development environments. These advancements will enable more complex and efficient smart contract execution, driving the next wave of innovation in decentralized networks.

Previous
Previous

Fully Homomorphic Encryption

Next
Next

The Overvaluation of Network Effects