• 沒有找到結果。

Our algorithm for constructing the control flow graph (1) is based on this rules. In the algorithm, in line 5, we use a list to record that special instruction. If the instruction being read is one of the special instruction, for example (line 24 to line 33), rule two, the J U M P or J U M P I instruction will mark ask the end of a execution block, thus a new block will be appended to the list of node with label (opcodes for the block) and a new edge which starts from the current block to the jumping destination will also be appended to the list of edge. Another tag f romJ U M P I will be marked as true for the instruction J U M P I because it will branch the execution path for the different condition. So after executing J U M P I, two new blocks will be appended to the list of the node. One for the truth condition path, and one for the false condition path. In algorithm line 10 to line 23, J U M P DEST instruction will be the first instruction inside a block. Furthermore, if the block is not ended with J U M P or J U M P I, we ill append a new block into the list of node and a new edge from the last block to the current block when we execute the J U M P DEST instruction. For none special instruction (rule three), they will be record and append as the block’s label (line 34 to line 35).

Using our algorithm we will be able to construct EVM opcode into control flow graph.

Inside the graph, EVM opcode is grouping as a block and at the same time, the variation of stack size and the total gas consumption of this instruction group will be calculate and recorded underneath the block. How we calculate the stack size and the gas consumption for each block is based on table 2 and table 3.

Here we use Graphviz[35], an open source control flow graph construct and visualiza-tion module, to generate a control flow graph from EVM opcode. By using this module, all the nodes and edges will be stored in a list data structure individually, and we can plot out the entire graph to check if there is any vulnerability inside it.

4.3 Stack overflow detection

Using the control flow graph, we want to find out if any positive cycle is contain in the graph. We use the depth-first-search algorithm to traverse through the graph. Depth-first

Mnemonic Gas Used Mnemonic Gas Used

STOP 0 EXTCODESIZE 700

search (DFS) is an algorithm for traversing or searching tree or graph data structures.

The algorithm starts at the root node (the entry point of the opcode will be our root node) and explores as far as possible along each branch before backtracking.

During the traversal, if any block is visiting more than one time, then there is a cycle in this path. Also, we will accumulate the stack size usage and gas consumption during depth-first-search traversal to calculate if the path is a positive cycle. For instance, if a block’s edge is a backward visit edge, that is a cycle contained in the graph. We will check the accumulate stack size, and if the number is increasing after visit the block of the backward edge, then this cycle is a positive cycle, that means traverse this cycle path too many time will make stack overflow happen. On the other hand, if the path is not a cycle, we will proceed to visit those unvisited block, and in the end, all blocks will be visited and checked.

Algorithm 2: Cycle Detection

input : Two lists; nodes list N, edges list E

1 def cycleDetection(N, E ):

2 V ← [];

3 RS ← [];

4 SN ← N[0];

5 DFS(SN, N, E, V, RS);

In the beginning of the algorithm (algorithm 2), we will initiate two lists, visited node and record of the stack. Total five parameter will be use as input of the DFS algorithm (algorithm 3. Here is the details about the DFS positive cycle checking process. We break the process into four steps.

1. Put the block (father block) into the visited list and record stack(line 5 to line 6).

2. Find the next block (child block) that is connected to the father block(line 7 to line 11).

3. If the child block is not inside the visited list, go back and do step one(line 12 to line 14).

4. If the child block is inside the visited list and stack, then a cycle is found. At the same time, sum up the stack size usage, if the number is bigger than the previous number, this path is a positive cycle(line 15 to line 22).

Following the above steps, we can detect any positive cycle inside the control flow graph. Using the path, we want to check if it is reachable when the smart contract is executing. Maybe the positive cycle path is not going to be executed over 1024 time due to the limitation of the parameter of the loop condition. Or the gas consumption is going to reach the gas limitation before the EVM stack overflow. As the result, the positive cycle path is extracting from the original control flow graph after the DFS checking for a more accurate checking on the stack state and gas consumption.

Algorithm 3: Depth-First-Search

input : staring node SN, nodes list N, edges list E, visited list V, record stack RS

1 def depthFirstSearch(SN, N, E, V, RS ):

2 SS ← 0;

Gas is the unit in Ethereum ecosystem for counting transaction fee. If someone wants to transfer cryptocurrencies, using a function inside a smart contract will be an option.

When triggering a function inside a smart contract, a transaction fee is calculated by gas usage multiply with gas price. Gas price is a custom parameter defined by the user who wants to make a transaction by smart contract. Higher the gas price is, faster the miners will mine the transaction due to higher transaction fees they will get. On the other hand, the gas used by a transaction is determining by the functional complexity. Executing a complicated function cost more fees than a short one because EVM calculates the gas by opcodes involved in the function.

As we know in blockchain system, each block will contain several transactions. Since there is an upper bound of total gas used for each block to prevent smart contract con-sumes too many gases that cause the total gas used to exceed the upper bound, blockchain system will reject the request to deploy the smart contract to the block. Besides, when the user wants to use a smart contract to make a transaction, they have to set a gas limit, a value of estimation that this transaction might consume. If the actual gas used is larger than the gas limit, EVM will rollback all the status that had changed during this transaction and still charge the user the transaction fee it cost.

In most case, the user can set the gas limit to a very high value, so the chance of outnumbering is relatively low. However, as we discovered, many smart contracts contain a function with a loop inside. Moreover, the condition value which determines the precise iteration of this loop in most of the smart contract is a function parameter or a local variable. Sometimes we do not even know the exact value when we trigger this function.

That is to say, if we can estimate how much gas will be used by each function inside the smart contract, we will get a reference gas value when setting the gas limit. Each opcode has its specific gas consumption. Table 3 shows how much gas will be used during executing of each instruction. Most opcode consume a specific number of gas. It is easy to calculate the gas consumption for those opcodes.

相關文件