The nitty-gritty of Ethereum and Solidity : Ethereum Virtual Machine (EVM) (Part 1).

Alberto Molina
Coinmonks

--

The Ethereum blockchain is very often referred to as “the global computer” as opposed to the Bitcoin blockchain which is commonly referred to as a “ the distributed ledger”.

The main difference between these two well known blockchains is that Ethererum offers the possibility to deploy smart contracts which are quasi Turing complete algorithms, meaning that you can execute practically anything on ethereum, turning the blockchain into some sort of distributed computer.

Nodes forming the ethereum network are capable of running these smart contracts independently of their underlying OS. The way this is achieved is very similar to how they made it for platforms like .Net and Java, using a Virtual Machine (which behaves as an intermediary between the compiled code and the underlying OS) and some sort of intermediate language.

New to trading? Try crypto trading bots or copy trading

Smart contracts compile into opcodes (the Ethereum intermediate language) that runs in the EVM (the Ethereum virtual machine). The EVM is what makes the Ethereum blockchain a global computer and it is very useful for developers to understand how it works, at least from a general point of view.

Accounts & Transactions

Let’s start with a very short presentation of accounts and transactions on Ethereum.

In Ethereum there are two types of accounts :

  • Externally owned accounts (EOA): Accounts controlled by actual humans. They can trigger transactions and they do not contain any code or storage.
  • Smart contracts: Accounts controlled by no one. They cannot trigger transactions (they can however invoke other smart contracts when they are triggered by an EOA) but they contain code and storage.

There are also two types of transactions:

  • Transactions that do not contain data: Used to transfer ether from account A to account B. If sent to a smart contract account it will trigger the “receive” function if implemented, otherwise it will trigger the “fallback” function if implemented, if none of them exist, the transaction will fail.
  • Transactions that contain data: If sent to a smart contract account it will run its code (the method indicated within the data or the “fallback” function if no matching signature is found). If sent to an EOA it will simply behave like a “Transaction that does not contain data”. It is important to note that smart contracts can invoke other smart contracts, these are called “messages”, meaning that a transaction contains one or multiple inner messages.
EOA to EOA transactions (with or without data). Always succeeds.
EOA to Smart contract transactions (with or without data). Might trigger further message calls and might fail.

There is always at least one message per transaction, the message originally submitted by the EOA).

The only way to “activate” the EVM is to send a transaction containing data to a Smart contract.

EVM Components

  • Program Code.

The opcodes (1 byte long commands) from the compiled smart contract that is been invoked by the transaction.

Smart contract’s program code are stored on the blockchain (persistent) and are immutable, meaning that opcodes can only be read and never modified (ROM memory).

  • Program Storage.

The storage associated to the smart contract. Every SM account has a 2**256 slot space of 32 bytes words, acting as a Read/Write database where the contract’s state is saved. The storage is persisted on the blockchain.

  • Machine State.

Ethereum machine persistent state is the list of accounts, their balances and nonces at a given point in time. The EVM has access to this huge list of accounts, balances and nonces and can update it.

Balances can be updated be transferring ether from one account to another, EOA nonces are increased after each transaction and SM nonces can also be updated if new smart contracts are deployed onto the blockchain (every time a SM deploys another SM using the “CREATE” opcode, its nonce is increased).

  • Program Counter.

The EVM keeps track of the latest executed opcode using a “volatile” program counter. Once the Transaction is finished, the Program counter is removed, it is not persisted on the blockchain.

  • Available Gas.

In order to execute smart contract’s functionality, the transaction sender must provide some Gas. The EVM keeps track of the available gas after each opcode, if at some point it runs out of Gas, the transaction is reverted (the Gas is not refunded though). If, on the other hand, there is some Gas left after the transaction finishes, it gets refunded to the transaction sender.

Gas is how Ethereum solves the “halting problem”, programs cannot run for ever, transactions cannot consume more gas than the maximum amount of Gas allowed within a single Block.

  • Stack.

The EVM is a stack based machine, what this means is that most opcodes will look for their operands in the stack although the EVM can also read/write data from its volatile memory and persistent program storage / state machine.

The stack is a 32 bytes word LIFO memory space, that gets deleted once the execution terminates. The stack has a maximum depth of 1024 and stores method local variables that are value types (all types other than arrays, mappings, structs and strings) although it can only access the top 16 items (in order to access items beyond the 16th slot it has to remove other items from the top), which means that if you declare, within the same function 16 local variables or more, you will get an exception at compile time “stack too deep”.

  • Memory.

The EVM has another storage location (besides the Stack, the Program Storage and the calldata), the “memory”, which has a 2**256 slot space and words are 1 byte long (as opposed to the stack and storage which are 32 bytes long). Despite been “byte-addressable” the memory normally hold 32 bytes words.

The first four 32 bytes slots (128 bytes in total) in memory are reserved for the following purposes:

0x00 - 0x3f (64 bytes): scratch space for hashing methods

0x40 - 0x5f (32 bytes): currently allocated memory size (aka. free memory pointer)

0x60 - 0x7f (32 bytes): zero slot

When assigning a memory variable to another memory variable, the EVM will not create a copy but just a reference. When assigning a memory variable to a storage variable, the EVM will create a copy.

The memory is volatile, at the end of the execution nothing will be persisted on the blockchain (as opposed to the storage).

  • Global Variables.

Last but not least, the EVM has access to several global variables when running.

BLOCK Variables, like “block number”, “block difficulty”, … These variables are the same for every single transaction within the same block.

TRANSACTION Variables, like “Tx origin”, “Tx gasPrice”, … These variables are the same for every single message within the same transaction.

MESSAGE Variables, like “msg.sender”, “msg.value”, … These variables are unique to the message. If a smart contract invokes another smart contracts, these variables will be updated.

EVM Execution Process

Once a transaction to a smart contract is sent by an EOA, nodes executing it will create an instance of the EVM by doing the following:

  • Loading the smart contract opcode & storage from the Ethereum blockchain.
  • Instantiating a new and empty Stack and Memory.
  • Retrieving the global variables

They will then proceed to execute the opcodes in order, update the stack, memory, storage and machine state if necessary, reduce the amount of Gas after each opcode execution and, if no exceptions are found (run out of Gas or stumble upon a revert command for example), the EVM terminates, the stack and memory are wiped out, the storage and machine state are persisted on the blockchain and the remaining gas is refunded to the transaction sender.

If, on the contrary, an exception is found, the transaction will revert, the stack and memory will be wiped out, the storage and machine state will NOT be persisted on the blockchain (except for the amount of Gas already used), and the remaining gas is refunded to the transaction sender.

Please check the second part of this blog series to see some other EVM particularities :

The nitty-gritty of Ethereum and Solidity : Ethereum Virtual Machine (EVM) (Part 2).

--

--