EVM Part I: The ABCs of Ethereum Virtual Machine

EVM Part I: The ABCs of Ethereum Virtual Machine
Design by Tanya Vijaykar

EVM in 100 words

The Ethereum Virtual Machine can simply be understood as an isolated environment specifically designed to process smart contract transactions as well as, most importantly, determine the overall state of the Ethereum blockchain with every new block that gets mined.

Imagine EVM as a computer that specializes in handling smart contract transactions as well as defining the rules for state changes from block to block in the Ethereum blockchain.

However, unlike physical computers, EVM is a virtual machine that is not bound to a single operating system or location, thus allowing global accessibility for anyone willing to run an Ethereum node.


Alright, there you go. EVM is now explained in precisely 100 words. Go ahead, count it 😃

Let's start Deciphering EVM

Now it's time to dive in just a bit deeper into EVMs.

If you have ever tried to understand and read about EVM before, you might have come across different ways in which EVM is defined. For instance:

  • EVM is a Virtual Machine …
  • EVM is a State Machine …
  • EVM is a Quasi-Turing complete machine…

I believe the best way to understand EVM effectively is to decipher each of these statements about EVM.

So, let’s get started

EVM as a Virtual Machine...

To begin with, let’s start with the VM(virtual machine) part of the EVM.

Let’s roll back and forget about Ethereum and even virtual machines.

Let’s talk about Physical machines.

Physical machines can simply be understood as the hardware that runs on your computer like the x86, ARM, or, perhaps your favorite, the new Apple M1. It's important to note that the lowest level of instruction, for a physical machine, is Binary. Basically just Zeros and Ones.

The physical machines perform actions based on their interpretation of these binary opcode instructions themselves.

Now, Virtual machines are very similar to physical machines as they too have opcodes to perform specific tasks. Some virtual machines you might know are JVM, LLVM, etc.

However, a crucial difference is a fact that these virtual machines, although they are quite similar to physical machines, aren’t tied to any physical hardware.

This means that virtual machines provide a runtime environment but are completely platform agnostic. It allows compatibility across a wide variety of systems, irrespective of the underlying hardware.

Alright, now that we understand VMs, it won't be hard to grasp the Ethereum virtual machine.

EVM is a virtual machine which means it can run on multiple hardware irrespective of the underlying platform/OS. This is quite crucial as it plays a major role in enabling decentralization since we can run EVM on as many platforms as we want.

In fact, the EVM is what makes Ethereum so interesting and sort of revolutionary because we now have the power to execute any arbitrary code on a blockchain.

In the pre-EVM era, this would have been a nightmare as a new blockchain with custom logic had to be created every time a new app with specific use case was to be built.

Thus, EVM is a virtual machine that provides us with a completely virtual runtime execution environment for processing smart contract transactions and has global accessibility where anyone with any hardware can easily run this virtual machine.

EVM as a State Machine...

As previously discussed, in the 100-word EVM intro, one of the essential goals of EVM is to determine the state of the Ethereum blockchain, hence the state machine.

But what exactly are State machines?

State machine, in very simpler terms, is a device that specializes in storing state as well as defining the rules of state changes of a particular system.

It can change(transition) its state from one to another depending on the inputs provided to it. See

Now, considering the world of Ethereum, the state refers to an extensive data structure that keeps all the accounts, i.e., Externally-owned accounts (EOAs) or Contract Accounts(more on this later), linked together by hashes.

In other words, every detail on the Ethereum blockchain, i.e., the amount of ERC20 tokens you hold, governance proposals and their vote counts, NFT ownership, etc, are technically different states on the network. These states are reducible to a single root hash or, as we call it, the World State.

This world state of Ethereum basically represents the current state of the entire blockchain which comprises all the historical states that together form this current state hash.

Now it's important to note that even the slightest change in any of the accounts (EOA or Contract Accounts), leads to a change/transition in the world state. This means with every single transaction that is mined, be it your NFT ownership change or a governance proposal being executed, leads to a change in the overall state of the chain. Read more about Ethereum's world state in this article.  

In a nutshell, every successfully executed transaction, irrespective of how big or small, leads to a change in the Ethereum state.

Fig.1a-Source: ethereum.org
And this is all possible because EVM acts as a state machine.

Well, why is this important?

EVM being a state machine plays a significant role in making the Ethereum blockchain so effective.

If we take a quick look at the Bitcoin blockchain, we will find that it's a distributed ledger that is quite strict in its state transitions. Transactions on the bitcoin blockchain lead to global state transitions that mainly track or record the ownership of the native currency(BTC).

While on the other hand, Ethereum being a distributed state machine provides much more than that.

Instead of simply recording the currency ownership states, it has the power to transition to a new state in response to an arbitrary smart contract input data as well.

This is incredibly significant because such flexibility in the state transitions is what allows us to create custom currencies(ERC-20 tokens), NFTs, complicated Defi protocols, or even a complete DAO using smart contracts.

EVM as a Quasi-Turing Complete Machine...

Alright, so per our usual approach, let’s forget about Ethereum or EVM and only focus on the Quasi-Turing Complete part.

Actually, just focus on the Turing Complete part.

Turing Complete refers to the kind of machine that enables running a program that can answer/solve any computational problem, irrespective of the time or memory it takes to do so.

In other words 👇

Yes, that’s Alan Turing who coined the idea of Turing Completeness 😃

For instance, languages like C, C++, or Java are turing complete systems.

Well, now comes the obvious question - Can the Ethereum blockchain be considered a Turing Complete system?

Well, yeah sure. (But read the whole thing, there's a catch)

It's turing complete as it can execute any program similar to a turing machine and can read as well as write data to memory. In fact, turning complete plays a significant role in allowing Ethereum to run arbitrary logic via smart contracts, which other blockchains are incapable of.

However, there lies a caveat with the turning-completeness of Ethereum that cannot be overlooked. Here comes the catch.

If you recall the nature of Turing machine systems, they can basically run forever and use infinite memory.

In the world of Ethereum, though, we cannot really have programs that run forever or uses infinite memory.

While regular computers can simply halt such infinitely running programs, we cannot do the same with Ethereum as it's a global computer(and a distributed ledger) that must be accessible/online at all times.

Now, in order to avoid the halting issue in Ethereum, it includes a specific type of limitation in the computational steps for any smart contract execution. It imposes this limitation using the concept of Gas.
Check out this article by Consensys to learn more about the fundamentals of Gas in Ethereum.

This means the EVM keeps track of every instruction that is to be executed and charges a particular amount of Gas fees (in ETH) for every computation or storage being used in the transaction. In other words, if you run out of gas (basically money) you can no more execute the transaction, thus resolving the issue of transactions/computations that run infinitely.

In simpler terms, Ethereum is indeed a Turing complete system. However, it does impose limitations using gas which doesn't really allow this system to include forever running computations or those that use infinite storage.

Therefore, while EVM doesn't belong completely in the category of a Turing-Complete system, we call it a Quasi-Turing Complete System.


Understanding the crucial components of EVM & Ethereum

EVM can be considered a machine with a simple stack-based architecture.

In order to effectively understand the working mechanism of EVM, we must understand some of its most crucial components and their responsibilities.

However, before diving into EVM components, I feel it's important to touch base on some fundamental concepts of the Ethereum blockchain.

🟢
Note: These fundamental concepts will help us understand EVM components better.
However, feel free to skip them if you are already aware of them.

Quick Review of the basics

1. Accounts in Ethereum

An account in Ethereum blockchain can simply be defined as a component that represents either an individual user or smart contracts on the blockchain and allows them to initiate transactions.

Ethereum includes 2 different types of accounts:

  • Externally Owned Accounts - also called EOA
  • Contract Accounts

Let’s quickly understand each of them:

a. Externally Owned Accounts are controlled by their private key. In simpler terms, a specific EOA is controlled by a user who owns the private key of that account.

  • These accounts are capable of initiating transactions in the blockchain. However, transactions between two EOAs can only be limited to ether or token transfers.
  • Since these accounts are owned by private keys, the owner of the key must sign the transaction to initiate any activity in their account.
  • For instance, this is an Externally Owned Account - HERE

b. Contract Accounts, on the other hand, are not controlled by a private key but by their own smart contract code logic.

  • Have you ever deployed on any EVM chain? The address you get after contract deployment is basically a contract account.
  • These are the accounts that do not just hold your ether or token balance but are also capable of storing smart contract codes within themselves.
  • While contract accounts are also capable of sending transactions, they do so only in response to receiving a particular transaction. In other words, they won’t send a transaction unless their logic allows them to.
  • It must also be noted, that, unlike externally owned accounts, creating a contract has a cost attached to it since we are deploying data on the chain.
  • This, for instance, is a Contract Account

2. The Concept of GAS

Remember when we discussed EVM being a quasi-turing complete system? Well, the concept of Gas plays a significant role in making it one.

Gas, in laymen's terms, can be understood as a unit that describes the amount of computation power required to execute specific transactions on the blockchain.

For a transaction to be executed and affect the world state of the Ethereum chain, one must pay a certain amount of gas. Additionally, this amount of gas relies on how heavy a transaction is. The heavier the transaction, the more gas one must pay to execute it.

For instance, transferring 1 ETH to your friend can cost lesser gas than executing a Swap function on Uniswap smart contracts.

3. Transactions in Ethereum

Alright, we discussed briefly how EOAs are capable of initiating and sending a transaction, but…. What exactly are transactions in the context of EVM?

A one-liner answer would be:

A transaction in the Ethereum chain is basically an action that can be triggered by any externally owned account to perform a state-changing interaction on the blockchain.

It means, whether you use your ethereum account to transfer an NFT to your friend or you interact with the PushCore smart contract to create a channel on the Push Protocol or you deploy a new smart contract, everything is a transaction on the blockchain that contains cryptographically signed data messages defining the task to perform.

Transactions in the Ethereum blockchain can broadly be categorized into 2 specific types:

a. Message Call transactions:

  • Message calls refer to the transactions that are triggered by an EOA in order to interact with a contract account or yet another EOA.
  • You sending USDT to my address or interacting with Uniswap are all examples of message call transactions

b. Contract Creation transactions:

  • As the name suggests, these are transactions that aim to create a new contract account on the chain.
  • For instance, deploying a new smart contract for your next web3 project is a type of contract creation transaction.

The Architecture of a transaction in Ethereum

Let’s quickly understand some of the crucial fields that an ethereum transaction holds:

  • nonce: A counter that keeps increasing every time you initiate a transaction from a particular EOA.
  • recipient or to: the address of the recipient of this transaction. (it can be an EOA or a Contract Account).
  • value: the amount of ether to be transferred from the sender to the recipient address. It can be left zero if no eth transfer is supposed to happen in your transaction.
  • data: an optional field to include any arbitrary data. This field can contain code in a specific transaction for a Contract account
  • gaslimit: which refers to the amount of gas that can use in a particular transaction.
  • maxPriorityFeePerGas as well as maxFeePerGas
  • and, signature

Alright, now that we understand the fundamental topics of the Ethereum blockchain, we are all set to dive in deep to get the gist of some crucial EVM components.


EVM Architecture and its Components

Fig.1b-takenobu-hs github

Storage

To begin with, Storage can be seen as the Hard drive of the computer that stores data permanently.

Storage can simply be understood as the permanent storage of the EVM. Any value that is written to the storage is retained even after the execution is completed.

In simpler terms, Storage is basically a key-value storage system that maps 32 bytes slots to 32-byte values.

It's imperative to note that since storage holds data permanently, it consumes more gas and is therefore costlier to use in your smart contracts.

💡
Considering the fact that storage operations are costs more gas, (= more money), it's always recommended to optimize your contracts to only use storage operations where necessary and remove wipe out the rest.

Memory

While EVM storage resembles a Hard drive, Memory is more of a RAM in the computer, a temporary data holder.

EVM memory is not really persistent and is wiped out as soon as the function execution is completed.

Unlike storage, memory usage in smart contracts is comparatively a cheap operation that costs less gas. However, it must be kept in mind that the cost of using memory can increase as memory usage increases in a function.

Calldata:

Calldata is an interesting section of the EVM and equally imperative.

It is a quite special data location of the EVM that refers to the location that stores the input parameters or arguments of the function that is supposed to be called.

Quite similar to memory, calldata is also a non-persistent data holder that is cleared after the execution of the transaction.

Calldata is quite cheaper and costs very less gas.

It should also be noted that it can never be written as it's read-only.

Stack

The stack is the most important component of the EVM.

EVM is technically a stack machine as it plays a significant role in every computation or operation performed in the EVM. With a maximum size of a total of 1024 values, the EVM stack can contain words of 256 bits.

It is mainly used to store smart contract instruction inputs as well as outputs.

Program Counter

The Program counter in an EVM indicates the specific instruction from the code, that should be read and executed next by the EVM.

This counter basically allows the EVM to step through the entire contract code and interpret as well as execute the specific instructions to reach the desired outcome/state.

At the very beginning of any transaction execution, the Program counter is set to ZERO.

How does EVM work?

Alright, now that we grasped the very core fundamentals of the Ethereum Virtual Machine as well as its components, it's time to combine all of it together and get the gist of how an EVM works.

Note: This is an eagle-eye perspective of how EVM works. We will dive into a lot of technical, in-depth and fun details about EVM in next articles of this series.

Before diving into EVM’s working mechanism…

If you remember the very first line of the EVM in 100 words section of the article, it said - Ethereum virtual machine is specifically designed to process smart contract transactions.

While it's true, it should also be kept in mind that the EVM cannot really execute solidity smart contracts directly. This is because the EVM doesn't really understand a high-level language like Solidity and therefore cannot interpret or execute it directly.

Every Solidity smart contract is compiled down to low-level machine instructions called Opcodes, which are understandable by the EVM.

In order to execute any tasks, storing data in state variables or executing a swap of tokens, the EVM uses these opcodes.

There are around 140 total unique opcodes at the moment and each one of them has a specific functionality attached to it. We shall read about opcodes extensively in the next article of this series.

EVM working mechanism

To begin with, it all starts with a transaction.

Here is what a dummy Ethereum transaction might look like. 👇

{
  from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8",
  to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a",
  gasLimit: "21000",
  maxFeePerGas: "300",
  maxPriorityFeePerGas: "10",
  nonce: "0",
  value: "10000000000",
  data: "0xabcd", 
}

Let's consider this transaction as the one that the EVM is now about to execute.

  1. EVM Instantiation

Whenever a transaction triggers the execution of smart contract code, an Ethereum Virtual Machine (EVM) is instantiated with all the necessary information. These details are related to the current block being created.

The address in the 'to' field is the address of the contract that is being targeted. Additionally, the transaction includes all other crucial details like gas limit, ether value, as well as the data that is to be executed on the target contract.

As soon as an EVM is instantiated, it basically prepares itself to start the processing of a new smart contract transaction.

This preparation, for instance, involves:

  • the program counter of the EVM being set to zero,
  • Storage being loaded from the contract account,
  • Environment variables being set as well as memory initialized to zero, etc.

The EVM then pulls up the contract and its code associated with the given address in the transaction.
This is where the significant role of the Program Counter starts. The program counter now helps the machine to step through the entire code which allows the EVM to interpret and execute the given instructions one-by-one.  

Once all such preparations are done, the EVM technically is then ready to start executing the instructions (opcodes) and resulting in the intended state changes of the contract.

2. Gas Supply & Adjustments

Although the EVM is now all set to start processing these opcodes, we cannot keep the concept of Gas out of this equation.

As previously discussed in the EVM as a quasi-turing complete machine section,  for every smart contract operation to be executed, a transaction fee must be paid in the form of gas.

When initiating a smart contract transaction, the sender of the transaction must provide a certain value of gas fees(in the form of ether) that he is willing to pay for this transaction to be executed.

Interestingly, as the smart contract operations are executed, the gas supply provided with the transaction reduces.

In other words, if the sender didn't provide an adequate gas supply required for the transaction to be completed, the supply eventually gets to zero and the EVM throws an Out of Gas exception error. This immediately stops further execution of the transaction.

If such an event happens, the entire transaction is rolled back and no changes are included in Ethereum's state.

The sender's ether balance, however, does decrease since he/she had to pay for the gas that was consumed so far by the transaction.

Gas can also be Refunded

Some transactions can also include a higher gas limit, i.e., the amount of gas that the sender is allowing to be consumed in his/her transaction.

However, if the provided gas limit is way higher than the required gas in the transaction, EVM simply refunds the unused gas back to the sender.

Fig.1c-Source: Ethereum.org

3. Processing transactions and Changing World State

Alright, let's consider that the above-mentioned transaction neither throws any Out of gas error nor has any logic error that might lead to its rejection.

This technically means this transaction can be successfully processed by the EVM, consume the required amount of gas, and lead to the expected changes in not just the target contract's state but also the entire world state of the chain.

Contracts calling Contracts

An interesting point to keep in mind is smart contracts can initiate transactions or calls to other smart contracts well.

A transaction initiated by an EOA to some Contract X can also lead to a new transaction initiated by the targeted Contract X to some other Contract Y if need be.

Every new call to a new contract creates a similar cycle of EVM instantiation and transaction execution which ultimately leads to desired state changes.

It should, however, be noted that every new smart contract transaction within the original transaction requires gas to adequately execute the transaction.

Therefore, a new EVM instantiation highly relies on the amount of gas remaining for the execution of the new transaction. In case the gas passed along with the transaction, isn't sufficient enough to make new calls to new contracts, the transaction shall completely revert.

The diagram below represents such transactions quite clearly.

Fig.1d-Source: ResearchGate

Wrapping it up

That brings us to the end of the very first part of the EVM series.

Remember, the core objective of this part was to set a strong foundation of the basics and important details about the Ethereum virtual machines. Thus, preparing ourselves to dive much deeper into its technicalities in the next series.

We now have a very clear idea of:

  • Basics of EVM.
  • Why is EVM a state machine and what exactly are virtual machines?
  • Why is EVM called a Quasi-Turing complete instead of a Turing complete machine?
  • Core components of EVM
  • An eagle-eye perspective of EVM's working mechanism.

In the next part, we shall start exploring the entire journey of smart contracts - from development to its on-chain execution. Stay tuned.

Further Reading

Join Decipher with Zaryab today

Let's learn and build better, secure Smart Contracts

Subscribe Now