Ethereum Virtual Machine Explained
Last Updated: 1st November 2018
The Ethereum Virtual Machine can be thought of as quasi-Turing complete machine. Turing completeness refers to a system of data manipulation rules, and is named after Alan Turing, creator of the Turing machine. Programming languages and central processing units (CPUs) are good examples of systems that access and modify data. If these rules can be used to simulate Turing’s hypothetical computing machine, the rules are regarded as being ‘Turing complete’. A Turing complete system can be mathematically proven to have the capability of performing any possible calculation or computer program. In other words, a Turing complete machine is mathematically able to solve any problem that you feed to it. The Ethereum Virtual Machine is only quasi-Turing complete because computations performed by the machine are bound by gas, which serves as a limitation to the number of computations that can be done.
Gas and EVM Bytecode
On Ethereum, gas can be thought of as being equivalent to a fee. Every single transaction that is performed on the Ethereum network requires that a fee be attached to it, which is paid in the form of gas. The concept of Ethereum’s gas can be subdivide into two: gas and gas price
- Gas – Serves as a tool by which we measure the fees that will be required for a particular computation to be executed.
- Gas Price – This is the amount of Ether that an individual is willing to spend on every unit of gas. Gas price is often measured in ‘Wei’, and Wei is the smallest unit of Ether, where 10^18 Wei represents one Ether.
So, in order for an individual to execute a transaction on the Ethereuem network, the sender must set the gas limit and gas price attached to the transaction. If a sender does not possess the required gas to perform a transaction, then it is said to ‘run out of gas’ and is invalid.
Gas can limit the number of computations that can be performed by the Ethereum Virtual Machine in a few ways, including:
- Blocks that are mined on the Ethereum blockchain have a gas limit attached to them, so the amount of gas used by all transactions inside a block cannot exceed a certain amount.
- Attached to gas is the gas price, regardless of if gas limit restrictions were lifted and the machine was theoretically able to solve any problem it received, some transactions may be too complex and prove economically impractical.
The Ethereum Virtual Machine possesses its own programming language, known as the ‘EVM bytecode’. When code is written in higher-level programming languages such as Ethereum’s contract-orientated language Solidity, this code can then be compiled to the EVM bytecode, so that the Ethereum Virtual Machine can understand what has been written.
Transaction-based State Machine
The Ethereum Virtual Machine is an important element of the Ethereum construction, because it is responsible for handling internal state and computation on the network. The machine must also handle account information pertaining to addresses, balances, current gas price, and block information.
As mentioned earlier, the Ethereum Virtual Machine is responsible for handling internal state on the network. The machine must keep track of that status of numerous components in order to successfully support a transaction. This is important because it is the state of these components that really drive the level of change in the overarching blockchain. This is why Ethereum is often described as being a transaction-based state machine. Before we look at the various components that the Ethereum Virtual Machine must keep track of, a brief explanation of the concept of a ‘state’ may be useful.
In the field of computer science, a state machine refers to a machine that is able to read a series of inputs and, based on those inputs, transition to a new state. Similarly, Ethereum’s state machine also functions like this. Before any inputs are made, or before any transactions on Ethereum are executed, the starting point is something of a blank slate. As transactions on the network are carried out, any point during this time signifies the current state of Ethereum. In order for a state transition to occur, transactions that are made must be valid, and a transaction is considered as valid when it is successfully validated through the mining process.
This mining process is well known as proof-of-work (PoW), and it involves nodes on the Ethereum network expending computer resources in order to receive the privilege of creating a block of valid transactions and adding it to the blockchain. A miner can add a block to the blockchain when they are able to provide a mathematical ‘proof’. A valid proof signals to the network that the block is valid, which then results in the block being accepted and added to the chain. A miner who successfully validates a block, is rewarded with Ethereum’s native asset, Ether, in exchange for expending computing resources during the PoW process.
The components that the Ethereum Virtual Machine must keep track of include: Account State, World State, Storage State, Block Information and Runtime Environment Information.
Ethereum can be thought of as comprising of numerous small accounts that are capable of interacting with one another (this is possible because of Ethereum’s message-passing frame work). Accounts on Ethereum can be subdivided into: externally owned accounts and contract accounts.
- Externally owned accounts – These accounts are controlled by private keys and have no code associated with them.
- Contract accounts – These accounts are controlled by their contract code and have code associated with them.
An account that is externally owned is able to send messages to other externally owned accounts, or other contract accounts. This is done by digitally signing a transaction by use of a private key. Communication between two externally owned accounts can be regarded as simply being a transfer of value. However, a message between an externally owned account and a contract account has the effect of executing the contract account’s code. This enables the contract account to perform actions that are laid out in the code, which can include: token transfer, creation of new tokens etc. It is important to note that contract accounts are not able to initiate a new transaction on their own (unlike externally owned accounts). Contract accounts are reactive in the sense that they can only engage in transactions that serve as a response to other transactions that they have received, which can be from an externally owned account or from other contract accounts.
There are four elements that comprise the account state, which includes:
- Nonce – If the account is externally owned, this value represents the number of transactions sent from the account’s address. However, if it is a contract account, then the nonce signifies the number of contracts created by the account.
- Balance – The number of Wei that is owned by the account address.
- CodeHash – This is an immutable hash value of the Ethereum Virtual Machine code for the corresponding account.
Ethereum’s global state effectively consists of a mapping between 160-bit address identifiers and account state. All this mapping information is maintained in a data structure known as a Merkle Patricia Tree. This data structure is made up of a set of nodes with:
- A large quantity of leaf nodes at the bottom of the tree that house the underlying data.
- A set of intermediate nodes, where each node is the hash of the two child nodes.
- A single root hash also formed from the hash of the two preceding child nodes, representing the top of the tree structure.
This is the account specific state information that is maintained at runtime on the Ethereum Virtual Machine.
These are the state values that are required to support a transaction, the block information includes:
- Blockhash – The hash of the most recently completed block
- Coinbase – The address of the recipient
- Timestamp – The current block’s timestamp
- Number – The number of the current block
- Difficulty – The difficulty of the current block
- Gaslimit – The gas limit that is attached to the current block
Runtime Environment Information
This is information that is used to execute a transaction, which includes:
- Gas price – Current gas price as specified by the initiator of the transaction
- Codesize – The size of the transaction codebase
- Caller – The address of the account that is executing the transaction
- Origin – The address of the transaction’s original sender