Ethereum Virtual Machine

1 Overview
The Ethereum Virtual Machine EVM is the running environment for smart contracts. It is not only sandboxed, but also completely isolated, which means that code running in the EVM cannot access the network, file system, and other processes. Even access between smart contracts is limited.
2.Account
There are two types of accounts in Ethereum (they share the same address space): external accounts are controlled by public-private key pairs (that is, people); contract accounts are controlled by code stored with the account.
The address of the external account is determined by the public key, while the address of the contract account is determined when the contract is created (this address is calculated from the address of the contract creator and the number of transactions sent from this address, which is the so-called "nonce")
Regardless of whether the account stores code or not, these two types of accounts are the same to the EVM.
Each account has a persistent store in the form of key-value pairs. The lengths of key and value are both 256 bits, which we call storage.
In addition, each account has an ether balance (balance) (the unit is "Wei", 1 ether is 10**18 wei), and the balance will change by sending transactions containing ether.
3. Transaction
A transaction can be seen as a message sent from one account to another account (the account here, may be the same or the special zero account, see below). It can contain a binary data (contract payload) and ether. If the target account contains code, this code will be executed with payload as input parameter. If the target account is a zero account (account address is 0), this transaction will create a new contract. As mentioned earlier, the address of a contract is not a zero address, but is calculated from the address of the contract creator and the number of transactions sent from that address (the so-called "nonce"). The payload of the transaction used to create the contract will be converted into EVM bytecode and executed. The output of the execution will be permanently stored as contract code. This means that in order to create a contract, you do not need to send the actual contract code, but rather the code that produces the contract code.
Note: During the contract creation process, its code is still empty. So until the constructor is executed, you should not call the contract's own functions in it.
4.Gas
Once created, each transaction is charged a certain amount of gas, which must be paid by the original transaction initiator (tx.orgin). When the EVM executes transactions, gas will be gradually exhausted according to specific rules. No matter where the execution reaches, once the gas is exhausted (such as falling to a negative value), an out-of-gas exception will be triggered. All state modifications made during the current call frame will be rolled back.
The Gas mechanism incentivizes economical use of EVM execution time while also compensating EVM executors (i.e. miners) for their work. Since each block has a maximum amount of Gas (block gas limit), it also limits the amount of work required to verify a block.
gas price is a value set by the transaction sender. The sender's account needs to prepay the handling fee = gas_price * gas. If there is any remaining gas after the transaction is executed, the gas will be returned along the way. If an exception occurs and the transaction is rolled back, the gas that has been used up will not be refunded.
Since EVM executors can choose whether to include transactions. Transaction senders cannot abuse the system by setting a low gas price.
5. Storage, memory and stack
The Ethereum Virtual Machine has three areas for storing data: storage, memory and stack.
Each account has a persistent memory area called storage. The storage is a key-value store that maps 256-bit words to 256-bit words. It is impossible to enumerate storage in a contract, and the relative overhead of reading storage is high, and the overhead of modifying storage is even higher. A contract can only read and write its own part of the storage area.
The second memory area is called memory, and the contract will try to obtain a memory instance that has been wiped clean for each message call. Memory is linear and byte-level addressable, but reads are limited to 256 bits, while writes can be 8 or 256 bits. When accessing (whether reading or writing) a word of memory that has never been accessed before (whether offset to any location within the word), the memory is expanded by words (each word is 256 bits). Expansion will also consume a certain amount of gas. As memory usage grows, so does its cost (on a square scale).
The EVM is not register-based but stack-based, so all calculations are performed in an area called the stack. The stack has a maximum of 1024 elements, and each element is one word (256 bits) long. Access to the stack is limited to the top of the stack and is restricted by allowing copying one of the top 16 elements to the top of the stack, or exchanging the top element of the stack with one of the 16 elements below. All other operations can only take the top two (or one, or more, depending on the specific operation) elements, and push the result onto the top of the stack after the operation. Of course, you can put elements on the stack into storage or memory. However, it is not possible to access only the element at a specified depth on the stack without first removing other elements from the top of the stack.
6.Instruction set
The EVM's instruction set should be as small as possible to minimize implementation errors that can lead to consensus issues. All instructions operate on the basic data type of "256-bit word". Features common arithmetic, bitwise, logical and comparison operations. Conditional and unconditional jumps can also be done. In addition, the contract can access relevant properties of the current block, such as its number and timestamp.
7.Message call
Contracts can call other contracts or send ether to non-contract accounts through message calls. Message calls are very similar to transactions in that they have a source, destination, data, ether, gas, and return data. In fact, every transaction consists of a top-level message call, which in turn creates more message calls.
The contract can decide how much of the remaining gas should be sent and retained in its internal message calls. If an out-of-gas exception (or any other exception) occurs during an internal message call, this will be indicated by an error value pushed onto the top of the stack. At this point, only the gas sent with the internal message call will be consumed. Moreover, in Solidity, the calling contract will trigger a manual exception by default so that the exception can "bubble up" from the call stack. As mentioned above, the called contract (which can be the same contract as the caller) will obtain a piece of memory that has just been cleared and can access the call payload - the data provided by an independent area called calldata. After the call is executed, the returned data will be stored in a piece of memory pre-allocated by the caller. The call depth is limited to 1024, so for more complex operations we should use loops instead of recursion.
8. Delegate calls/code calls and libraries
There is a special type of message call called a delegatecall. The difference between it and a general message call is that the code of the target address will be executed in the context of the contract that initiated the call, and msg.sender and msg.value remain unchanged. This means that a contract can dynamically load code from another address at runtime. Storage, current address and balance all point to the calling contract, only the code is obtained from the called address. This allows Solidity to implement "library" capabilities: reusable code libraries can be placed on the storage of a contract, such as libraries used to implement complex data structures.
9.Log
There is a special indexable data structure that stores data that can be mapped all the way down to the block level. This feature is called logs, and Solidity uses it to implement events. Log data cannot be accessed after the contract is created, but the data can be accessed efficiently from outside the blockchain. Because part of the log data is stored in a Bloom filter, we can search the logs efficiently and cryptographically securely, so they can also be found by network nodes (light clients) that have not downloaded the entire blockchain.
10.Contract creation
Contracts can even create other contracts with a special instruction (rather than simply calling the zero address). The only difference between create calls and ordinary message calls to create a contract is that the payload will be executed, the execution result is stored as contract code, and the caller/creator gets the address of the new contract on the stack.
11. Failure and self-destruction
The only way for the contract code to be removed from the blockchain is for the contract to perform a selfdestruct operation on the contract address. The remaining ether on the contract account is sent to the specified destination, and then its storage and code are removed from the state. Removing a contract sounds good, but it is potentially dangerous. If someone sends ether to the removed contract, the ether will be lost forever.
Warning: Even if a contract is deleted by selfdestruct, it is still part of the blockchain history and may be retained by the majority of Ethereum nodes. Therefore, using selfdestruct is different from deleting data from the hard drive.
Note: Even if selfdestruct is not explicitly called in the code of a contract, it is still possible to perform self-destruction through delegatecall or callcode.
12. Pre-compiled contracts
There are a small number of contract addresses that are special. The address range between 1 and (inclusive) 8 contains "precompiled contracts", which can be called like other contracts but their actions (and their gas consumption) are not stored there. Addresses are defined by the EVM code (precompiled contracts contain no code). Rather, it is implemented within the EVM execution environment itself.
Compatible chains may use a different set of precompiled contracts. It is also possible that new precompiled contracts will be added to the Ethereum main chain in the future. But you can reasonably expect them to always be in 0xffffthe address range 1 and (inclusive).

おすすめ

転載: blog.csdn.net/m0_58724783/article/details/132685222