[Virtual Machine Column] The Past and Present of Smart Contract Execution Engines
As the first smart contract language proposed, Solidity has opened a new door for blockchain application scenarios.
—— Origin——
The term Smart Contract was first proposed in 1994 by Nick Szabo, an interdisciplinary legal scholar. His definition of a smart contract is as follows:
"A smart contract is a set of digitally defined commitments, including an agreement on which the parties to the contract can enforce those commitments."
So in a nutshell, Nick Szabo sees a smart contract as a set of promises. The so-called commitment refers to the mutual rights and obligations agreed by the participants. So the essence and purpose of smart contracts is the promise itself. For example, in a simple buying and selling event, the seller promises to supply, and the buyer promises to pay. These two promises can form a smart contract. Note the keywords mentioned in Nick Szabo's definition of a smart contract: digital form and agreement. These two keywords determine that smart contracts are different from commitments in the traditional sense, and have decisive characteristics in form and function.
"Smart contract" was first introduced into the blockchain by Ethereum. According to the Ethereum white paper, the introduction of smart contracts is mainly to solve the following problems:
For scripting languages, scripts are not Turing-complete (will be introduced later), and it is difficult to implement complex functions, such as elliptic curve signature algorithm
Scripts do not have fine-grained control over the amounts that can be withdrawn
Scripts lack state preservation and cannot implement more complex stateful contracts
The data that can be obtained during execution is not rich enough, such as the acquisition of random numbers, timestamps and previous block hashes
In short, the scripting language cannot satisfy richer application operations, so Ethereum designed a unique smart contract language Solidity, and at the same time, the smart contract execution engine EVM for executing smart contracts was also born.
Since then, the application scenarios of blockchain technology have extended from a single UTXO-based digital currency transaction to Turing's complete general computing field. Users are no longer limited to the simple logic supported by Bitcoin Script, but can design arbitrarily complex contract logic by themselves.
-- Overview--
The Ethereum design smart contract has the following design features:
▲ Certainty of execution
Determinism means that a program has the same output for a given input, no matter when and where it is executed, no matter how many times it is executed. Since the blockchain maintains the same ledger, the certainty of smart contract execution can be understood as different nodes executing the same contract must have the same result.
The Ethereum smart contract language is designed to be simple enough. In order to ensure the certainty of execution, it will not implement functions such as random numbers and uncertain (system) calls. At the same time, the execution of smart contracts is in a virtual machine with a limited environment. In this way, the certainty of the results can be guaranteed at the bottom layer.
▲ Turing completeness
Turing's complete language, the more official explanation is a language that "can calculate all problems that can be calculated by an algorithm", including infinite loops. The purpose of introducing smart contracts in Ethereum is to achieve Turing completeness to support richer application forms.
One problem that needs to be solved after the introduction of Turing completeness is the halting problem: in general, there is no way to tell whether a given program will halt.
In order to avoid the downtime problem caused by Turing's completeness, Ethereum introduced the Gas mechanism to perform cost calculations on related execution processes. By calculating the cost of various operations in units of gas (each operation will correspond to a specific gas consumption, that is, there is a corresponding table of gas consumption), and setting the upper limit of gas consumption for each execution, that is, gasLimit, the cumulative operation of the contract execution After the gasLimit upper limit, the execution is forced to stop, so as to achieve the effect of shutdown. The introduction of the Gas mechanism makes the user's complexity of using the application depend on the price he is willing to pay for it, rather than the physical limitations of the platform.
Of course, the introduction of the Gas mechanism also has other benefits, which will not be introduced here.
▲ Security
As the design premise of Ethereum, security is also what smart contracts need to guarantee. The security of Ethereum smart contracts is mainly reflected in two aspects in design:
1) Relatively simple smart contract language
Compared with the mainstream Turing-complete language, the Solidity language focuses on blockchain scenarios, so there is no need to implement many language features such as multi-threading and system calls, which makes its design as simple as possible. However, this is also one of the reasons why it was difficult to use in the early days, although with the gradual development of the language, its functions are constantly increasing and improving.
2) The execution environment of the smart contract is sufficiently isolated
Ethereum smart contracts run in the Ethereum Virtual Machine (EVM). The execution in the EVM is not only sandboxed, but actually completely isolated, which means that the code running in the EVM cannot access the network, file system or other processes. Even smart contracts have limited access to other smart contracts. The controllable security is guaranteed to a large extent through the isolation of operation.
However, it is undeniable that Ethereum smart contracts still have many security problems, such as the famous "reentrant attack".
text
text
EVM is defined as a stack virtual machine that uses one byte as an instruction. The characteristic of the stack virtual machine is that it relies on interacting with the operand stack (operand stack) when performing operations.
The Solidity contract source code is compiled to use a low-level, stack-based bytecode, so what we actually deploy on Ethereum and execute in the EVM is actually a string of bytecodes. Code consists of a series of bytes, where each byte represents an operation. When the bytecode is executed, it is executed sequentially from the first bytecode according to the operation meaning of the bytecode until it reaches the end of the code or an error occurs (such as encountering REVERT, STOP or RETURN opcodes). These operations can access three types of spaces to store data:
Stack: LIFO container whose values can be pushed and popped;
Memory: an infinitely expandable byte array;
Storage: The long-term storage of the contract, which is stored as a key/value pair. Unlike the stack and memory that are reset after the calculation, the storage will exist for a long time, and this part is also part of the "world state" that is often called.
The execution process of the smart contract is actually the operation process of the three types of storage space according to the behavior defined by the opcode. Let's briefly show it with the following example:
The following figure shows some contract fragments: the left side is the contract bytecode, and the right side is the operation meaning represented by the bytecode

The simple meaning of each opcode is as follows:
PUSH1: The bytecode hexadecimal is 60, the meaning of the operation is to push the next byte onto the stack
ADD: Bytecode hexadecimal is 01, the meaning of the operation is to pop and add two elements on the stack, and then put the result back on the stack
MSTORE: Byte code hexadecimal is 52, the meaning of the operation is to store the second value popped from the stack into Memory, and the stored index value is the first element popped from the stack
RET: Bytecode hexadecimal is f3, the meaning of the operation is the end of execution, return the result, the result is in Memory, the starting index is the first value popped from the stack, and the length is the second value popped from the stack
Put this bytecode into the EVM for execution, and its execution process is as follows:

Among them, PC represents the position of the current execution operation code. At the end of the execution of the contract fragment (ie: RET operation code), 5 bytes of data will be taken out from the beginning of 60 in Memory. Therefore, the execution of the contract fragment is completed. The final result will be returned to the caller!
Careful students will find that the relevant instructions in the figure do not have operations related to Storage. In fact, it is because relevant instructions such as SStore are not selected in the sample code for simplicity, and its execution principle is similar to the above expression.
"So, why is the EVM designed like this? Why is it possible to solve the calculation problem and complete the acquisition and modification of the contract state through the entry and exit of these stacks, the copying of the memory, and the operation of the Storage? "
This involves the design of programming languages. Theoretically, in the theoretical system of computing, the instruction set architecture is an abstract model of a computer, and the richness of instruction types contained in the instruction set directly affects the richness of program expression. For example, the instruction set can include arithmetic and logical operation instructions such as addition, subtraction, multiplication and division, control instructions such as jump, and data processing instructions such as reading memory. As a virtual machine, you can select or add instructions as needed to build an instruction set to express your desired functions. For example, the EVM does not add Storage-related instructions for operations related to floating-point numbers, so this explains from the instruction level that the Solidity language does not support floating-point number operations. After the instruction is determined, with the help of some tools of modern programming, a specific language can be designed. So, to some extent, we can also implement our own language and corresponding execution engine if necessary.
-- develop--
The essence of EVM is to operate the "world state" through a programmable language, which is what we call the blockchain ledger. Therefore, how to operate better and faster is a major pursuit of the smart contract virtual machine.
With the continuous development, there are many smart contract execution engines in the industry, and there is no shortage of new explorations.
EVM: Compatible with Ethereum EVM, and optimized for performance and rich in functions
HVM: FunChain pioneered an efficient, easy-to-use and complete smart contract execution engine that supports writing smart contracts in Java language
FVM: A safe, diverse and efficient smart contract execution engine that supports writing smart contracts in Rust and other languages
KVSQL: A new execution engine that supports the execution of SQL statements on the blockchain
About the Author
About the Author
He Qi
references
references
[1] Smart contract Baidu Encyclopedia
[2] Ethereum Yellow Paper
[3] Ethereum White Paper


