In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)05/31 Report--
Today, the editor will share with you the relevant knowledge about what the assembly code of the block chain etherfang virtual machine is. The content is detailed and the logic is clear. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article, let's take a look at it.
What is the difference between string, bytes32, byte [], and bytes?
Where should I use which type?
What happens when you convert string to bytes? Can it be converted to byte []?
What is the cost of their storage?
How does EVM store mapping (mappings)?
Why can't a mapping be deleted?
Is it possible to have a mapping? (yes, but how is it mapped?)
Why is there a storage mapping but no memory mapping?
What does a compiled contract look like to EVM?
How is the contract created?
What exactly is a constructor?
What is the fallback function?
I think learning a Solidity-like high-level language that runs on the Ethernet Square Virtual Machine (EVM) is a good investment for several reasons:
Solidity is not the last language. A better EVM language is coming. (please? )
EVM is a database engine. To understand how smart contracts work in any EVM language, you must understand how data is organized, stored, and manipulated.
Know how to be a contributor. Etay Fong's tool chain is still in its early stages, and understanding EVM can help you achieve a great tool for yourself and others to use.
An intellectual challenge. EVM gives you a good reason to soar between the intersection of cryptography, data structures, and programming language design.
In this series of articles, I'll take apart a simple Solidity contract to show you how it works in EVM bytecode (bytecode).
I hope to be able to learn and write an outline of the article:
Basic understanding of EVM bytecode
How different types (mappings, arrays) are represented
What happens when a new contract is created
What happens when a method is called
How ABI bridges different EVM languages
My ultimate goal is to understand a compiled Solidity contract as a whole. Let's start by reading some basic EVM bytecode.
The EVM instruction set will be a helpful reference.
1 A simple contract
Our first contract has a constructor and a state variable:
/ / c1.solpragma solidity ^ 0.4.11 X contract C {uint256 a; function C () {a = 1;}}
Compile this contract with solc:
Solc-- bin-- asm c1.sol = c1.sol:C = EVM assembly: / * "c1.sol": 26:94 contract C {. * / mstore (0x40, 0x60) / * "c1.sol": 59:92 function C () {. * / jumpi (tag_1) Iszero (callvalue)) 0x0 dup1 revert tag_1: tag_2: / * "c1.sol": 84:85 1 * / 0x1 / * "c1.sol": 80:81 a * / 0x0 / * "c1.sol": 80:85 a = 1 * / dup2 swap1 sstore pop / * "c1.sol": 59:92 function C () {/ tag_3: / * "c1.sol": 26:94 contract C {. * / tag_4: dataSize (sub_0) dup1 dataOffset (sub_0) 0x0 codecopy 0x0 returnstop sub_0: assembly {/ * "c1.sol": 26:94 contract C {. * / mstore (0x40) 0x60) tag_1: 0x0 dup1 revert auxdata: 0xa165627a7a72305820af3193f6fd31031a0e0d2de1ad2c27352b1ce081b4f3c92b5650ca4dd542bb770029} Binary:60606040523415600e57600080fd5b5b60016000819055505b5b60368060266000396000f30060606040525b600080fd00a165627a7a72305820af3193f6fd31031a0e0d2de1ad2c27352b1ce081b4f3c92b5650ca4dd542bb770029
6060604052... This string of numbers is the bytecode that EVM actually runs.
2 step by step
The first half of the compilation assembly is a boilerplate statement that exists in most Solidity programs. We'll look at these later. Now, let's look at the unique part of the contract, which simply stores variable assignments:
A = 1
The bytecode representing this assignment is 6001600081905550. Let's break it down into one instruction:
60 0160 0081905550
EVM is essentially a loop that executes every command from top to bottom. Let's annotate the assembly code with the corresponding bytecode (indented under the tag tag_2) to better see the association between them:
Tag_2: / / 60 01 0x1 / / 60 00 0x0 / / 81 dup2 / / 90 swap1 / / 55 sstore / / 50 pop
Note that 0x1 is actually shorthand for push (0x1) in assembly code. This instruction pushes the number 1 into the stack.
It's still hard to understand what's going on just staring at it, but don't worry, simulating EVM one line at a time is relatively simple.
3 Analog EVM
EVM is a stack machine. The instruction may take a numeric value on the stack as an argument, or push the value into the stack as a result. Let's think about the add operation.
Suppose there are two values on the stack:
[1 2]
When EVM sees add, it adds up the two items at the top of the stack and pushes the answer into the stack. The result is:
[3]
Next, we use the [] symbol to identify the stack:
/ / empty stack stack: [] / / Stack with three data, top item is 3, stack bottom item is 1stack: [3 21] use {} symbol to identify contract memory: / / empty storage store: {} / numeric 0x1 is stored in 0x0 location store: {0x0 = > 0x1} now let's look at the real bytecode. We will simulate the 6001600081905550 byte sequence like EVM. And print out the machine status of each instruction: / / 60 01: press 1 into the stack 0x1 stack: [0x1] / / 60 00: press 0 into the stack 0x0 stack: [0x0 0x1] / / 81: copy the second item in the stack dup2 stack: [0x1 0x0 0x1] / 90: two pieces of data at the top of the exchange stack swap1 stack: [0x0 0x1 0x1] / / 55: store the numerical 0x01 in the location of 0x0 / / this fuck Sstore stack: [0x1] store: {0x0 = > 0x1} / / 50: pop (discard the top data) pop stack: [] store: {0x0 = > 0x1}
Finally, the stack is empty, and there is an item of data in the memory.
It is worth noting that Solidity has decided to save the state variable uint256 an in the location of 0x0. Other languages can choose to store state variables anywhere else.
The 6001600081905550 byte sequence is essentially represented by the operation pseudocode of EVM:
/ / a = 1sstore (0x0, 0x1)
If you look closely, you will find that the dup2,swap1,pop is redundant, and the assembly code can be simpler:
0x10x0sstore
You can simulate the above three instructions, and then you will find that their machine states are all the same:
Stack: [] store: {0x0 = > 0x1} 4 two storage variables
Let's add an additional storage variable of the same type:
/ / c2.solpragma solidity ^ 0.4.11 X contract C {uint256 a; uint256 b; function C () {a = 1; b = 2;}}
After compilation, let's take a look at tag_2:
The preceding code of $solc-- bin-- asm c2.sol// ignores tag_2: / * "c2.sol": 99tag_2 100 1 * / 0x1 / * "c2.sol": 95:96 a * / 0x0 / * "c2.sol" a = 1 * / dup2 swap1 sstore pop / * "c2.sol": 112asm c2.sol// 113 2 * / 0x2 / * "c2.sol": 108 tag_2 109 B * / 0x1 / * "c2.sol": 108 0x1 113 b = 2 * / dup2 swap1 sstore pop
Compiled pseudo code:
/ a = 1sstore (0x0, 0x1) / / b = 2sstore (0x1, 0x2)
We can see that the storage locations of the two storage variables are arranged in turn, an in the 0x0 location and b in the 0x1 location.
5 Storage and packaging
Each slot can store 32 bytes. If a variable only needs 16 bytes, but using all 32 bytes would be wasteful. Solidity provides an optimization for efficient storage: if possible, package two smaller data types and store them in a storage slot.
We modify an and b to 16-byte variables:
Pragma solidity ^ 0.4.11 X contract C {uint128 a; uint128 b; function C () {a = 1; b = 2;}}
Compile this contract:
$solc-bin-asm c3.sol
The resulting assembly code is now a little more complex:
Tag_2: / / a = 1 0x1 0x0 dup1 0x100 exp dup2 sload dup2 0xffffffffffffffffffffffffffffffff mul not and swap1 dup4 0xffffffffffffffffffffffffffffffff and mul or swap1 sstore pop / / b = 2 0x2 0x0 0x10 0x100 exp dup2 sload dup2 0xffffffffffffffffffffffffffffffff mul not and swap1 dup4 0xffffffffffffffffffffffffffffffff and mul or swap1 sstore pop
The assembly code above packages the two variables in a storage location (0x0), like this:
[b] [a] [16 bytes / 128 bits] [16 bytes / 128 bits]
The reason for packaging is that by far the most expensive operation is the use of storage:
The sstore instruction takes 20000 gas to write to a new location for the first time.
It takes 5000 gas for the sstore instruction to subsequently write to an existing location.
The cost of the sload instruction is 500 gas
Most instructions cost 3 to 10 gas
By using the same storage location, Solidity pays 5000 gas for storing the second variable instead of 20000 gas, saving 15000 gas.
6 more optimizations
Instead of using two separate sstore commands to store variables an and b, it should be possible to package two 128bit numbers into one number and store them in memory using a single 'sstore' instruction, which saves an extra 5000 gas.
You can let Solidity achieve the above optimization by adding the optimize option:
$solc-bin-asm-optimize c3.sol
The resulting assembly code has only one sload instruction and one sstore instruction:
Tag_2: / * "c3.sol": 95:96 a * / 0x0 / * "c3.sol": 95 dup1 sload 100a = 1 * / dup1 sload / * "c3.sol": 108 dup1 sload 113 b = 2 * / 0x200000000000000000000000000000000 not (sub (exp (0x2, 0x80)) 0x1)) / * "c3.sol": 95c3.sol 100a = 1 * / swap1 swap2 and / * "c3.sol": 99Rose 100 1 * / 0x1 / * "c3.sol": 95c3.sol 100a = 1 * / or sub (exp (0x2, 0x80), 0x1) / * "c3.sol": 108Rod 113b = 2 * / and or swap1 sstore
The bytecode is:
600080547002000000000000000000000000000000006001608060020a03199091166001176001608060020a0316179055 parses the bytecode into one instruction line: / / push 0x060 00max / dup180// sload54// push27 presses the following 17 bytes into the stack as a 32-word number 70020000000000000000000000000000 / * not (exp (0x2, 0x80) (0x1)) * / / push 0x160 01max / push 0x80 (32) 60 80max / push 0x80 (2) 6002max / exp0a// sub03// not19// swap190// swap291// and16// push 0x160 01max / or17/* sub (exp (0x2, 0x80), 0x1) * / push 0x160 01max / push 0x8060 80max / push 0x0260 02max / exp0a// sub03// and16// or17// swap190// sstore55
The above assembly code uses four magical values:
* 0x1 (16 bytes), using a low 16-byte / / represented as 0x0116:32 0x0000000000000000000000000000000000:16 0x00000000000000000000000000000000000000000001 * 0x2 (16 bytes), using a high 16-byte / / represented in the bytecode as 0x200000000000000000000000000000000 16:32 0x0000000000000000000000000000000200:16 0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 * not (exp (0x2, 0x80), 0x1) / High 16-byte mask 16:32 0x0000000000000000000000000000000000:16 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
The code converts some bits of these values to achieve the desired results:
16:32 0x00000000000000000000000000000002 00:16 0x00000000000000000000000000000001
Finally, the 32-byte value is saved in the 0x0 location.
The use of 7Gas
600080547002000000000000000000000000000000006001608060020a03199091166001176001608060020a0316179055
Notice that 0x200000000000000000000000000000000 is embedded in the bytecode. But the compiler may also choose to use the exp (0x2, 0x81) instruction to calculate the value, which results in a shorter bytecode sequence.
But it turns out that 0x200000000000000000000000000000000 is cheaper than exp (0x2, 0x81). Let's take a look at the information related to gas fees:
The fee for each zero byte of data or code for a transaction is 4 gas
The fee for each non-zero byte of data or code for a transaction is 68 gas
To calculate the gas cost of the following two representations:
0x200000000000000000000000000000000 bytecode contains a lot of zeros, which is much cheaper. (1 * 68) + (32 * 4) = 196
The 608160020a bytecode is shorter, but not zero. 5 * 68 = 340
The longer bytecode sequence has a lot of zeros, so it's actually cheaper!
These are all the contents of the article "what is the assembly code of the block chain etai Fong virtual machine". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.