moonia picture

moonia/posts

🌉 Bridging Virtual Machines: Building an Ethereum Bytecode Interpreter in Gno.land


During my internship at Gno.land (New Tendermint), I undertook a technically ambitious challenge: developing a proof-of-concept Ethereum Virtual Machine interpreter that runs entirely within the Gno.land environment.

The goal was to bridge two fundamentally different blockchain paradigms (Ethereum and Gno.land) unlocking new possibilities for interoperability and contract portability.

What started as a curiosity about how virtual machines work quickly grew into a full-fledged bytecode interpreter. This interpreter can run Solidity-compiled EVM bytecode straight within Gno.land. Along the way, I learned not just how the EVM operates under the hood, but also how closely you can mimic its behavior inside a totally different runtime.

> Understanding the Foundations : Ethereum vs. Gno.land

Before I go into the architecture of the interpreter, let’s step back and look at what exactly we’re trying to bridge.

> The Ethereum Virtual Machine

The EVM is Ethereum's computation engine. It runs on every Ethereum node, ensuring that smart contracts are executed deterministically across the network. That means if two nodes run the same bytecode with the same inputs, they’ll always produce the same result.

The EVM is a stack-based virtual machine, operating on 256-bit words. It includes:

Each contract is compiled from a high-level language like Solidity into bytecode, which is then deployed on-chain and executed via this model.

> The Gno.land Vision

Gno.land is a platform built for collaborative, open-source-style smart contract development. Instead of Solidity, contracts here are written in Gno, a language derived from Go, interpreted by the GnoVM.

The Gno.land ecosystem is structured around two types of packages:

What makes Gno.land unique is that it doesn't just run your logic, it also renders the output directly as markdown in the UI. That means your contracts don’t just execute, they also interact with users live, in the browser, with real-time feedback. Everything is on-chain, inspectable, and forkable. Imagine writing a contract, seeing the output live, forking it, tweaking it, and publishing your own version—all without leaving the chain.

> The Idea: EVM Inside Gno

So the big question was: Can we replicate the EVM, and run Ethereum bytecode directly inside the GnoVM?

Spoiler: yes. But it required some creative architecture.

> Bridging the Gap: Architecture of the EVM Interpreter

To replicate EVM execution inside Gno.land, we architected the system around two principal components:

  1. Realm Interface (User Layer)

    This acts as the frontend for users to upload and execute EVM bytecode. It simulates Ethereum-like accounts with balances, manages transaction submissions, displays state changes, and offers step-by-step visual debugging.

  2. Pure Package (EVM Engine)

    The core interpreter lives here. It implements more than 140 EVM opcodes, handles stack and memory operations, manages persistent storage, and ensures deterministic execution within GnoVM constraints.

These components work together to form a self-contained Ethereum-like execution environment, mapped directly into Gno.land’s infrastructure.

> The Execution Cycle: Fetch, Decode, Execute

At the heart of the interpreter lies a tightly controlled three-phase cycle that mirrors Ethereum’s real-world execution model.

Execution begins by fetching the next instruction from the bytecode, using the program counter (PC). For instance, in the bytecode sequence 6080604052..., the first byte 0x60 is fetched.

The byte is then decoded into an opcode. In this case, 0x60 corresponds to PUSH1, meaning the following byte is a value to be pushed onto the stack.

During the execution phase, the interpreter pushes the value (here, 0x80) onto the stack and advances the program counter accordingly. This process continues instruction by instruction, until the program halts due to a STOP, RETURN, REVERT, or runtime error.

EVM Cycle

> Modeling EVM Structures Inside Gno.land

Accurate EVM emulation involves careful tracking of key data structures: the stack, memory, and storage.

The stack is a Last-In-First-Out structure with a capacity of 1024 elements, each 256 bits wide. All arithmetic, logic, and control operations rely on it.

Memory is byte-addressable, volatile, and expands dynamically during execution. Although Ethereum applies gas penalties for memory growth, this interpreter simulates that behavior for completeness.

Storage is persistent across transactions and unique to each contract. In the interpreter, it is modeled as a 256-bit key-value store attached to each simulated account.

Additional components, including the program counter, validated jump destinations, transaction context, and simulated gas tracking, are all managed to reflect EVM semantics as accurately as possible.

> Error Handling and Edge Case Detection

An interpreter isn’t just about “what it can do.” It’s also about what it must refuse to do.

The interpreter includes strict safeguards to prevent incorrect behavior. It detects stack underflows and overflows, rejects invalid jump destinations, halts on unrecognized opcodes, and protects against out-of-bounds memory access.

Each opcode implementation was tested against tricky edge cases, using reference tools like evm.codes.

This wasn’t just about functionality, it was about faithfulness to Ethereum’s semantics.

> Developer Experience: A Full Debugging Environment

The Gno.land interpreter offers more than just raw execution. Through the Realm interface, developers can:

EVM Ui

This level of transparency is rare in Ethereum development, where bytecode often remains a black box unless deployed and monitored via external tooling.

> Practical Applications and Technical Value

This project unlocks new use cases beyond just emulation. With EVM compatibility on Gno.land, Ethereum contracts can be tested or even executed without modification. This makes it possible to experiment with cross-chain deployments, perform compatibility testing, and migrate contracts progressively across ecosystems.

It also serves as a powerful tool for education, offering a clear view into how high-level Solidity code translates into low-level operations and how those operations affect blockchain state.

> The End

By reimplementing the EVM within Gno.land, this project demonstrates that blockchain execution models are portable and that interoperability is achievable at the virtual machine level. The success of this proof-of-concept lays the groundwork for a future where smart contracts are not bound to a single ecosystem. Whether used for development, debugging, migration, or education, the EVM interpreter in Gno.land is a tool for exploring what it means to run code across blockchains and what it takes to make them speak the same language.


Useful references that helped shape this post:

> https://ethereum.github.io/yellowpaper/paper.pdf
> https://www.evm.codes/