What is the Ethereum Virtual Machine (EVM)?
Table of contents
- EVM Break-down
Disclaimer: This is an attempt to research the topic and try to understand it in more detail to find gaps in my understanding of it, I'm not an expert on the topic. I will attach sources throughout the article, so you too can make your own research. So, any feedback is good feedback.
Let us first start with a definition of what is the EVM. This is how Wikipedia defines the Ethereum Virtual Machine:
The Ethereum Virtual Machine (EVM) is the runtime environment for transaction execution in Ethereum. It consists of a stack, memory, gas balance, program counter, and the persistent storage for all accounts (including contract code). When a transaction calls a contract's function, the arguments in the call are added to the stack and the EVM translates the contract's bytecode into stack operations. Stack items may be stored in memory or storage, and data from memory/storage may be added to the stack. The EVM is isolated from the other files and processes on the node's computer to ensure that for a given pre-transaction state and transaction, every node produces the same post-transaction state, thereby enabling network consensus.
Ok, that's it. Thank you Wikipedia, the article is now finished. Hold on, what the heck does that even mean?
Okay, there must be another clear definition for us. Let me check the official Ethereum website docs:
The Ethereum Virtual Machine (EVM) is the runtime environment for smart contracts in Ethereum. All smart contracts and state changes on the Ethereum blockchain are executed by transactions. The EVM handles all of the transaction processing on the Ethereum network.
So far we knew the EVM is:
- A runtime environment for Smart Contracts.
- A state machine.
- Consisted of stack, memory, storage, and gas balancer.
- Virtual and isolated machine.
- Turing-complete machine.
- Capable of executing/handling transactions instantiated by Externally Owned Accounts (EOA) or other Smart Contracts.
Well, let's break down each of those points separately
EVM is a runtime environment
What is a runtime environment
In short, think of the runtime as a middle-man between an operating system/hardware and the software/applications that run and use the capabilities of those two components. It is part of the execution layer of any operating system, in our case, the operating system here is the Ethereum Virtual Machine and the software are our little apps called Smart Contracts.
How EVM is a runtime environment
Well, Ethereum is trying to be the computer of the internet, and the main component of any computer is its operating system which is the EVM in our case. Operating systems need to have software so they can communicate with their hardware components and use the capabilities offered by the operating system. EVM runs on every full node on the Ethereum network, so if we considered Ethereum to be the computer of the internet, that computer processing power is distributed between every node on the network, which makes it more interesting and secure.
Solidity, among other programming languages (like Vyper, and LLL for example) are used to program our little smart apps (Smart Contracts) to be run on top of the Ethereum network, but our computer operating system only understands Bytecode. Bytecode is not directly understandable by computer hardware, but it's easily understandable by a virtual machine. So, here comes the runtime environment aspect, the EVM translates/compiles the code written in Solidity and other programming languages to bytecode and the virtual machine translates it to the corresponding machine code that can be run on every Ethereum node.
So, to recap what the EVM is really doing here in short simple words. We write smart contract code in Solidity, for example, that code is then translated to bytecode when compiled so the EVM can understand the logic behind the written code and then executes it on the Ethereum network accordingly after compiling it to machine code by the virtual machine compiler first.
Here is another great illustration of how the runtime aspect of the EVM work from XamHans
EVM is a state machine
Image credits: Wikipedia
In computer science, a system is described as stateful if it is designed to remember preceding events or user interactions. The Ethereum network is designed in a way that allows the whole network to have only one state at any given block, and only one state. For example, a variable in a smart contract when stored in the storage (more on that later) can only have one value at any point in time. The EVM here is the one responsible for changing that state by allowing users (EOA) or other smart contracts to send transactions (or message calls in case of a smart contract) that contain data with the new state. Like a turnstile, it only has one state at any given point in time, and you need to insert a coin inside of it to change that state.
EVM consists of stack, memory, storage, and gas balancer
Image credits: Official Ethereum website.
Mainly, three of them are used for storing data (stack, memory, storage), and the gas balancer have other uses. So, let's break down each one of them separately.
What is a stack in computer science? It is an abstract data type that serves as a collection of elements, with two main principal operations:
01) Push=> which adds an element to the collection
02) Pop=> which removes the most recently added element that was not yet removed
Okay, but how's that related to the EVM? Well, EVM is designed as a stack machine as a design choice, we can visualize a stack as a storage type that has a medium-term memory span, or more precisely, it can only store a certain type of data, which is our smart contract local variables in our case. But there is a catch here, the stack storage is limited to a certain amount of values (1024 values). Stack storage is so cheap, compared to storage type.
The memory type is a kind of storage that only lives during the lifespan of a function call, and the data will be discarded and deleted from the blockchain afterward. Because of the nature of this type, it's also so cheap and usually used for on-the-fly computations that don't need to be persistent on the network.
Storage may be referred to also as Account, at the end every Ethereum address is an account that holds a balance of Ether, and this balance must be saved inside of persistent storage so it only gets updated when a transaction occurs. Smart contracts need to use storage so they can have persistent data, for example, a smart contract needs to persistently store account balances for each user of any ERC20 token like DAI or Tether. Storage costs are very high, but they can have/take relatively large space on the Ethereum network compared to other storage types.
Ok, what is gas on the Ethereum network? Okay, gas is simply gas, it's the fuel that powers all the transactions that occur on the Ethereum network. Ethereum is designed on top of a consensus mechanism called Proof of Work (PoW) and one of its main features is incentivizing network participants with the network native currency, Ether in our case, so a user who is using the network for their own benefit should spend a little bit of their holdings of Ether as an incentive for the network participants so they provide their computing power to the network to continue functioning. This incentive is called GAS. Their is also another aspect of how gas works on Ethereum, the more the network is being used by many users, the more the gas fees a user should pay to incentivize a network participant to pick his/her request first (more on that and how gas fees are calculated on another day) and the gas balancer is the part responsible for adjusting those gas fees according to how busy is the whole network is.
EVM is virtual and isolated
A virtual machine is defined as an abstraction layer on top of any physical machine. How is that related to Ethereum, anyway? Well, no one would be happy if any malicious actor in the network figured out a way to run malicious code on every physical computer of each node in the Ethereum network, that would be devastating. So, the EVM here provides an abstraction layer on top of the physical hardware of the full nodes on the network who are contributing computing power and resources to the network, and this abstraction only allows actors and developers to use the full capacity of the network but with the limitations of only what the EVM offers, which is a lot.
Then comes the isolation part, which ensures nobody has access to the file system, the underlying network, and the processors of the full nodes except the virtual machine, and this ensures that all code and the logic behind it will run the same way (deterministic execution, meaning that we will get the same results whenever we provide the same inputs each time we run the program) on all nodes.
EVM is Turing-complete
Turing Complete refers to a machine that, given enough time and memory along with the necessary instructions, can solve any computational problem, no matter how complex. The EVM is designed to handle and solve any computational logic provided by smart contracts, but there is a catch here, we don't want our virtual machine to be running non-stop on each node in the network to solve infinite loops for example. That would make the whole network collapse, that's where the concept of gas which we talked about earlier comes to play.
Gas cost simply caps the amount of time and execution steps needed by any function call or smart contract interaction to be completed. This ensures that the state doesn't change until the function call is complete, and it's not complete if the capped gas limit is exceeded, this will result in the function being reverted to the initial state.
EVM is capable of executing/handling transactions
Transactions on Ethereum are one of two types, first is the one initiated by EOA to another EOA or to a smart contact by cryptographically signing a request on the network that would change the state of the EVM. The second type is a message call initiated by a smart contract to another smart contract. Ok, why transactions are that important? Because the nature of the Ethereum network is designed as a state machine (as we discussed earlier) and what a transaction really does is that it broadcasts the request of the initiator to every node on the network so they pick up the data contained inside of the request and do any processing required to change the state of anything on the network. Transactions should be picked-up by miners (network participants) to be valid, and a miner will be choosing a transaction that has more gas fees than others, so they could have more profit maximization (which we were talking about earlier).
Okay, I guess I should add my final thoughts here on this spot, well, there is so much I learned about from writing about EVM. Mainly, the EVM is the main killer feature of the Ethereum network, being Turing-complete and capable of computing complex logic may actually lead it to be the computer of the internet for real. Also, understanding what is gas and how it works under the hood, is very crucial for writing a cost-efficient smart contract both for the deployer and for the end-user. There is so much more to understanding the underlying workings of the EVM, you can find on the Yellow Paper, we just had a general understanding of what is going on. For the next series of articles I'll start deep diving into Solidity programming language to learn it more in-depth; stay tuned.
If there is an error or something that needs more clarification, or I just still have an understanding gap about it, or to just connect with each other, please reach out to me here on comments or on Twitter @0xBeshoy