HI, welcome me to continue the deconstruction of smart contracts. This is the third part of this article series, if you haven’t read the previous article, please take a look:
(1) the basic code and operation mode;
(2) analysis to create and run time code;
We are the deconstruction of a simple Solidity intelligent contract EVM byte code.
In the article, we will determine the intelligent contract byte code is divided into two parts to create and run, and know why to do so, in-depth understanding of the creation part, now is the time to begin our exploration of runtime part. If you look at the deconstruction map, we can first look at the name of BasicToken.evm (run time) of the second large split block.
This may seem a bit scary, because the running code length is at least four times to create a code size! But don’t worry, we in the previous article for understanding EVM code and the development of skills, and we use absolute reliable “divide and rule” strategy, will make this a challenge even more systematic, more likely to. This is just the beginning, we will continue to identify the independent structure, continue until a split decomposition can resolve the problem.
First of all, let us return to the Remix online editor, and use the runtime bytecode start a debugging session. What do we do? Last, we deploy smart contracts and debug the deployment services. This time, we will use one function to interact with the intelligent interface contracts have been deployed, and debug the transaction.
First, we recall the intelligent contract together:
What is this interface? It is smart in all public contracts or external methods list that any account or contract intelligent Ethernet Fang can interact. Private and internal methods not shown here, how smart and contract runtime code specific part of the interaction, this paper will focus on the deconstruction.
We can try, click the Remix “run” totalSupply button in the panel. You should immediately see the response button below, this is what we expect, because we will be intelligent as the initial token deployment of supply contracts. Now, in the Console panel, click the Debug button to use this particular transaction to start a debugging session. Please note that the Console panel will have multiple Debug button; make sure you are using the latest version.
In this case, we do not have to debug the 0x0 address of the transaction, as we saw in the previous article, create a smart contract. On the contrary, we are debugging of intelligent transaction contract itself — i.e. its runtime code.
If the pop-up “instruction” panel, it should be able to verify the Remix commands listed in figure BasicToken.evm and deconstruction (runtime) part of the instructions in the same. If they do not match, then the problem. Try again and make sure you use the correct settings.
The first thing you may notice is about 60% of you in the debugger and the transaction instruction 246 slider at bytecode. Why? Because Remix is a very generous program, it takes you directly to the EVM to execute the totalSupply function part of the body. However, before this happened a lot of things, these are what we should pay attention to here. In fact, we don’t even study on the implementation of the function in this paper. Our only concern is the Solidity generated EVM code how to route incoming transaction, this is our contract as “function selector” will work to understand.
Therefore, it has been dragged and seize the slider to the left, so we started from zero instruction. As we saw before, EVM is always from the instruction 0 executable code, there is no exception, and then through the rest of the code. Let us through the operation code to complete the implementation of the operation code.
The first structure is that we have seen in the past (in fact, we can see many):
Figure 1. free memory pointer
This is the Solidity EVM code generated by any operation will always be executed before the call: a point for later use stored in memory.
Let’s see what happens next:
Figure 2. Calldata length check.
If you open the Remix in the Debug tab in the Stack panel and skip instructions 5 to 7, you will see the stack now contains two digital. If you have problems in reading these long number, please note that you adjust the width of the panel to Remix debugging, very well suited for digital single. First from the regular push, but the second is the implementation of the operation code results, as the yellow book, no parameters and return to the input data in the current environment or size, we often called calldata:4CALLDATASIZE
What is the calldata? The document explained ABI specification as the Solidity of calldata is a block encoding sixteen hexadecimal numbers, which contains information about the intelligent contract we have to call the function, and its parameters or data. Simply speaking, it consists of a “ID function”, it is through the hash function signature (truncated to the first four bytes) and then compressed parameters data generation. If necessary, you can study in detail the document links, but don’t worry about this package to the fine details of how to work. It is explained in the document, but a little difficult to grasp. With the actual example it would be easier to understand.
Let’s see what calldata. Open the call data panel in the Remix debugger, see: 0x18160ddd. This is by applying the algorithm of keccak256 function signature for 4 byte string to generate accurate totalSupply () “and executes the truncation. Because of this particular function with no parameters, so it is just a four byte function ID. When CALLDATASIZE is called, it will be just second push 4 onto the stack.
Then, 8 LT instructions used to verify the calldata size is less than 4. If it is, then the following two instruction executes the JUMPI 86 (0x0056). This is less than four bytes, so in this case there will be no jump, will continue to execute the instruction execution stream 13. but before we do, let us assume that we use the empty calldata call our intelligent contract – that is to say, 0x0 instead of 0x18160ddd. You can use Remix btw to do this, but you can manually construct transaction.
In this case, we will enter the 86 instruction, it is basically a few zero onto the stack and deliver them to the REVERT operation code. Why? Well, because this intelligent contract no backup function. If the byte code does not recognize the incoming data, it will transfer to rollback function, if the structure is not “capture” call, this recovery structure will be terminated, absolutely no rollback. If there is no return, then nothing to do, but the call completely restored.
Now, let’s do some more interesting things. Return to the Remix Run tab, copy the Account address, and use it as a parameter to invoke the balanceOf instead of totalSupply to debug the transaction. This is a new debugging session; let us temporarily forget totalSupply. Navigate to the 8 command, CALLDATASIZE will now 36 (0x24) onto the stack. If you look at the calldata, which is now 0x70a08231000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c.
This new calldata is actually very easy to decompose: four bytes of the 70a08231 hash signature is, behind the “balanceOf (address)” contains 32 bytes we passed as parameters. Why is 32 bytes, if Ethernet address square only 20 bytes long, curious readers may ask? ABI always uses 32 byte “word” or “slot” to save the parameters used in a function call.
We continue to call balanceOf environment, let us in the instruction 13 left where we left off, no content in the stack at this time. 13 instructions then push the 0xFFFFFFFF onto the stack, and the next instruction will be 29 bytes of 0x000000001000… The digital 000 is pushed onto the stack. We’ll see why. Now, only need to pay attention to a four byte, one containing four bytes of 0’s’.
The next CALLDATALOAD takes a parameter (in the parameter instruction 48 onto the stack) and read a 32 byte from the location of the calldata block, in this case, the Yul will be:
Basically my entire calldata onto the stack. The interesting part of it. The DIV consumes two parameters from the stack, and it gets the calldata divided by the strange 0x000000001000… 000 digital filter, effectively in addition to all content function signature in calldata, and will stay on the stack: 0x000… 000070a08231. The next instruction using AND, it also consumes two elements in the stack: our ID function and digital with four byte F. This is to ensure that the signature of Hashi is just eight bytes long, if there is any other content, any other content is shielded. I think the security measures used by Solidity.
In short, we just check whether calldata is too short, if so, reduction, then a little improvement, so that we can have our function in the stack,
In addition, we almost finished. The next section will be very easy to understand:
Figure 3. function selector
In order 53, the code will 18160ddd (function ID totalSuppy) onto the stack, the incoming calldata and then use the a DUP2 to copy the 70a08231 currently exists on the stack section two position value. Why you want to copy? Because the EQ 59 instruction operation code will consume two values in the stack, and we want to maintain the 70a08231 value, because we had trouble extracting it from calldata.
The code will now try to match one of the known functions of ID and ID function in calldata. Because the 70a08231 entry, it will not match 18160ddd, skip the JUMPIat instruction 63. but it will be in the next examination, and in the instruction 74 jump to JUMPI.
Let us take the time to look at these checks on each contract equal intelligent public or external function. This is the core function selector: to act as a switch statement, simply will execute the route to the right part of the code. This is our center “”.
Therefore, as a final case, execution will bring us into the position of JUMPDESTat 130, as we will see in the next part of this series that the balanceOf function of the ABI wrapper”. As we will see, this wrapper will be responsible for unpacking transaction data for the function body consumption.
Try to transfer the debugging function. The function selector really no mystery. This is a simple and effective structure in each contract door (at least all those compiled from Solidity) and will perform a redirect to the appropriate location in the code. This is the Solidity for the intelligent contract bytecode provides analog power of multiple entrance points the way, so that the interface.
Look at the map of this is just our deconstruction, deconstruction:
Figure 4. function selector and intelligent contract runtime code main entrance point.
All in all, you guys, imperceptibly to solidity familiar with the underlying code is more than most people, stick to it, you will be able to open it.
* by Alejandro Santander starting in medium, and by the cheetah block chain security translation *
Cheetah Kingsoft to block chain security technology based on combination of artificial intelligence, NLP technology, provide contract audit, sentiment analysis and ecological security services for the blockchain users.
The official website of Ratingtoken https://www.ratingtoken.net/ from=z?