A vulnerability detection method for historical transactions of Ethereum smart contracts

By simulating the execution of historical transactions of Ethereum smart contracts in EVM and analyzing intermediate states to detect vulnerabilities, the problem of difficult conversion of transaction sequences into IR forms in the existing technology is solved, efficient and accurate vulnerability detection is achieved, and the security of smart contracts is improved.

CN117911030BActive Publication Date: 2025-08-12HANGZHOU DIANZI UNIV
View PDF 2 Cites 0 Cited by

Patent Information

Application Number
CN202311795616.8
Authority / Receiving Office
CN · China
Patent Type
Patents(China)
Current Assignee / Owner
Filing Date
2023-12-25
Publication Date
2025-08-12
Estimated Expiration
2043-12-25

AI Technical Summary

Technical Problem

The existing Ethereum smart contract historical transaction vulnerability detection method cannot effectively convert the transaction sequence into IR form when facing complex arithmetic operations, resulting in wasted computing resources and detection timeouts, and the vulnerability attacks in transactions cannot be analyzed.

Method used

By simulating the execution of historical transactions in EVM, reproducing the transaction process, and retaining the intermediate state during the execution process, defining vulnerability detection rules, analyzing the intermediate state of the transaction to determine whether there are vulnerability characteristics, directly analyzing the opcode relationship in the same transaction behavior, avoiding global dependency analysis.

Benefits of technology

It improves the efficiency and accuracy of the detection of historical transaction vulnerabilities of Ethereum smart contracts, can effectively detect six types of vulnerabilities, reduce the risk of smart contract writing, and improve security.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN117911030B_ABST
    Figure CN117911030B_ABST
Patent Text Reader

Abstract

The present invention discloses a vulnerability detection method for historical transactions of Ethereum smart contracts. The present invention mainly includes the following stages: 1. Transaction sequence processing stage, which includes reading the transaction sequence, initializing the opcode sequence into an opcode object sequence, calculating the number of calls and call depth of the opcode object, and constructing a control flow graph and an execution flow graph. 2. Transaction execution stage, which includes selecting the control flow graph execution stack and executing the control flow graph. 3. Transaction execution result analysis stage, which includes obtaining the call path and analyzing various transaction vulnerabilities. The present invention is applicable to six types of Ethereum smart contract transaction vulnerabilities, and summarizes the manifestations of transaction vulnerabilities based on the vulnerability detection results. Smart contract writers can reduce the probability of smart contract vulnerability writing through feedback in the form of transaction vulnerability attacks, thereby improving the security of smart contracts. The present invention has the advantages of high detection efficiency, high accuracy, and strong scalability.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the field of smart contract security, and more specifically, to a method for detecting vulnerabilities in historical transactions of Ethereum smart contracts. Background Art

[0002] Smart contracts are distributed, self-executing programs running on a blockchain network. Once deployed on-chain, smart contracts are immutable and unmodifiable. Therefore, ensuring they are free of vulnerabilities before being deployed is crucial. Current smart contract security research primarily focuses on vulnerability detection within the smart contract source code, with limited attention paid to the security of transactions between smart contracts. Ethereum smart contract vulnerabilities are also triggered during transactions after the smart contract is deployed on-chain. Analyzing the details of smart contract vulnerabilities in Ethereum transactions and understanding the attack behavior of malicious contracts can help detect more attack instances in historical Ethereum transactions. Ultimately, this can provide Ethereum smart contract developers with a reference for attack examples, improving the quality of Ethereum smart contract code and preventing non-standard and vulnerable Ethereum smart contract code. This, in turn, reduces the incidence of vulnerabilities in Ethereum smart contracts after they are deployed on-chain.

[0003] Related work on vulnerability detection in historical transactions of Ethereum smart contracts: TXSPECTOR converts the dependencies between the opcode sequences of smart contract transactions into IR (a special intermediate representation), derives the operation information of each opcode based on TR, writes detection rules for various vulnerabilities, and uses souffle (static code solver) to analyze the derived opcode operation information for vulnerability feature analysis and matching.

[0004] However, when encountering historical transaction sequences involving complex arithmetic operations, TxSpector cannot effectively convert the transaction sequences into IR form, making it unable to analyze the corresponding transaction sequences. TxSpector's vulnerability detection method can be abstracted to performing global dependency analysis on the exported opcode information. This method analyzes opcodes that do not belong to the same Ethereum smart contract operation, wasting computing resources. Furthermore, when encountering highly complex transaction sequences, the need to calculate a large number of inter-opcode dependencies can cause computation timeouts, making it impossible to analyze the vulnerability attacks in the transactions.

[0005] In response to the above problems, the present invention proposes to reproduce the historical transactions of Ethereum smart contracts (re-execute historical transactions) and judge whether this historical transaction is attacked by the corresponding vulnerability based on the execution information in the process of reproducing the historical transactions. By simulating the execution of historical transactions in EVM (Ethereum Virtual Machine) and retaining the intermediate state of the transaction sequence during the execution process. Define the detection rules for various vulnerabilities, analyze whether there are corresponding vulnerability features in the intermediate state of the transaction, and judge whether the Ethereum smart contract transaction is attacked maliciously based on the detected vulnerability features. This method does not need to convert the transaction sequence into IR form, and only analyzes the relationship between the opcodes in the same transaction behavior. There is no need to analyze the global opcodes, which improves the detection efficiency and accuracy. Summary of the Invention

[0006] The purpose of this invention is to propose a vulnerability detection method for Ethereum smart contract historical transactions based on the existing technology, which mainly includes three stages: transaction sequence processing stage, transaction execution stage, and transaction execution result analysis stage. The detection method processing flow is as follows Figure 1 As shown in the figure: (1) The smart contract transaction sequence file is used as the input of the transaction sequence preprocessing stage, which mainly consists of two parts. First, according to the transaction sequence read from the contract transaction sequence file, the transaction operation code sequence is initialized as the operation code object sequence. Second, the execution flow graph is constructed based on the operation code object sequence in the first part, and the corresponding control flow graph is constructed for each basic block of the execution flow graph. (2) The execution flow graph and the corresponding control flow graph generated in this stage are used to reproduce the contract historical transactions in the transaction execution stage, and to obtain the call path in the transaction execution result analysis stage. In the transaction execution stage, according to the execution flow graph and control flow graph constructed in the previous stage. First, the corresponding execution stack is selected for each basic block of the execution flow graph, and the corresponding execution stack is used as the execution environment to execute the control flow graph corresponding to the basic block of the execution flow graph in the EVM. During the execution of the control flow graph, the intermediate state of execution in the execution stack is retained, and the intermediate state of execution is used for vulnerability analysis of the transaction in the transaction execution result analysis stage. (3) In the transaction execution result analysis phase, the call path between contracts in the transaction sequence is first obtained based on the execution flow graph and control flow graph generated in the transaction sequence processing phase; then, potential vulnerabilities in the transaction are detected by combining the call path, the intermediate execution state generated in the transaction execution phase, and the predefined vulnerability detection rules. Finally, a transaction vulnerability detection report is output based on the detection results.

[0007] Furthermore, the present invention specifically comprises the following steps:

[0008] 1. Transaction sequence processing stage, the specific flow chart of this stage is as follows Figure 2 .

[0009] 1-1. Get the transaction sequence

[0010] Read the transaction operation code sequence OC={oc1,…,oc i ,…,oc n}, indicating that the operation code sequence 0C has n operation codes; among them, the operation code oc i Expressed as a triple: (pc i ;opcode i ;value i ), the three elements represent the pc value of the opcode, the opcode itself and the operating parameters of the opcode; during the reading process, the opcode oc i Initialized as the opcode object opObject i :[1ine i , (pc i , opcode i ,value i , call_depth i , call_num i )], where line i Represents the operation code oc i Line number in the opcode sequence OC, call_depth i 、call_num i Represents the call depth and call count corresponding to the opcode, and all opcodes oc i After all are initialized as opcode objects, take the opcode object sequence as input and proceed to step 1-2 to calculate the call depth and call count corresponding to the opcode object.

[0011] 1-2. Calculate the opcode call depth and call count

[0012] The call depth and call count of an opcode are auxiliary data used to distinguish the call relationships between smart contracts in a transaction. Both the call depth and call count are initialized to 0, and the call count is an incremental value. The call count and call depth of an opcode object are used during the transaction execution phase.

[0013] Traverse the opcode sequence OC obtained in step 1-1. The subscript of the opcode in the traversal process is defined as i. The initial call count is 0. When the opcode object opObject is encountered i The pc value is 0 but the current traversal index i is not 0, and the call count is increased by 1. This means that the current transaction execution flow has flowed to a new smart contract. And the corresponding call count is assigned to the corresponding operation code object opObject i call_num i property.

[0014] Whenever an opcode object opObject is encountered during the traversal iThe pc value is 0 but the current traversal index i is not 0, the call depth is increased by 1. When the traversal reaches the opcode itself related to the call or the creation i When judging, if the current operation code object opObject i Same as the previous opcode object opObject i-1 call_num i The attributes are equal and the previous opcode itself is opcode i If it is not a termination type opcode, it means that the currently called smart contract has not yet finished executing. Therefore, call_depth i Otherwise, it means that the current smart contract execution has ended and returns to the previous level smart contract, then call_depth i Subtract 1. And assign the corresponding call depth to the corresponding opcode object opObject i call_depth i property.

[0015] Furthermore, call-related opcodes include CALL, DELEGATECALL, CALLCODE, STATICCALL, etc., creation-related opcodes include CREATE, CREATE2, etc., termination-related opcodes include THROWI, RETURN, REVERT, etc. The opcode attributes are defined or modified according to the opcodes and attributes involved in the transaction vulnerability to be detected, as shown in Table 1.

[0016] Table 1 Operation code attributes

[0017]

[0018]

[0019] 1-3. Construction of execution flow graph

[0020] The execution flow graph represents the call execution order between smart contracts in a transaction. The structure of the execution flow graph is EFGblock = {efgblock1, ..., efgblock s ,…,efgblock s}, the structure of the execution flow graph basic block is efgblock s :(startBlockPC s , endBlockPC s , instrList s , CFGBlockMap s , StackEvents s ,allCallPath s), the corresponding attributes in the structure are given in Table 2.

[0021] Traverse the opcode sequence 0C obtained in step 1-1, define a Boolean variable start during the traversal process, with an initial value of true, and set start to false after initializing the first execution flow graph basic block.

[0022] When encountering an opcode related to a call or termination, i When the current operation code object opObject1 is the same as the previous operation code object opObject i-1 The call_num attribute is not equal to the previous opcode object opObject i-l When the opcode is a termination type, it indicates that the smart contract execution has ended. A new execution flow graph basic block needs to be generated. Set start to true and initialize a new execution flow graph basic block. After initializing a new execution flow graph basic block, set start to false.

[0023] When traversing to other types of opcodes other than call-related or termination-related, add the opcode object opObject1 to the instrList of the current execution flow graph basic block s In the properties, the opcode object opObject at the start and end positions of the execution flow graph basic block i The pc value is assigned to the startBlockPC of the execution flow graph basic block s and endBlockPC s Attributes serve as the start and end locations of basic blocks in the execution flow graph.

[0024] Table 2 Execution flow graph attributes

[0025] Attribute Name describe startBlockPC The starting pc value of the basic block endBlockPC The end pc value of the basic block instrList Opcodes in basic blocks CFGBlockMap Control flow graph of the current basic block decomposition StackEvents opcode_log collection allCallPath Call Path

[0026] 1-4. Construction of control flow graph

[0027] The idea of constructing a control flow graph is to generate a new basic block when traversing the opcodes related to unconditional jump (JUMP), conditional jump (JUMPI), and termination. According to the above opcodes, the control flow graph is divided into four types of blocks: unconditional jump block, conditional jump block, termination block, and ordinary block.

[0028] According to the execution flow graph constructed in steps 1-3, an execution flow graph basic block can construct a corresponding control flow graph.

[0029] The structure of the control flow graph is CFGblock = {cfgblock1, ..., cfgblock j ,…,cfgblock J}, the structure of the control flow graph basic block is cfgblock j :(startBlockPC j , endBlockPc j , instrList j , conditionJumpPos j , conditionJumpExpression j , unconditionJumpPos j , unconditionJumpExpression j , jumpType j , stack j ), the corresponding attributes in the control flow graph structure are given in Table 3;

[0030] Traverse the basic block sequence EFGblock of the execution flow graph obtained in steps 1-3 block by block, and further traverse the instrList of each execution flow graph basic block. During the traversal process, define a Boolean value variable start with an initial value of true. After initializing the first control flow graph basic block, set start to false.

[0031] When traversing to the JUMPI opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblock j The jumpType is set to 1 (conditional jump block).

[0032] When traversing to the JUMP opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j The jumpType is set to 2 (unconditional jump block).

[0033] When traversing to the termination-related opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j Set the jumpType to 4 (terminate block).

[0034] The jumpType of the remaining control flow graph basic blocks is set to 3 (normal block). When the JUMPDEST opcode is traversed, it indicates that the basic block has ended, and start is set to false.

[0035] When traversing to other types of opcodes, the opcode object is added to the instrList attribute of the current control flow graph basic block.

[0036] The pc value of the opcode object at the start and end of the basic block is assigned to the startBlockPC of the basic block in the control flow graph. j and endBlockPC j property.

[0037] And the generated control flow graph needs to be stored in the CFGBlockMap attribute of the execution flow graph basic block, CFGBlockMap: (blockStartPos s , cfgblock s ), the key of CFGBlockMap is the startBlockPC of the control flow graph basic block, and the value is the control flow graph basic block.

[0038] This step ends when all execution flow graph basic blocks have built corresponding control flow graphs.

[0039] Table 3 Control flow graph attributes

[0040] Attribute Name describe startBlockPC The starting pc value of the basic block endBlockPC The end pc value of the basic block instrList Opcodes in basic blocks conditionJumpPos JUMPI jump position conditionJumpExpression Conditional jump expressions unconditionJumpPos JUMP jump position unconditionJumpExpression Unconditional jump expression jumpType Basic block type stack Execution Stack

[0041] Step 2: Transaction execution phase, such as Figure 3 shown.

[0042] 2-1. Control flow graph execution stack selection

[0043] Figure 6 The legend of the execution stack selection of the control flow graph is given in . First, initialize an execution stack list Stack = {stack1, ..., stack s ,…,stack s}, used to save the execution stack at the end of smart contract execution. The execution stack object has the structure stack: (stack, preSrtack.call_depth), with attribute values representing the call depths of the current and previous execution stacks, respectively. The call depth of the execution stack is assigned by the call depth of the first opcode object in the basic block of the control flow graph.

[0044] The initial execution stack is an empty stack stack1. Traverse the execution flow graph basic block sequence. If the pc value of the first opcode object of the execution flow graph basic block is 0, it means that the execution flow has reached a new called smart contract, so a new execution stack stack is generated. s As the execution environment of this basic block.

[0045] Continue traversing. If the first opcode object of the execution flow graph basic block is a call class or create class opcode, it means the previous call has ended. Return the execution stack where the previous call ended. s-1 , judge the stack s-1The call_depth of the first opcode of the current execution flow graph basic block s Are they equal? If they are equal, use stack s-1 As the execution stack of the current basic block. If not equal, return stack s-2 As the execution stack of the currently called smart contract.

[0046] After selecting the execution stack, proceed to step 2-2 to execute the control flow graph. After execution, a judgment is made. If the pc value of the first opcode object of the execution flow graph basic block is 0 and the type of the last opcode object is not a termination type, the execution stack is added to the execution stack list Stack. This situation corresponds to the current new smart contract being called has not yet been executed.

[0047] If the first opcode object of the execution flow graph basic block is of the creation type and the last opcode object type is not of the termination type, the execution stack is added to the execution stack list Stack. This corresponds to the previously called smart contract not yet completed, so the execution stack needs to be retained.

[0048] 2-2. Control Flow Graph Execution

[0049] In this step, the control flow graph constructed by the execution flow graph basic blocks in steps 1-4 is executed, and the execution stack obtained in step 2-1 is used as the execution stack of the current control flow graph.

[0050] The execution order of the control flow graph is determined by the basic block type. The next basic block executed after a conditional jump block is determined by the conditionJumpPos key of that basic block. The next basic block executed is the basic block with the key conditionJumpPos in the execution flow graph's CFGBlockMap. Unconditional jump blocks and termination blocks execute in the same order as conditional jump blocks. Ordinary blocks execute the next control flow graph basic block in sequence.

[0051] Traverse the execution flow graph and execute the control flow graph constructed in steps 1-4 for each execution flow graph basic block. The main execution part is the instrList attribute in the control flow graph basic block. InstrList contains multiple opcode objects. According to the execution logic of the opcode itself, it is executed in the EVM. According to the operation of the opcode in the execution stack, opcode_log is generated. Opcode_log represents the execution status of the opcode in the execution stack. The expression of opcode_log is (pc: opcode→pc→value_pc), where pc is the opcode pc value, opcode represents the opcode itself, and value_pc represents the opcode operation value. Figure 7 Generate a comparison chart of the opcode object and opcode_log during the opcode_log generation process. Figure 8This is a detailed diagram of opcode_log generation.

[0052] All opcode_logs are saved to the StackEvents property of the execution flow graph and serve as a basis for vulnerability detection during the transaction execution analysis phase. The opcode_logs associated with the JUMPI and JUMP opcodes are used as conditionJumpExpression and unconditionJumpExpression, respectively, and assigned to the corresponding properties in the basic blocks of the control flow graph. The opcodes contained in conditionJumpExpression and unconditionJumpExpression indicate a dependency between the opcode and the JUMP / JUMPI opcode.

[0053] During this execution phase, it will also be determined whether this transaction sequence has an integer overflow vulnerability, which will be further explained in the specific implementation method 3-2-6.

[0054] Step 3: Transaction execution result analysis phase, such as Figure 4 shown.

[0055] 3-1 Get the call path

[0056] Based on the execution flow graph and control flow graph constructed in steps 1-3 and 1-4, the call path is obtained. The call path refers to the execution path of the basic block of the control flow graph that contains the CALL opcode. Some vulnerabilities in transactions are triggered by the CALL opcode, such as reentrancy vulnerabilities. If the global execution path is detected, some execution paths may not contain the CALL opcode. If the execution path does not contain the CALL opcode, it is unlikely to contain a reentrancy vulnerability. Executing these paths will result in a waste of computing resources. Therefore, directly detecting the call path for some vulnerabilities can greatly improve detection efficiency.

[0057] In the control flow graph constructed in step 1-4, the basic blocks of the control flow graph have the basic block type attribute. The basic block type determines the execution order between blocks (explained in 2-2). The control flow graph is traversed according to the execution order of the basic blocks. If the instrList attribute of the basic block in the execution path contains the CALL opcode, then the execution path is defined as a call path, and this call path is assigned to the allCallPath attribute of the corresponding execution flow graph basic block as the vulnerability detection path in 3-2.

[0058] 3.2 Transaction Vulnerability Detection

[0059] The detection part of transaction vulnerability detection is the StackEvents generated after the execution of the control flow graph in 2-2 and the call path obtained in 3-1. Then, by writing detection rules to detect the dependencies in the call path of contract execution, vulnerabilities are detected.

[0060] Beneficial effects of the present invention:

[0061] The present invention does not need to convert the contract transaction sequence into IR form, but directly analyzes the contract transaction execution process, thereby improving the efficiency of detecting transaction vulnerabilities. (2) It uses dynamic analysis to detect transaction vulnerabilities. By re-executing historical transactions and combining the saved execution status with predefined vulnerability rules, the correctness of vulnerability detection is guaranteed. (3) The present invention can be well extended to detect other transaction vulnerabilities. By analyzing the vulnerability detection results of the present invention, the details of the smart contract attack can be analyzed, further improving the security of smart contract development.

[0062] This invention is applicable to six types of Ethereum smart contract transaction vulnerabilities. Based on the vulnerability detection results, it summarizes the manifestations of transaction vulnerabilities. By providing feedback on the forms of transaction vulnerability attacks, smart contract developers can reduce the probability of writing smart contract vulnerabilities and improve the security of smart contracts. This invention offers advantages such as high detection efficiency, high accuracy, and strong scalability. BRIEF DESCRIPTION OF THE DRAWINGS

[0063] Figure 1 It is the overall processing flow chart;

[0064] Figure 2 A flow chart for the transaction sequence processing phase;

[0065] Figure 3 This is a flowchart for the transaction execution phase;

[0066] Figure 4 Flowchart for the transaction execution result analysis phase;

[0067] Figure 5 Convert the execution flow graph into a control flow graph flowchart;

[0068] Figure 6 Select a graph for the control flow graph execution stack;

[0069] Figure 7 Generate a comparison chart for opcode_log;

[0070] Figure 8 Generate detailed graph for opcode_log. DETAILED DESCRIPTION

[0071] The following is a complete description of the technical solution of the Ethereum smart contract historical transaction vulnerability detection method in conjunction with the accompanying drawings of the present invention.

[0072] refer to Figure 1 As shown in the overall processing flow chart, the detection method of the present invention for Ethereum smart contract historical transactions consists of three stages: transaction sequence processing stage, transaction execution stage, and transaction execution result analysis stage. The implementation methods of these three stages will be described in detail below:

[0073] 1 The transaction sequence processing stage includes the following steps. The specific flow chart of this stage is as follows: Figure 2 :

[0074] 1-1. Get the transaction sequence

[0075] Read the transaction operation code sequence OC={oc1,…,oc i ,…,oc n}, indicating that the operation code sequence OC has n operation codes; among them, the operation code oc i Expressed as a triple: (pc i ;opcode i ;value i ), the three elements represent the pc value of the opcode, the opcode itself and the operating parameters of the opcode; during the reading process, the opcode oc i Initialized as the opcode object opObject i :[1ine i , (pc i , opcode i ,value i , call_depth i , call_num i )], where line i Represents the operation code oc i Line number in opcode sequence 0c, call_depth i 、call_num i Represents the call depth and call count corresponding to the opcode, and all opcodes oc i After all are initialized as opcode objects, take the opcode object sequence as input and proceed to step 1-2 to calculate the call depth and call count corresponding to the opcode object.

[0076] 1-2. Calculation of opcode call depth and call count

[0077] The call depth and call count of an opcode are auxiliary data used to distinguish the call relationships between smart contracts in a transaction. Both the call depth and call count are initialized to 0, and the call count is an incremental value. The call count and call depth of an opcode object are used during the transaction execution phase.

[0078] Traverse the opcode sequence OC obtained in step 1-1. The subscript of the opcode in the traversal process is defined as i. The initial call count is 0. When the opcode object opObject is encountered i The pc value is 0 but the current traversal index i is not 0, and the call count is increased by 1. This means that the current transaction execution flow has flowed to a new smart contract. And the corresponding call count is assigned to the corresponding operation code object opObject i call_num i property.

[0079] Whenever an opcode object opObject is encountered during the traversal i The pc value is 0 but the current traversal index i is not 0, the call depth is increased by 1. When the traversal reaches the opcode itself related to the call or the creation i When judging, if the current operation code object opObject i Same as the previous opcode object opObject i-1 call_num i The attributes are equal and the previous opcode itself is opcode i If it is not a termination type opcode, it means that the currently called smart contract has not yet finished executing. Therefore, call_depth i Otherwise, it means that the current smart contract execution has ended and returns to the previous level smart contract, then call_depth i Subtract l. And assign the corresponding call depth to the corresponding opcode object opObject i call_depth i property.

[0080] Furthermore, call-related opcodes include CALL, DELEGATECALL, CALLCODE, STATICCALL, etc., creation-related opcodes include CREATE, CREATE2, etc., termination-related opcodes include THROWI, RETURN, REVERT, etc., and opcode attributes are defined or modified based on the opcodes and attributes involved in the transaction vulnerability to be detected.

[0081] 1-3. Construction of execution flow graph

[0082] The execution flow graph represents the call execution order between smart contracts in a transaction. The structure of the execution flow graph is EFGblock = {efgblock1, ..., efgblock s ,…,efgblock s}, the structure of the execution flow graph basic block is efgblock s :(startBlockPCs , endBlockPC s , instrList s , CFGBlockMap s , StackEvents s ,allCallPath s ), the corresponding attributes in the structure are given in Table 2.

[0083] Traverse the opcode sequence OC obtained in step 1-1, define a Boolean variable start during the traversal process, with an initial value of true, and set start to false after initializing the first execution flow graph basic block.

[0084] When encountering an opcode related to a call or termination, i When the current operation code object opObject i The same as the previous opcode object opObject i-1 The call_num attribute is not equal to the previous opcode object opObject i-1 When the opcode is a termination type, it indicates that the smart contract execution has ended. A new execution flow graph basic block needs to be generated. Set start to true and initialize a new execution flow graph basic block. After initializing a new execution flow graph basic block, set start to false.

[0085] When traversing to other types of opcodes other than call-related or termination-related, the opcode object opObject i Add to the instrList of the current execution flow graph basic block s In the properties, the opcode object opObject at the start and end positions of the execution flow graph basic block i The pc value is assigned to the startBlockPC of the execution flow graph basic block s and endBlockPC s Attributes serve as the start and end locations of basic blocks in the execution flow graph.

[0086] During the traversal process, the execution flow graph basic blocks are added to efgBlockList one by one. After the traversal is completed, efgBlockList is returned. efgBlockList is the constructed execution flow graph.

[0087] Algorithm 1 for constructing the execution flow graph is as follows:

[0088]

[0089]

[0090] 1-4 Construction of Control Flow Graph

[0091] Figure 5 This section shows the process of converting a basic block of an execution flow graph into a control flow graph. The control flow graph represents the execution order of smart contract behaviors. The control flow graph is converted from the execution flow graph generated in 1-3. One basic block of the execution flow graph can be converted into several basic blocks of the control flow graph.

[0092] The structure of the control flow graph is CFGblock = {cfgblock1, ..., cfgblock j ,…,cfgblock j}, the structure of the control flow graph basic block is cfgblock j :(startBlockPC j , endBlockPc j , instrList j , conditionJumpPos j , conditionJumpExpression j , unconditionJumpPos j , unconditionJumpExpression j , jumpType j , stack j ), the corresponding attributes in the control flow graph structure are given in Table 3;

[0093] The idea of constructing a control flow graph is to generate a new basic block when traversing the opcodes related to unconditional jump (JUMP), conditional jump (JUMPI), and termination. According to the above opcodes, the control flow graph is divided into four types of blocks: unconditional jump block, conditional jump block, termination block, and ordinary block.

[0094] The construction of the control flow graph is determined by key opcodes related to jumps or terminations, including jump-related opcodes (such as JUMP / JUMPI) and termination-related opcodes (such as STOP / REVERT / RETURN). When an opcode related to one of the above opcodes is traversed, a new basic block is generated. The jumpType value of the basic block is assigned based on the key opcode (1, 2, 3, and 4 correspond to conditional jump blocks, unconditional jump blocks, termination blocks, and ordinary blocks). The opcodes between the two key opcodes are added to the basic block as the basic block content.

[0095] Traverse the basic block sequence EFGblock of the execution flow graph obtained in steps 1-3 by block, and further traverse the instrList of each execution flow graph basic block. During the traversal process, define a Boolean variable start with an initial value of true. After initializing the first control flow graph basic block, set start to false. When traversing to the JUMPI opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblock is j The jumpType is set to 1 (conditional jump block).

[0096] When traversing to the JUMP opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j The jumpType is set to 2 (unconditional jump block).

[0097] When traversing to the termination-related opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j Set the jumpType to 4 (terminate block).

[0098] The jumpType of the remaining control flow graph basic blocks is set to 3 (normal block). When the JUMPDEST opcode is traversed, it indicates that the basic block has ended, and start is set to false.

[0099] When traversing to other types of opcodes, the opcode object is added to the instrList attribute of the current control flow graph basic block.

[0100] The pc value of the opcode object at the start and end of the basic block is assigned to the startBlockPC of the basic block in the control flow graph. j and endBlockPC j property.

[0101] And the generated control flow graph needs to be stored in the CFGBlockMap attribute of the execution flow graph basic block, CFGBlockMap: (blockStartPos s , cfgblock s ), the key of CFGBlockMap is the startBlockPC of the control flow graph basic block, and the value is the control flow graph basic block.

[0102] This step ends when all execution flow graph basic blocks have built corresponding control flow graphs.

[0103] The control flow graph construction algorithm is similar to the execution flow graph construction algorithm, but the key operation codes for division are different, so pseudo code is no longer given.

[0104] 2. Transaction execution phase, such as Figure 3 shown.

[0105] 2-1 Control Flow Graph Execution Stack Selection

[0106] Figure 6 The legend of the execution stack selection of the control flow graph is given in . First, initialize an execution stack list Stack = {stack1, ..., stack s ,…,stack s}, used to save the execution stack at the end of smart contract execution. The execution stack object has the structure stack: (stack, preSrtack.call_depth), with attribute values representing the call depths of the current and previous execution stacks, respectively. The call depth of the execution stack is assigned by the call depth of the first opcode object in the basic block of the control flow graph.

[0107] The initial execution stack is an empty stack stack1. Traverse the execution flow graph basic block sequence. If the pc value of the first opcode object of the execution flow graph basic block is 0, it means that the execution flow has reached a new called smart contract, so a new execution stack stack is generated. s As the execution environment of this basic block.

[0108] Continue traversing. If the first opcode object of the execution flow graph basic block is a call class or create class opcode, it means the previous call has ended. Return the execution stack where the previous call ended. s-1 , judge the stack s-1 The call_depth of the first opcode of the current execution flow graph basic block s Are they equal? If they are equal, use stack s-1 As the execution stack of the current basic block. If not equal, return stack s-2 As the execution stack of the currently called smart contract.

[0109] After selecting the execution stack, proceed to step 2-2 to execute the control flow graph. After execution, a judgment is made. If the pc value of the first opcode object of the execution flow graph basic block is 0 and the type of the last opcode object is not a termination type, the execution stack is added to the execution stack list Stack. This situation corresponds to the current new smart contract being called has not yet been executed.

[0110] If the first opcode object of the execution flow graph basic block is of the creation type and the last opcode object type is not of the termination type, the execution stack is added to the execution stack list Stack. This corresponds to the previously called smart contract not yet completed, so the execution stack must be retained. When the called contract fragment completes execution and returns to the calling contract, the execution stack is deleted and the execution result value is added to the previous execution stack.

[0111] 2-2 Control Flow Graph Execution

[0112] In this step, the control flow graph constructed by the execution flow graph basic blocks in steps 1-4 is executed, and the execution stack obtained in step 2-1 is used as the execution stack of the current control flow graph.

[0113] The execution order of the control flow graph is determined by the basic block type. The next basic block executed after a conditional jump block is determined by the conditionJumpPos key of that basic block. The next basic block executed is the basic block with the key conditionJumpPos in the execution flow graph's CFGBlockMap. Unconditional jump blocks and termination blocks execute in the same order as conditional jump blocks. Ordinary blocks execute the next control flow graph basic block in sequence.

[0114] Traverse the execution flow graph and execute the control flow graph constructed in steps 1-4 for each execution flow graph basic block. The main execution part is the instrList attribute in the control flow graph basic block. InstrList contains multiple opcode objects. According to the execution logic of the opcode itself, it is executed in the EVM. According to the operation of the opcode in the execution stack, opcode_log is generated. Opcode_log represents the execution status of the opcode in the execution stack. The expression of opcode_log is (pc: opcode→pc→value_pc), where pc is the opcode pc value, opcode represents the opcode itself, and value_pc represents the opcode operation value. Figure 7 Generate a comparison chart of the opcode object and opcode_log during the opcode_log generation process. Figure 8 This is a detailed diagram of opcode_log generation.

[0115] All opcode_logs are saved to the StackEvents property of the execution flow graph as the basis for vulnerability detection in the transaction execution analysis phase. The opcode_logs related to the JUMPI opcode and the JUMP opcode are used as conditionJumpExpression and unconditionJumpExpression respectively, and assigned to the corresponding properties in the basic block of the control flow graph.

[0116] The opcode contained in unconditionJumpExpression indicates that the opcode has a dependency on the JUMP / JUMPI opcode.

[0117] The pseudo code for execution stack selection and control flow graph execution is as follows, Algorithm 2:

[0118]

[0119]

[0120] 3. Transaction execution result analysis stage

[0121] 3-1 Get the call path

[0122] Based on the execution flow graph and control flow graph constructed in steps 1-3 and 1-4, the call path is obtained. The call path refers to the execution path of the basic block of the control flow graph that contains the CALL opcode. Some vulnerabilities in transactions are triggered by the CALL opcode, such as reentrancy vulnerabilities. If the global execution path is detected, some execution paths may not contain the CALL opcode. If the execution path does not contain the CALL opcode, it is unlikely to contain a reentrancy vulnerability. Executing these paths will result in a waste of computing resources. Therefore, directly detecting the call path for some vulnerabilities can greatly improve detection efficiency.

[0123] In the control flow graph constructed in step 1-4, the basic blocks of the control flow graph have the basic block type attribute. The basic block type determines the execution order between blocks (explained in 2-2). The control flow graph is traversed according to the execution order of the basic blocks. If the instrList attribute of the basic block in the execution path contains the CALL opcode, then the execution path is defined as a call path, and this call path is assigned to the allCallPath attribute of the corresponding execution flow graph basic block as the vulnerability detection path in 3-2.

[0124] 3.2 Transaction Vulnerability Detection

[0125] The transaction vulnerability detection part is to detect the StackEvents generated after the execution of the control flow graph in 2-2 and the call path obtained in 3-1. Then, by writing detection rules to detect the dependencies in the call path of the contract execution, the vulnerabilities are detected. The detection rules for vulnerabilities such as reentrancy vulnerabilities, unchecked low-level call vulnerabilities, Tx.origin vulnerabilities, self-destruction vulnerabilities, timestamp dependency vulnerabilities, and arithmetic overflow vulnerabilities are as follows:

[0126] 3-2-1 Reentrancy Vulnerability Detection

[0127] Reentrancy vulnerability detection focuses on the call path in step 3-1. The call path is the execution path associated with the CALL opcode, and the key opcode triggering the reentrancy vulnerability is also the CALL opcode. Before detecting reentrancy vulnerabilities, the transaction sequence is first checked for the presence of the CALL and SLOAD opcodes. If the transaction sequence does not contain these opcodes, reentrancy vulnerability detection is immediately terminated. Reentrancy vulnerability detection analyzes the dependencies between the CALL, SLOAD, and SSTORE opcodes. It traverses the call path of each basic block in the execution flow graph, first obtaining the PC value of the SLOAD opcode. It then traverses the StackEvents generated in step 2-2 and searches for the PC values of the CALL and SSTORE opcodes. If, within the same call path, the SSTORE opcode's PC value is greater than the CALL opcode's PC value, and the CALL opcode's PC value is greater than the SLOAD opcode's PC value, or if the SSTORE opcode's PC value is absent and the CALL opcode's PC value is greater than the SLOAD opcode's PC value, this indicates that the transaction sequence has been attacked by a reentrancy vulnerability.

[0128] 3-2-2 Unchecked Low-Level Call Vulnerability Detection

[0129] An unchecked low-level call vulnerability occurs when the return value is not checked after a call. In smart contracts, return value checks often use require or if statements, both of which are represented by ISZERO in the opcode. Therefore, we analyze the dependency between the ISZERO opcode and the CALL opcode. We traverse the StackEvents stored in each execution flow graph, find the opcode_log that begins with the CALL opcode, and find the CALL_pc value from the opcode_log. We traverse the next opcode_log. If the opcode_log begins with the ISZERO opcode and contains the CALL_pc value, then the return value of the CALL opcode has been checked by the ISZERO opcode, indicating that the vulnerability does not exist. Otherwise, the transaction contains the vulnerability attack.

[0130] 3-2-3Tx.origin vulnerability detection

[0131] This vulnerability is caused by the incorrect use of ORIGIN. This vulnerability detects the dependency between the ORIGIN opcode and the EQ opcode. It checks the stackEvents of the execution flow graph, first finds the opcode_log belonging to the ORIGIN opcode in the stackEvents, obtains the ORIGIN_pc value, and traverses the next opcode_log. If the opcode_log starts with EQ and contains the ORIGIN_pc value, then it indicates a dependency between the ORIGIN opcode y and the EQ opcode, indicating that the transaction is vulnerable to this vulnerability. Otherwise, the transaction does not contain this vulnerability.

[0132] 3-2-4 Self-destruction vulnerability detection

[0133] The self-destruct vulnerability checks the dependency between the SELFDESTRUCT opcode and the JUMPI opcode. If a smart contract is verified when using the self-destruct operation, it is considered a safe operation. The execution flow graph is traversed and the control flow graph contained in the execution flow graph is further traversed. If the conditionJumpExpression in the control flow graph contains the SELFDESTRUCT opcode, it means that the SELFDESTRUCT opcode was used after verification. Therefore, the transaction is judged to be free of this vulnerability attack. Otherwise, this vulnerability attack is present.

[0134] 3-2-5 Timestamp Dependency Vulnerability Detection

[0135] This vulnerability detects the dependency between the TIMESTAMP opcode and the JUMPI opcode. If the TIMESTAMP timestamp is used, it indicates a potential timestamp vulnerability in the transaction. The execution flow graph is traversed and the control flow graph contained within it is further traversed. If the conditionJumpExpression in the control flow graph contains the TIMESTAMP opcode, it indicates a dependency between the TIMESTAMP opcode and the JUMPI opcode. Therefore, the transaction is considered vulnerable to this vulnerability. Otherwise, it is not vulnerable to this vulnerability.

[0136] 3-2-6 Arithmetic Overflow Vulnerability Detection

[0137] This vulnerability detects whether arithmetic overflow occurs during transaction execution, primarily targeting the four arithmetic operations of addition, subtraction, multiplication, and division. The transaction sequence contains the execution parameters of the opcodes from previous transactions. Therefore, this vulnerability is detected during the execution of the control flow graph in step 2-2. As the opcodes execute arithmetic operations in the EVM, the operands and results are extracted. The vulnerability is then determined by verifying the relationship between the operands and results. For example, in addition and multiplication, if the result of an addition operation with two operands a and b is c, then an integer overflow has occurred if cb!=a. In multiplication, if the result of a multiplier a and b is only c, then if c / a!=b (both a and b are non-zero), then a multiplication overflow has occurred, and the transaction contains this vulnerability attack.

[0138] The above is only a preferred embodiment of the present invention. It should be pointed out that for ordinary technicians in this technical field, several improvements and modifications can be made without departing from the principles of the present invention. These improvements and modifications should also be regarded as the scope of protection of the present invention.

Claims

1. A vulnerability detection method for historical transactions of Ethereum smart contracts, characterized by It includes three stages: transaction sequence processing stage, transaction execution stage, and transaction execution result analysis stage. The specific implementation steps are as follows: (1) The smart contract transaction sequence file is used as the input of the transaction sequence preprocessing stage. This stage consists of two parts: I. According to the transaction sequence read from the contract transaction sequence file, the transaction operation code sequence is initialized to the operation code object sequence; II. According to the operation code object sequence in the first part, an execution flow graph is constructed, and a corresponding control flow graph is constructed for each basic block of the execution flow graph; (2) The execution flow graph and the corresponding control flow graph generated in this stage are used to reproduce the contract historical transactions in the transaction execution stage, and to obtain the call path in the transaction execution result analysis stage; in the transaction execution stage, according to the transaction sequence processing The execution flow graph and control flow graph constructed in the transaction processing phase are first selected for each basic block of the execution flow graph, and the corresponding execution stack is used as the execution environment to execute the control flow graph corresponding to the basic block of the execution flow graph in the EVM; the intermediate state of execution in the execution stack is retained during the execution of the control flow graph, and the intermediate state of execution is used for vulnerability analysis of the transaction in the transaction execution result analysis phase; (3) In the transaction execution result analysis phase, the call path between contracts in the transaction sequence is first obtained based on the execution flow graph and control flow graph generated in the transaction sequence processing phase; then, the potential vulnerabilities of the transaction are detected by combining the call path, the intermediate state of execution generated in the transaction execution phase, and the predefined vulnerability detection rules, and finally a transaction vulnerability detection report is output based on the detection results; The transaction sequence processing phase is specifically implemented as follows: 1-1. Get the transaction sequence; Read the transaction operation code sequence OC={oc1,…,oc i ,…,oc n }, indicating that the operation code sequence OC has n operation codes; among them, the operation code oc i Expressed as a triple: (pc i ;opcode i ;value i ), the three elements represent the pc value of the opcode, the opcode itself and the operating parameters of the opcode; during the reading process, the opcode oc i Initialized as an opcode object: [line i ,(pc i , opcode i ,value i , call_depth i , call_num i )], where line i Represents the operation code oc i Line number in the opcode sequence OC, call_depth i 、call_num i Represents the call depth and call count corresponding to the opcode, and all opcodes oc i After all are initialized as opcode objects, take the opcode object sequence as input; 1-2. Calculate the opcode call depth and call count; Traverse the opcode sequence OC obtained in step 1-1. The opcode subscript is defined as i during the traversal process. The initial call count is 0. When the pc value of the opcode object is 0 but the current traversal subscript i is not 0, the call count is increased by 1; this indicates that the current transaction execution flow has flowed to a new smart contract; and the corresponding call count is assigned to the call_num of the corresponding opcode object. i property; During the traversal process, whenever the pc value of the opcode object is 0 but the current traversal index i is not 0, the call depth is increased by 1; when the traversal reaches the opcode itself related to the call or the creation, a judgment is made. If the call_num of the current opcode object is the same as the call_num of the previous opcode object i When the attributes are equal and the previous opcode itself is not a termination type opcode; it means that the currently called smart contract has not yet completed execution, so call_depth i Otherwise, it means that the current smart contract execution has ended and returns to the previous level smart contract, then call_depth i Subtract 1; and assign the corresponding call depth to the call_depth of the corresponding opcode object i property; 1-3. Build the execution flow graph; The execution flow graph represents the call execution order between smart contracts in a transaction. The structure of the execution flow graph is EFGblock = {efgblock1, ..., efgblock s ,…,efgblock S }, the structure of the execution flow graph basic block is efgblock s :(startBlockPC s , endBlockPC s , instrList s , CFGBlockMap s , StackEvents s ,allCallPath s ); Traverse the opcode sequence OC obtained in step 1-1, define a Boolean variable start during the traversal process, with an initial value of true, and set start to false after initializing the first execution flow graph basic block; When encountering a call-related or termination-related opcode itself, if the current opcode object is the same as the previous opcode object -1 The call_num attribute of the previous opcode object is not equal to -1 When it is a termination type opcode, it means that the smart contract execution has ended and a new execution flow graph basic block needs to be generated. Set start to true and initialize a new execution flow graph basic block. After initializing a new execution flow graph basic block, set start to false. When traversing to other types of opcodes other than call-related or termination-related, add the opcode object to the instrList of the current execution flow graph basic block s In the properties, the pc value of the opcode object at the start and end positions of the execution flow graph basic block is assigned to the startBlockPC of the execution flow graph basic block s and endBlockPC s Attributes serve as the start and end locations of basic blocks in the execution flow graph; 1-4. Construction of control flow graph An execution flow graph basic block can construct a corresponding control flow graph, which is divided into four types of blocks according to the opcode: unconditional jump block, conditional jump block, termination block and ordinary block; The structure of the control flow graph is CFGblock = {cfgblock1, ..., cfgblock j ,…,cfgblock J }, the structure of the control flow graph basic block is cfgblock j :(startBlockPC j , endBlockPc j , instrList j , conditionJumpPos j , conditionJumpExpression j , unconditionJumpPos j , unconditionJumpExpression j ,jumpType j ,stack j ); Traverse the basic block sequence EFGblock of the execution flow graph obtained in steps 1-3, and then traverse the instrList of each execution flow graph basic block. During the traversal process, define a Boolean variable start with an initial value of true. After initializing the first control flow graph basic block, set start to false. When traversing to the JUMPI opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblock j Set jumpType to 1; When traversing to the JUMP opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j Set jumpType to 2; When traversing to the termination-related opcode, a new control flow graph basic block needs to be generated and start is set to true, and the control flow graph basic block cfgblocki j Set jumpType to 4; The jumpType of the remaining control flow graph basic blocks is set to 3; when the JUMPDEST opcode is traversed, it indicates that the basic block has ended, and start is set to false; When traversing to other types of opcodes, add the opcode object to the instrList attribute of the current control flow graph basic block; The pc value of the opcode object at the start and end of the basic block is assigned to the startBlockPC of the basic block of the control flow graph. j and endBlockPC j Attribute; and the generated control flow graph needs to be stored in the CFGBlockMap attribute of the execution flow graph basic block, CFGBlockMap: (blockStartPos s , cfgblock s ), the key of CFGBlockMap is the startBlockPC of the control flow graph basic block, and the value is the control flow graph basic block; until all execution flow graph basic blocks have built the corresponding control flow graph; The transaction execution phase is specifically implemented as follows: 2-1. Control flow graph execution stack selection; First, initialize an execution stack list Stack = {stack1, ..., stack s ,…,stack S }, used to save the execution stack at the end of smart contract execution; the structure of the execution stack object is stack:(stack, preSrtack.call_depth), and the attribute values are the call depths of the current execution stack and the previous execution stack respectively; the call depth of the execution stack is assigned by the call depth of the first opcode object in the basic block of the control flow graph; The initial execution stack is an empty stack stack1; traverse the execution flow graph basic block sequence. If the pc value of the first opcode object of the execution flow graph basic block is 0, it means that the execution flow has reached a new called smart contract, so a new execution stack stack is generated. s As the execution environment of the basic block; Continue traversing. If the first opcode object of the execution flow graph basic block is a call class or create class opcode, it means that the previous call has ended. Return the execution stack where the previous call ended. s-1 , judge the stack s-1 The call_depth of the first opcode of the current execution flow graph basic block s Are they equal? If they are equal, use stack s-1 As the execution stack of the current basic block; if not equal, return stack s-2 As the execution stack of the currently called smart contract; After selecting the execution stack, proceed to step 2-2 to execute the control flow graph. After execution, make a judgment. If the pc value of the first opcode object of the execution flow graph basic block is 0 and the type of the last opcode object is not a termination type, add the execution stack to the execution stack list Stack. This situation corresponds to the current new smart contract that has not yet been executed. If the first opcode object of the execution flow graph basic block is of the creation type and the last opcode object type is not of the termination type, the execution stack is added to the execution stack list Stack. This corresponds to the previously called smart contract not yet completed, so the execution stack needs to be retained; 2-2. Control flow graph execution; The execution order of the control flow graph is determined by the basic block type. The next executed basic block of a conditional jump block is determined by the conditionJumpPos of the basic block. The next executed basic block is the basic block with the key conditionJumpPos in the CFGBlockMap of the execution flow graph. The execution order of unconditional jump blocks and termination blocks is the same as that of conditional jump blocks. Ordinary blocks execute the next control flow graph basic block in sequence. Traverse the execution flow graph and execute the control flow graph constructed in steps 1-4 for each execution flow graph basic block; the main execution part is the instrList attribute in the control flow graph basic block. InstrList contains multiple opcode objects. According to the execution logic of the opcode itself, it is executed in the EVM. The opcode_log is generated according to the operation of the opcode on the execution stack. The opcode_log represents the execution status of the operation of the opcode in the execution stack; The expression of opcode_log is (pc:opcode→pc→value_pc), where pc is the opcode pc value, opcode represents the opcode itself, and value_pc represents the opcode operation value; All opcode_logs are saved to the StackEvents property of the execution flow graph as the basis for vulnerability detection in the transaction execution analysis phase. The opcode_logs related to the JUMPI opcode and the JUMP opcode are used as conditionJumpExpression and unconditionJumpExpression respectively, and assigned to the corresponding properties in the basic block of the control flow graph; conditionJumpExpression and The opcode contained in unconditionJumpExpression indicates that the opcode has a dependency relationship with the JUMP / JUMPI opcode; The specific implementation of the transaction result analysis phase is as follows: 3-1 Get the call path Obtain the call path based on the constructed execution flow graph and control flow graph. The call path refers to the execution path of the basic block of the control flow graph that contains the CALL opcode. Some vulnerabilities in transactions are triggered by the CALL opcode. Therefore, directly detecting the call path for some vulnerabilities can greatly improve detection efficiency. The basic blocks of the control flow graph have a basic block type attribute. The basic block type determines the execution order between blocks. The control flow graph is traversed according to the execution order of the basic blocks. If the instrList attribute of the basic block in the execution path contains the CALL opcode, then the execution path is defined as a call path and this call path is assigned to the allCallPath attribute of the corresponding basic block of the execution flow graph. 3-2 Transaction Vulnerability Detection The detection part of transaction vulnerability detection is the StackEvents generated after the control flow graph is executed and the call path obtained. Then, the dependency relationship in the call path of the contract execution is detected through the detection rules to detect vulnerabilities.

2. A method for detecting vulnerabilities in historical transactions of Ethereum smart contracts according to claim 1, characterized in that Reentrancy vulnerability detection is implemented through detection rules as follows: The detection of reentrancy vulnerabilities focuses on detecting the call path, which is the execution path related to the CALL opcode. The key opcode triggered by the reentrancy vulnerability is also the CALL opcode. Before detecting the reentrancy vulnerability, the transaction sequence is first checked to see whether it contains the CALL opcode and the SLOAD opcode. If the transaction sequence does not contain these two types of opcodes, the reentrancy vulnerability detection is directly exited. The reentrancy vulnerability detection analyzes the dependency relationship between the CALL opcode, the SLOAD opcode, and the SSTORE opcode, traverses the call path of each execution flow graph basic block, first obtains the pc value of the SLOAD opcode, traverses the StackEvents generated in step 2-2, and finds the pc values of the CALL opcode and the SSTORE opcode in it. If in the same call path, the pc value of the SSTORE opcode is greater than the pc value of the CALL opcode, and the pc value of the CALL opcode is greater than the pc value of the SLOAD opcode, or the pc value of the SSTORE opcode does not exist and the pc value of the CALL opcode is greater than the pc value of the SLOAD opcode, it indicates that this transaction sequence has been attacked by a reentrancy vulnerability.

3. A method for detecting vulnerabilities in historical transactions of Ethereum smart contracts according to claim 2, characterized in that The detection rules are used to detect unchecked low-level call vulnerabilities. The specific implementation is as follows: An unchecked low-level call vulnerability occurs when the return value is not checked after the call. In smart contracts, return value checks mostly use require or if statements, both of which are represented as ISZERO in the opcode. Therefore, the dependency between the ISZERO opcode and the CALL opcode is analyzed. The StackEvents saved in each execution flow graph are traversed to find the opcode_log that begins with the CALL opcode, and the CALL_pc value is found in the opcode_log. The next opcode_log is traversed. If the opcode_log begins with the ISZERO opcode and contains the CALL_pc value, then the return value of the CALL opcode has been checked by the ISZERO opcode, and this vulnerability does not exist. Otherwise, this transaction contains this vulnerability attack.

4. A method for detecting vulnerabilities in historical transactions of Ethereum smart contracts according to claim 3, characterized in that The Tx.origin vulnerability detection is implemented through detection rules as follows: This vulnerability is caused by the incorrect use of ORIGIN. This vulnerability detects the dependency between the ORIGIN opcode and the EQ opcode. It checks the stackEvents of the execution flow graph, first finds the opcode_log belonging to the ORIGIN opcode in the stackEvents, obtains the ORIGIN_pc value, and traverses the next opcode_log. If the opcode_log starts with EQ and contains the ORIGIN_pc value, then it indicates a dependency between the ORIGIN opcode y and the EQ opcode, indicating that the transaction is vulnerable to this vulnerability. Otherwise, the transaction is not vulnerable to this vulnerability.

5. The method for detecting vulnerabilities in historical transactions of an Ethereum smart contract according to claim 3, characterized in that The self-destruct vulnerability detection is implemented through detection rules as follows: The self-destruct vulnerability detects the dependency between the SELFDESTRUCT opcode and the JUMPI opcode. If the smart contract is verified when using the self-destruct operation, it is considered a safe operation. The execution flow graph is traversed and the control flow graph contained in the execution flow graph is further traversed. If the conditionJumpExpression in the control flow graph contains the SELFDESTRUCT opcode, it means that the SELFDESTRUCT opcode is used after verification. Therefore, it is judged that the transaction does not have this vulnerability attack, otherwise it does.

6. A method for detecting vulnerabilities in historical transactions of Ethereum smart contracts according to claim 3, characterized in that The timestamp dependency vulnerability detection is implemented as follows: This vulnerability detects the dependency between the TIMESTAMP opcode and the JUMPI opcode. If the timestamp TIMESTAMP is used, it indicates that there may be a potential timestamp vulnerability in the transaction. The execution flow graph is traversed and the control flow graph contained in the execution flow graph is further traversed. If the conditionJumpExpression in the control flow graph contains the TIMESTAMP opcode, it indicates a dependency between the TIMESTAMP opcode and the JUMPI opcode. Therefore, the transaction is judged to be vulnerable to this vulnerability. Otherwise, this vulnerability does not exist.

Citation Information

Patent Citations

  • Intelligent contract malicious transaction detection and analysis system and method based on data dynamic storage

    CN114491508A

  • Vulnerability detection method and device, computer equipment, storage medium and program product

    CN116861434A