An Ultimate, In-depth Explanation of How EVM Works.
This post is a continuation of my Getting Deep Into Series started in an effort to provide a deeper understanding of the internal workings and other cool stuff about Ethereum and blockchain in general which you will not find easily on the web. Here are the previous parts of the Series in case you missed them:
In this part, we are going to explore explain and describe in detail the core behavior of the EVM. We will see how contracts are created, how message calls work, and take a look at everything related to data management, such as
calldata, and the stack.
To better understand this article, you should be familiar with the basics of the Ethereum. If you are not, I highly recommend reading these posts first.
Throughout this post, we will illustrate some examples and demonstrations using sample contracts you can find in this repository. Please clone it, run
npm install, and check it out before beginning.
Enjoy, and please do not hesitate to reach out with questions, suggestions or feedback.
EVM: 10,000 ft Perspective
Before diving into understanding how EVM works and seeing it working via code examples, let’s see where EVM fits in the Ethereum and what are its components. Don’t get scared by these diagrams because as soon as you are done reading this article you will be able to make a lot of sense out of these diagrams.
The below diagram shows where EVM fits into Ethereum.
The below diagram shows the basic Architecture of EVM.
This below diagram shows how different parts of EVM interact with each other to make Ethereum do its magic.
We have seen what EVM looks like. Now it’s time to start understanding how these parts play a significant role in the way Ethereum works.
Smart contracts are just computer programs, and we can say that Ethereum contracts are smart contracts that run on the Ethereum Virtual Machine. The EVM is the sandboxed runtime and a completely isolated environment for smart contracts in Ethereum. This means that every smart contract running inside the EVM has no access to the network, file system, or other processes running on the computer hosting the VM.
As we already know, there are two kinds of accounts: contracts and external accounts. Every account is identified by an address, and all accounts share the same address space. The EVM handles addresses of 160-bit length.
Every account consists of a balance, a nonce, bytecode, and stored data (storage). However, there are some differences between these two kinds of accounts. For instance, the code and storage of external accounts are empty, while contract accounts store their bytecode and the Merkle root hash of the entire state tree. Moreover, while external addresses have a corresponding private key, contract accounts don’t. The actions of contract accounts are controlled by the code they host in addition to the regular cryptographic signing of every Ethereum transaction.
The creation of a contract is simply a transaction in which the receiver address is empty and its data field contains the compiled bytecode of the contract to be created (this makes sense — contracts can create contracts too). Let’s look at a quick example. Please open the directory of exercise 1; in it, you will find a contract called
MyContract with the following code: