Method for optimizing wasm byte code, execution method, computer device and storage medium

By optimizing the Webassembly bytecode and deploying and performing the optimized bytecode at the blockchain node, the problem of low execution efficiency of the WASM bytecode in the existing technology has been solved, and the efficient execution of smart contracts and the realization Resource optimization.

WO2025020397A1PCT designated stage expired Publication Date: 2025-01-30ANT BLOCKCHAIN TECHNOLOGY (SHANGHAI) CO LTD
View PDF 7 Cites 0 Cited by

Patent Information

Application Number
PCT/CN2023/134987
Authority / Receiving Office
WO · WO
Patent Type
Applications
Current Assignee / Owner
Priority Date
2023-07-24
Filing Date
2023-11-29
Publication Date
2025-01-30

AI Technical Summary

Technical Problem

The prior art has inefficiency problems when optimizing and executing WebAssembly (wasm) bytecode, especially during the deployment and execution of smart contracts.

Method used

By providing a method of optimizing WASM bytecode, including optimizing the WASM bytecode before optimization, generating optimized WASM bytecode, and deploying and executing the optimized WASM bytes on the blockchain node code. This method includes reading and analyzing WASM bytecode, creating linear memory, filling memory, and executing the code segment in the WASM module object.

Benefits of technology

By optimizing the WASM bytecode, the execution efficiency of smart contracts is significantly improved, resource occupation is reduced, and the performance of the blockchain network is improved.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN2023134987_30012025_PF_FP_ABST
    Figure CN2023134987_30012025_PF_FP_ABST
Patent Text Reader

Abstract

A method for deploying a smart contract, comprising: a blockchain node receiving a transaction for deploying a contract, the transaction comprising an unoptimized wasm byte code of the contract; optimizing the unoptimized wasm byte code to obtain an optimized wasm byte code; the blockchain node generating a smart contract account on a blockchain, and generating a codehash in the smart contract account according to the optimized wasm byte code; and the blockchain node storing the generated smart contract account on a blockchain ledger, the smart contract account comprising the codehash and the corresponding optimized wasm byte code.
Need to check novelty before this filing date? Find Prior Art

Description

A method for optimizing wasm bytecode and execution method, computer device and storage medium

[0001] This application claims priority to the Chinese patent application filed with the State Intellectual Property Office of China on July 24, 2023, with application number 202310914548.6 and application name “A method for optimizing wasm bytecode and execution method, computer device and storage medium”, the entire contents of which are incorporated by reference into this application. Technical Field

[0002] The embodiments of this specification belong to the field of compilation technology, and in particular, relate to a method for optimizing wasm bytecode and an execution method, a computer device, and a storage medium. Background Art

[0003] WebAssembly, an open standard developed by the W3C Community Group, is a secure, portable, low-level code format designed for efficient execution and compact representation. It delivers near-native performance and provides a compilation target for languages ​​such as C, C++, Java, and Go. The WASM virtual machine was originally designed to address the increasingly severe performance issues facing web applications. Due to its superior features, it is being adopted by a growing number of non-web projects, such as replacing the EVM, the blockchain smart contract execution engine.

[0004] Summary of the Invention

[0005] The object of the present invention is to provide a method for optimizing wasm bytecode, a method for executing the optimized wasm bytecode, a computer device and a storage medium, comprising:

[0006] This application provides a method for deploying a smart contract, including:

[0007] The blockchain node receives the transaction for deploying the contract, which includes the contract's pre-optimized wasm bytecode.

[0008] Optimizing the wasm bytecode before optimization to obtain optimized wasm bytecode;

[0009] The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode;

[0010] The blockchain node stores the generated smart contract account on the blockchain ledger, where the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

[0011] This application provides a method for executing the above-deployed smart contract, including:

[0012] The blockchain node receives a transaction that calls a contract. The transaction specifies the address of the contract account, the function being called, and the parameters passed in. The contract is an optimized wasm contract.

[0013] The blockchain node determines the codehash of the wasm contract through the contract account address, and loads the wasm bytecode corresponding to the codehash into the wasm virtual machine;

[0014] The wasm virtual machine reads and parses the optimized wasm bytecode to obtain a wasm module object;

[0015] The wasm virtual machine creates a linear memory and fills the linear memory according to the parsed wasm module object;

[0016] The wasm virtual machine executes the code of the code segment in the wasm module object based on the filled linear memory and the passed-in parameters.

[0017] A computer device comprising:

[0018] processor;

[0019] and a memory storing a program, wherein when the processor executes the program, the following operations are performed:

[0020] Receive the transaction that deploys the contract, which includes the contract's pre-optimized wasm bytecode;

[0021] Optimizing the wasm bytecode before optimization to obtain optimized wasm bytecode;

[0022] The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode;

[0023] The blockchain node stores the generated smart contract account on the blockchain ledger, where the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

[0024] A storage medium for storing a program, wherein the program performs the following operations when executed:

[0025] Receive a transaction that calls a contract, which specifies the address of the contract account, the function being called, and the parameters passed in. The contract is an optimized wasm contract.

[0026] Determine the codehash of the wasm contract through the contract account address, and load the wasm bytecode corresponding to the codehash into the wasm virtual machine;

[0027] Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0028] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0029] The code of the code segment in the wasm module object is executed based on the linear memory obtained by filling and the passed in parameters. BRIEF DESCRIPTION OF THE DRAWINGS

[0030] In order to more clearly illustrate the technical solutions of the embodiments of this specification, the following briefly introduces the drawings required for use in the description of the embodiments. Obviously, the drawings described below are only some embodiments recorded in this specification. For ordinary technicians in this field, other drawings can be obtained based on these drawings without paying any creative labor.

[0031] FIG1 is a schematic diagram of the compilation and execution process of a Java program in one embodiment;

[0032] FIG2 is a flowchart of a process in which a compiler can compile Java source code into a wasm file;

[0033] FIG3 is a schematic diagram of a bytecode structure and a virtual machine module in one embodiment;

[0034] FIG4 is a flow chart of a method in one embodiment;

[0035] FIG5 is a schematic diagram of a wasm file, linear memory, and managed memory in one embodiment;

[0036] FIG6 is a schematic diagram of a wasm file, linear memory, and managed memory in one embodiment;

[0037] FIG7 is a schematic diagram of a wasm file, linear memory, and managed memory in one embodiment;

[0038] FIG8 is a schematic diagram of a wasm file, linear memory, and managed memory in one embodiment;

[0039] FIG9 is a flow chart of a method in one embodiment;

[0040] FIG10 is a schematic diagram of creating and deploying a smart contract in a blockchain network according to one embodiment;

[0041] FIG11 is a schematic diagram of creating, deploying, and calling a smart contract in a blockchain network according to one embodiment;

[0042] FIG12 is a schematic diagram of creating, deploying, and calling a smart contract in a blockchain network according to one embodiment;

[0043] FIG13 is a schematic diagram of a bytecode structure and a virtual machine module in one embodiment;

[0044] FIG14 is a flow chart of a method according to an embodiment;

[0045] FIG15 is a flow chart of a method according to an embodiment;

[0046] FIG16 is a flow chart of a method in an embodiment. DETAILED DESCRIPTION

[0047] To help those skilled in the art better understand the technical solutions in this specification, the following will provide a clear and complete description of the technical solutions in the embodiments of this specification, in conjunction with the accompanying drawings. Obviously, the described embodiments are only part of the embodiments of this specification, not all of them. All other embodiments derived by those skilled in the art based on the embodiments in this specification without creative effort shall fall within the scope of protection of this specification.

[0048] High-level computer languages ​​are easier for people to write, read, communicate, and maintain, while machine language can be directly interpreted and executed by computers. A compiler takes an assembly or high-level computer language source program as input and translates it into an equivalent program in a target language (machine code). The source code is typically in a high-level language such as C or C++, while the target is the machine language object code, sometimes also called machine code. This machine code (or "microprocessor instructions") can then be executed by the CPU. This process is generally referred to as "compile and execute."

[0049] Compiled execution generally lacks cross-platform scalability. CPUs from different manufacturers, brands, and generations often support different instruction sets, such as the x86 and ARM instruction sets. Furthermore, CPUs from the same manufacturer and brand but different generations may not support exactly the same instruction sets. Therefore, the same program code written in the same high-level language may produce different machine code when converted by the compiler on different CPUs. Specifically, when converting high-level language program code to machine code, the compiler optimizes the specific CPU instruction set (such as vector instructions) to improve program execution speed. These optimizations are often specific to the specific CPU hardware. Consequently, the same machine code may run on an x86 platform but not on an ARM platform. Even on the same x86 platform, the instruction set continues to expand and enrich over time, resulting in different machine code running on different generations of x86 platforms. Furthermore, because machine code execution requires CPU scheduling by the operating system kernel, even on the same hardware, the machine code supported by different operating systems may differ.

[0050] Different from compiled execution, there is also an "interpreted execution" program running mode. For example, for high-level languages ​​​​such as Java and C#, the function of the compiler in this case is to compile the source code into bytecode (bytecode) of a common intermediate language.

[0051] For example, Java source code is compiled into standard bytecode by a Java compiler. This compiler does not target the instruction set of any actual hardware processor, but instead defines an abstract standard instruction set. This compiled standard bytecode generally cannot be run directly on a hardware CPU, so a virtual machine (JVM) was introduced. The JVM runs on a specific hardware processor to interpret and execute the compiled standard bytecode.

[0052] JVM, short for Java Virtual Machine, is a fictional computer that often simulates various computer functions on an actual computer. The JVM shields information related to specific hardware platforms and operating systems, allowing Java programs to run unmodified on a variety of platforms simply by generating standard bytecode that can run on the Java Virtual Machine.

[0053] A very important feature of the Java language is its platform independence. The use of the Java virtual machine is key to achieving this. A typical high-level language, if it is to run on different platforms, must at least be compiled into different target codes. However, with the introduction of the Java virtual machine, the Java language no longer requires recompilation when running on different platforms. The Java virtual machine shields platform-specific information from the Java language, allowing the Java compiler to run on multiple platforms without modification simply by generating target code (bytecode) that runs on the Java virtual machine. When executing bytecode, the Java virtual machine interprets the bytecode as platform-specific machine instructions. This is why Java can be "compile once, run anywhere." Thus, as long as the JVM can correctly execute .class files, it can run on different operating system platforms such as Linux, Windows, and macOS.

[0054] The JVM runs on a specific hardware processor and is responsible for interpreting and executing bytecode for that specific processor. It shields these underlying differences from the JVM and presents developers with standard development specifications. When executing bytecode, the JVM ultimately translates the bytecode into platform-specific machine instructions. Specifically, after receiving the input bytecode, the JVM interprets each instruction individually and translates it into machine code suitable for the current machine. This process is performed, for example, by an interpreter. This allows Java developers to avoid having to consider the specific hardware platform their code will run on. The JVM itself is developed by professional developers within the Java community to adapt the JVM to different processor architectures. Currently, there are only a limited number of mainstream processor architectures, such as X86, ARM, RISC-V, and MIPS. Once professional developers port the JVM to platforms supporting these specific hardware, Java programs can theoretically run on all machines. JVM porting is typically performed by professional personnel within the Java development community, significantly reducing the burden on Java application developers.

[0055] Figure 1 briefly illustrates the compilation and execution process of the Java program described above. Java source code developed by developers typically has a .java extension. The source file is compiled by a compiler, generating files with a .class extension. These .class files are bytecode. Bytecode consists of bytecode instructions, also known as opcodes, and operands. The JVM interprets these opcodes and operands to execute the program. When a .class file is run using the Java command, the bytecode in the .class file is actually loaded and executed by the Java Virtual Machine (JVM). The JVM is the core component of Java program execution, responsible for interpreting and executing Java bytecode. Loading and executing the bytecode in the .class file by the JVM is essentially like launching a JVM process in the operating system and requesting a certain amount of memory from the operating system. This memory is generally managed directly by the JVM and can include the method area, heap area, and stack area. The JVM interprets and executes the Java program line by line according to the bytecode instructions. During execution, the JVM performs garbage collection, memory allocation, and deallocation as needed to ensure the proper operation of the Java program. The JVM interprets the loaded bytecode to execute the program, which can be done in two specific ways. One is the common interpreted execution, which translates the opcode + operand into machine code and then passes it to the operating system for execution. The other execution method is JIT (Just In Time), which is real-time compilation. This method will compile the bytecode into machine code under certain conditions before executing it.

[0056] Interpreted execution brings cross-platform portability, but because the execution of bytecode goes through the JVM intermediate translation process, the execution efficiency is not as high as the above-mentioned compiled execution efficiency. This efficiency difference can sometimes even reach dozens of times.

[0057] As mentioned earlier, when a Java program is run, it compiles Java source code into Java bytecode, or .class files, which are then loaded and interpreted by the JVM. Therefore, the size of the .class files has a certain impact on the performance of Java programs. Smaller .class files generally mean faster loading and less memory usage. When the Java virtual machine loads a .class file, it parses it into internal data structures and then stores them in memory. Smaller .class files can be parsed and loaded more quickly, reducing loading time and memory usage. Furthermore, smaller .class files can be transferred and stored more quickly, helping to improve the overall performance of Java programs. When transferring .class files over a network or storing them on disk, smaller files require less bandwidth and storage space, allowing them to be downloaded or read more quickly, resulting in faster program startup and responsiveness.

[0058] To reduce the size of .class files and provide standardized APIs, the JVM integrates a large number of standard libraries that Java programs can rely on and use. For example, a developer's Java source code includes two files, Person.java and Main.java, with the header declaration of Main.java importing Person. In reality, Main and its dependent Person file will involve even more dependent classes at runtime, such as default parent and ancestor classes (a specific example is the indirectly dependent String.class). If the JVM didn't integrate a large number of dependent libraries, the compilation process would require compiling person, main, and their dependent classes simultaneously. This would result in a larger number of compiled .class files and a larger overall size. With the integration of a large number of standard libraries, the JVM needs to load fewer .class files from the external class loader during Java program execution, resulting in a smaller file size. However, dependent classes still need to be loaded internally, for example, from local files or the network. Another aspect of the JVM is its dynamic loading feature. As mentioned earlier, when the JVM executes Java bytecode .class files, such as Person.class and Main.class in the example above, it not only loads these two bytecode files but also many dependent class files. The dynamic loading feature means that the JVM does not load all classes into memory all at once, but instead loads classes on demand. Specifically, the JVM only loads a class when it needs it. The JVM's dynamic class loading feature allows Java programs to conditionally load different implementation classes at runtime, thereby reducing memory usage. Memory usage directly affects JVM execution efficiency.

[0059] Languages ​​like Java use virtual machines running on general-purpose hardware instruction sets like the x86, executing their own "assembly language" (e.g., Java Bytecode). In fact, web platforms also utilize virtual machine environments similar to Java and Python in browsers. These virtual machine environments execute JavaScript and other scripting languages, enabling interactive HTML pages and specific web page behaviors, such as embedded dynamic text. As business needs grow increasingly complex, front-end development logic also becomes increasingly complex, leading to increased code size and lengthy project development cycles. Besides the complexity of logic and code size, another factor is a flaw inherent in JavaScript: JavaScript lacks static variable types, which reduces efficiency. Specifically, JavaScript engines cache and optimize frequently executed functions within JavaScript code. For example, the JavaScript engine compiles this code into machine code, packages it, and sends it to the JIT compiler, which compiles it into machine code. The next time the function is executed, the compiled machine code is executed directly. However, because JavaScript uses dynamic variables, a variable might be an array one time and an object the next. In this way, the optimization done by the JIT Compiler last time becomes ineffective and needs to be optimized again next time.

[0060] In 2015, WebAssembly (also abbreviated as wasm) emerged. WebAssembly is an open standard developed by the W3C Community Group. It is a safe, portable, low-level code format designed for efficient execution and compact representation, capable of running with near-native performance. WebAssembly is compiled code that is small in size, fast to start, and completely syntactically separate from JavaScript, while also having a sandboxed execution environment. WebAssembly uses static typing, which improves execution efficiency. In addition, WebAssembly brings many programming languages ​​to the web. Moreover, WebAssembly further simplifies some execution processes, resulting in a significant improvement in execution efficiency.

[0061] WebAssembly is a new, portable, compact, fast-loading, and web-compatible format that can serve as a compilation target for languages ​​like C, C++, Rust, and Java. WebAssembly can be thought of as a universal x86 hardware instruction set for the web platform. As an intermediate language, it connects to upper layers like Java, Python, Rust, and C++, allowing these languages ​​to be compiled into a unified format for the web platform.

[0062] For example, source files developed in C++ generally have the extension .cpp. After being compiled by the compiler, cpp files can generate bytecode in the wasm format. Similarly, source files developed in Java generally have the extension .java. After being compiled by the compiler, java files can generate bytecode in the wasm format. Bytecode in the wasm format can be encapsulated in a wasc file. wasc is a file that combines bytecode and ABI (Application Binary Interface). The WebAssembly virtual machine (also called wasm virtual machine or wasm runtime environment, which is a virtual machine runtime environment for executing WASM bytecode) implemented according to the open standards of the W3C community is implemented by loading wasm bytecode at runtime and interpreting it.

[0063] For example, if you want to develop an application across multiple platforms, perhaps using Java for Linux, Objective-C for iOS, or C# for Windows, etc., with Wasm, you can simply choose any language, compile it into a Wasm file, and distribute it to various platforms. For example, as shown in Figure 2, a Java application can be compiled into Wasm bytecode, which can be run on various platforms equipped with a Wasm virtual machine.

[0064] The WASM virtual machine was originally designed to solve the increasingly severe performance problems of Web programs. Due to its superior features, it is being adopted by more and more non-Web projects, such as replacing the smart contract execution engine EVM in the blockchain.

[0065] Compilation generally includes single-file compilation and multi-file joint compilation.

[0066] In single-file compilation, all program code is contained in a single source file, which can be written in any programming language. During compilation, the compiler compiles this source file into an object file. The object file can be a binary file containing machine code and some metadata, or a file such as .class or .o. The linker then links this object file with other files (such as dependent static or dynamic libraries) to generate the final executable program or library file. The linker's main job here is to match and link symbols (such as functions and variables) that are not defined in the object file with their definitions in other files.

[0067] Multi-file joint compilation involves writing a program or library in multiple files and compiling these files into a single executable or library file. Generally, each source file implements a single function or a set of related functions. After a compiler compiles each source file into an object file, a linker is used to link multiple object files into a single executable or library file. The linker's primary function is to match and link undefined symbols (such as functions and variables) in an object file with definitions in other object or library files. In comparison, multi-file joint compilation offers improved maintainability and scalability. Using multiple files to write a program allows for clearer code organization, encapsulating different functions in separate files for easier modification and maintenance. Multi-file joint compilation also effectively avoids code duplication and dependency issues, while improving compilation efficiency and reusability.

[0068] In many high-level language program development processes, such as C++, code is written using multiple source files, compiled into multiple object files, and finally linked into a single executable or library file. During this process, only one source / object file contains a main() function, which serves as the program's entry point. Other object files contain various definitions, declarations, and implementations used by the main() function. This approach facilitates modular programming and avoids code duplication and dependency issues. Java programs are similar: a Java program has a single entry point but can contain multiple classes and packages. When the program starts, the JVM automatically executes the main() function in the class containing the entry point (specifically, the entry point function in Java is public static void main(String[]args), which is the starting point of a Java program). Methods in other classes can be called by the main() function in the Main class, thereby implementing various functions.

[0069] As mentioned above, Java programs can be compiled into wasm bytecode, which can run on various platforms integrated with a wasm virtual machine. When a Java program is compiled into WebAssembly bytecode, the compiler can automatically generate a start function and place it in the WebAssembly bytecode. This start function can serve as the entry point of the WebAssembly module and can be used to initialize the Java virtual machine and prepare the runtime environment for the Java program (for example, loading necessary class libraries). In addition, the compiler will insert the main function of the Java program into the start function of the compiled WebAssembly bytecode, so that the main function of the Java program can be started by calling the start function, thereby starting the execution of the entire Java program. The start function in the above wasm bytecode performs the initialization of the Java virtual machine and prepares the runtime environment for the Java program, for example, including initializing the Java heap, calling the static constructors of each Java class, initializing garbage collection, etc. Other high-level languages ​​are similar and can also be compiled into WebAssembly modules using the WebAssembly compiler, and the compiled WebAssembly module includes a start function.

[0070] In an example, the source code written in a high-level language (such as Go, TypeScript, Python, etc.) can be the following or similar code:

[0071] As shown in the source code above, line 1 declares and defines the global variable sum in this high-level language, assigning it a value of 0. Lines 3-6 are the main function, which executes the print function and returns the value of sum. Line 8 assigns sum a value of 1. Line 8 is a global scope operation.

[0072] The wasm bytecode (pseudocode) generated after compiling the above source code is as follows:

[0073] As shown in the wasm code above, line 2 assigns the variable at index position 0 to 0 (indicated by \0 in double quotes, corresponding to sum in the source code, because sum is at the front position in the source code, so the index is 0); lines 3-5 are the main function, which includes executing the print function and returning the value of the variable at index position 0 (that is, sum in the source code). The start function in lines 7-10 contains operations corresponding to the global scope in line 8 above, because such global scope operations are suitable for execution first in the start function. Line 9 indicates that the start function is marked as the startup function of the wasm bytecode, that is, the entry function. Line 3 is other function code, which can generally be the wasm bytecode corresponding to the main() / apply() function in the source code. After the entry function start is executed, the code starting from line 3 will continue to be executed.

[0074] As you can see, although there's no start function in the source code, it's automatically generated during the compilation process into a wasm module. The start function's responsibilities include initializing the Java virtual machine and preparing the Java program's runtime environment. Because the wasm specification stipulates that the start function is automatically executed after the module is loaded, the main entry point of a Java program is typically placed in the start function. This function thus acts as the program's entry point, automatically executing after the module is instantiated without requiring an explicit call.

[0075] When wasm bytecode is executed, the WebAssembly virtual machine loads and runs the wasm bytecode. Figure 3 shows the content and loading process of a wasm bytecode. The content of each segment (or section) is as follows:

[0076] Table 1. Description of each segment and content included in the wasm module

[0077] Among them, the memory segment (Memory Section) 5 can describe the basic situation of the linear memory segment used in a wasm module, such as the initial size of this memory segment, the maximum available size, etc. The data segment (Data Section) 11 describes some metadata filled in the linear memory, storing data that may be used by various modules, such as a string, some numeric values, etc. The data 0 in the above wasm code example (corresponding to sum=0 in the source code) is part of the Data Section. In addition, the Data Section can also include some source code, such as the underlying implementation of memory allocation such as the malloc function in the standard library used, and some constructor calls, garbage collection, and other initialization content.

[0078] Generally speaking, WebAssembly linear memory mainly stores two types of content:

[0079] Heap: used to store various data structures, such as objects, arrays, etc.

[0080] Stack: used to store local variables and other temporary information during function calls.

[0081] WebAssembly's linear memory is a contiguous memory space used to store runtime data. WebAssembly's linear memory consists of multiple pages, each 64KB in size. Linear memory is allocated and managed in units of pages. When starting a WebAssembly module, you must specify the initial and maximum sizes of the linear memory. If the program requires more memory, you can dynamically allocate more memory by expanding the linear memory to a larger number of pages. Every byte in linear memory is directly accessible to the WebAssembly virtual machine. WebAssembly provides various instructions to support read and write operations on linear memory, such as i32.load, i32.store, i64.load, and i64.store. These instructions can read or write memory data at a specified address, as well as perform operations such as offset and alignment. Linear memory is a core mechanism of WebAssembly, providing efficient and reliable memory management, making WebAssembly modules run more efficiently and stably.

[0082] After loading the wasm bytecode into the WebAssembly virtual machine, a linear memory can be allocated as the memory space for the WebAssembly bytecode. Specifically, a linear memory can be allocated based on the memory segment 5 in the wasm file described above, and the contents of data segment 11 can be filled into the linear memory. Furthermore, many other contents in the wasm file can be stored in a memory area managed by the host environment (such as a browser or other application) during loading, rather than in WebAssembly's linear memory. The specific storage location depends on the implementation details of the host environment, and this memory area is generally not directly accessible to WebAssembly code. This type of area is generally referred to as managed memory. The code section 10 in the wasm file described above contains the specific definition of each function, that is, the set of wasm instructions corresponding to the function body. The wasm instruction set of the start function can be stored in this code section 10. Furthermore, the main() / apply() portion of the source code can also be stored in this code section 10.

[0083] In the above example, line 2 (data 0 "\0") in the wasm bytecode belongs to the data segment; the parts in brackets starting with func on lines 3 and 7 belong to the code segment.

[0084] A specific example of the above content can be shown in Figure 3. In addition, each time the wasm module is loaded into the virtual machine and executed, the content of the start function will be repeatedly executed before the rest of the code is executed. Specifically, after the wasm bytecode is loaded into the WebAssembly virtual machine, a linear memory can be allocated as the memory space used by the WebAssembly bytecode based on the content of memory segment 5 in the managed memory, and the content of data segment 11 can be filled into the linear memory. As shown in the wasm code example above, the position with index 0 in line 2 is assigned the value 0, which is located in data segment 11. Then, the WebAssembly virtual machine executes the code in code segment 10 in the managed memory, which is mainly the part in the brackets starting with func in lines 3 and 7. In this example, the two functions main and start are included. Among them, as mentioned above, the start function is equivalent to the entry point of the code, so the content of the start function is executed first, and then the other code (here, the code of the main function) is executed. During the execution of the start function, the data in the linear memory may be modified. For example, line 8 in the wasm bytecode above (corresponding to line 8 "sum=1;" in the source code) changes the variable at the same index position 0 in the data segment to 1.

[0085] The above example is relatively simple. In practice, there are likely to be more complex situations. For the sake of illustration and simplicity, the above source code and wasm bytecode are modified as follows:

[0086] As shown in the source code above, line 1 declares and defines the global variable sum in this high-level language and assigns it a value of 0. Lines 3-6 are the main function, which executes the print function and returns the value of sum. Lines 7-10 define a Fibonacci function fib(n) that calculates the nth term of the Fibonacci series based on the input parameter n. Line 11 assigns sum to the value of fib(5). Similarly, lines 7-11 are operations in the global scope.

[0087] The wasm bytecode (pseudocode) generated after compiling the above source code is as follows:

[0088] As shown in the wasm code above, line 2 also assigns the variable at index position 0 to 0, which is located in the data segment. Lines 3-5 are the main function, which includes executing the print function and returning the value of the variable at index position 0 (i.e., sum in the source code). The ellipsis in line 6 indicates the bytecode corresponding to the Fibonacci function in lines 7-10 of the source code. The start function in lines 7-10, which contains the result of assigning the global variable fib(5), corresponds to the global scope operation in line 11 above. This type of global scope operation is suitable for execution first in the start function. Line 9 indicates that the start function is marked as the startup function of the wasm bytecode, that is, the entry function.

[0089] In this example, the calculation of the Fibonacci function becomes relatively complex. Repeating the code in the start function each time the wasm bytecode is loaded and run will incur significant time and performance overhead. This is especially true in many practical situations where the start function contains more complex code, such as the aforementioned code involving the underlying implementation of the standard library, some constructor calls, and initialization of garbage collection.

[0090] The following describes how to provide optimized wasm bytecode in one embodiment with reference to FIG4 .

[0091] S410: Read and parse the wasm bytecode to obtain a wasm module object.

[0092] The wasm virtual machine can be used to load the wasm bytecode to be optimized. The wasm bytecode can specifically be binary data of the wasm bytecode, which can be obtained by compiling the source code of the high-level language by the WebAssembly compiler. Furthermore, the loaded wasm bytecode can be parsed using the wasm virtual machine, and the parsing mainly includes a decoding process. The wasm bytecode file is generally an encoded binary file. Through decoding, the various Section IDs in the wasm module (i.e., the IDs in Table 1 above) can be obtained according to the wasm standard, and then parsed to obtain the detailed content in the Section corresponding to each ID. In this way, by parsing the wasm bytecode, a wasm module object can be obtained, which can include the start function code in the memory segment, data segment, and code segment (only those that are closely related to this embodiment are listed here, and the whole is actually as shown in Table 1 above, and no further details are given).

[0093] In a specific implementation, such as the code example above using the Fibonacci function, the parsed wasm module object is as follows:

[0094] Table 2. Wasm modules in a specific example

[0095] The main problem here is that in data segment 11, the value of the first 4 bytes is 0 (since sum is the first variable defined and the int type occupies 4 bytes, the first 4 bytes are used here).

[0096] The result of loading the wasm bytecode is that the decoded wasm bytecode binary file is saved in the managed memory of the wasm virtual machine, as shown in Figure 5.

[0097] S420: Create a linear memory according to the parsed wasm module object and fill the linear memory.

[0098] During execution, a wasm instance is first created, and linear memory is created based on the memory segments in the wasm module object parsed in S410. As mentioned above, memory segment 5 can describe the basic information of the linear memory segment used in a wasm module, such as the initial size of this memory segment and the maximum available size.

[0099] This process can be understood by combining Figures 3 and 5. Data segment 11 in the managed memory comes from data segment 11 in the wasm file. Of course, the contents of the managed memory as a whole can be a copy of the binary file in the wasm bytecode.

[0100] After creating a linear memory segment in the wasm virtual machine based on the memory segment in managed memory, the contents of data segment 11 in managed memory can be filled into this linear memory. This results in the linear memory containing the value 0 from bytes 0 to 3 in the example above. This value is the value of sum in the code example above. Furthermore, linear memory can also contain other constants and variables, depending on how they are defined in the actual code.

[0101] S430: Execute the start function in the wasm module object, and modify the linear memory according to the execution result of the start function.

[0102] After creating a wasm instance, it can be executed. The execution process includes executing the start function in code segment 10 copied to managed memory. As mentioned earlier, each time a wasm module is loaded into the virtual machine and executed, the start function serves as the entry point for the code. Therefore, the contents of the start function are executed first, followed by the rest of the code.

[0103] It's important to note that loading and executing an instance are two separate processes. A single load can be followed by multiple executions, essentially launching multiple instances. Each instance launch creates its corresponding linear memory, populates the linear memory with the data segments in managed memory, and locates and executes the entry point start function.

[0104] In the example of the above code, the process of executing the start function specifically includes calling the fib() function and setting the input parameter to 5. The result of executing fib(5) is 5 (the first 5 items of the Fibonacci sequence starting from 1 are 1-1-2-3-5, that is, the 5th item is 5). Then, i32.store 0(call fib 5)) in the above wasm bytecode is executed, which changes the value of sum in the source code to 5. The modified sum = fib(5) is more complicated than the previous modification of sum = 1, because the call and execution of the fib(5) function involves 5 iterations, which requires additional computational overhead and time overhead. As shown in Figure 6, during the execution of an instance of the above wasm code, after executing the start function once, the result is that the value of bytes 0 to 3 in the linear memory is changed to 5 (the execution result of calling the fib(5) function is 5).

[0105] S440: Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object.

[0106] As described above, since the start function is executed from the data segment 11 of the managed memory each time the instance is started, and the result of each execution of the start function is fixed and the same, the data in the modified linear memory can be used to replace the corresponding data segment in the wasm module object. Specifically, if the operation permission of the managed memory can be obtained, the data in the modified linear memory can be used to replace the corresponding data segment in the wasm module object; if the operation permission of the managed memory cannot be obtained, the wasm module object parsed in S410 can be saved to a memory area with operation permission, and then the data in the modified linear memory can be used to replace the corresponding data segment in the wasm module object in the memory area with operation permission.

[0107] The former can be shown in FIG7 , that is, when the managed memory operation permission is obtained, the data in the modified linear memory can be used to replace the corresponding data segment in the wasm module object stored in the managed memory. The overall structure of the latter is similar to that in FIG7 , except that it is not the managed memory without operation permission but other memory with operation permission. Of course, regardless of whether the operation permission is obtained, the wasm module object parsed in S410 can also be stored in a memory other than the managed memory.

[0108] In the modified example above containing the Fibonacci function, since the result 5 after executing the Fibonacci function in the start function is the same as the result 0 before execution, both are int types and occupy 4 bytes, and the other constants and variables in linear memory remain consistent with those in the data segment. Therefore, in one implementation, the portion of linear memory that changes after the start function is executed can be replaced with the corresponding portion in the data segment of the wasm module object. In this example, the values ​​of bytes 0 to 3 in linear memory are replaced from 0 to the result 5 after the start function is executed, without using other constants and variables in linear memory to replace the other constants and variables in the data segment, thus saving copying overhead.

[0109] Of course, it's possible that the result of executing the function in the start function is longer than the corresponding portion of linear memory before execution. For example, a variable-length string type might initially occupy 2 bytes, but after executing the start function, it would occupy 5 bytes. In this case, a better approach is to replace the corresponding data segment in the wasm module object with the entire data in the modified linear memory.

[0110] In addition, the result after executing the function in the start function may be longer than the corresponding part in the linear memory before execution. For example, it is a variable-length string type. The initial value occupies 5 bytes, and after executing the start function, it occupies 2 bytes. In this case, the best approach is to use the entire data in the modified linear memory to replace the corresponding data segment in the wasm module object. A 3-byte hole is generated in the middle, which can be used by other code in the subsequent code segment. In addition, the data in the modified linear memory can be removed from the hole area and then replaced with the corresponding data segment in the wasm module object, thereby avoiding the problem of low addressing efficiency caused by the subsequent use of part of the empty memory.

[0111] S450: Encode the wasm module object after replacing the data segment and save it as wasm bytecode.

[0112] As previously mentioned, wasm bytecode files are typically encoded. Parsing wasm bytecode includes decoding. After the data segment is replaced in S440, the wasm module object in memory can be further encoded to obtain wasm bytecode, which can then be stored outside of memory, such as on disk, or transmitted over a network. The resulting wasm bytecode is then optimized.

[0113] In a computer device, there may be a virtual logic unit that executes the optimized wasm bytecode method corresponding to Figure 4 above, which can be called an optimizer. To distinguish it from subsequent optimizers, it is set here as optimizer 1.

[0114] Subsequently, when the optimized wasm bytecode is loaded, it can be directly parsed to obtain a wasm module object in memory. Specifically, as previously described, the decoded, optimized wasm module object is stored in the managed memory of the wasm virtual machine, as shown in Figure 7. Furthermore, linear memory can be created and populated based on the parsed wasm module object. Furthermore, as previously described, since the contents of the current data segment are the result of loading the linear memory and executing the start function each time the instance is started before optimization, and the result is fixed and identical each time, it is unnecessary to execute the start function in managed memory. Thus, the start function can be further removed from the optimized wasm bytecode by deleting the start function's start marker (start$start), as shown in Form 1 below; or the entire start function content can be removed (this depends on whether other code in the start function is used), as shown in Form 2 below. Both of these approaches ensure that after launching the wasm instance, the code in the start function will not be executed, but instead the code corresponding to the main() / apply() function will be executed directly.

[0115] Specifically, after S430 and before S450, the start function in the wasm module object may be removed, and then the wasm module after the data segment is replaced and the start function is removed may be encoded and saved to obtain the wasm bytecode.

[0116] In this way, the wasm bytecode (pseudocode) generated after compiling the above source code includes two forms:

[0117] Remove the start function form 1

[0118] Remove the start function form 2

[0119] Correspondingly, as shown in FIG8 , the start function in the managed memory can be removed, specifically in the two forms above.

[0120] The following describes an embodiment of a method for executing the optimized wasm bytecode of the present application, as shown in FIG9 , including:

[0121] S910: Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0122] S920: Create a linear memory according to the parsed wasm module object and fill the linear memory;

[0123] S930: Execute the code of the code segment in the wasm module object.

[0124] Among them, if the code segment in the wasm module object does not contain the start function, the start function will not be executed; if the code segment in the wasm module object still contains the start function, that is, the optimized wasm bytecode does not remove the start function, but cancels the code marked as the start function, the start function is skipped and the code segment in the wasm module object is executed directly.

[0125] In this way, in the subsequent process of loading and executing the optimized wasm bytecode, the overhead caused by repeatedly executing the start function is eliminated, thereby improving the program's running performance.

[0126] The following describes an embodiment of a computer device of the present application, including:

[0127] processor;

[0128] and a memory storing a program, wherein when the processor executes the program, the following operations are performed:

[0129] Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0130] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0131] Executes the code in the code section of the wasm module object.

[0132] The following describes an embodiment of a storage medium of the present application, which is used to store a program, wherein the program performs the following operations when executed:

[0133] Read and parse the wasm bytecode to get the wasm module object;

[0134] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0135] Execute the start function in the wasm module object and modify the linear memory according to the execution result of the start function;

[0136] Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object;

[0137] Encode the wasm module after replacing the data segment and save it as wasm bytecode.

[0138] The wasm bytecode obtained by the above-mentioned wasm bytecode optimization method may have a larger overall size. A major reason for this may be that the linear memory modified in step S420 is larger, so the corresponding data segment in the wasm module object replaced after step S440 is also larger, resulting in a larger wasm bytecode after encoding.

[0139] A major reason for the large linear memory size may be that the start function initializes variables, generating a large amount of initialized data. This initialization includes assigning initial values ​​to global variables, calling constructors, and initializing Java's garbage collection function.

[0140] The result of executing the start function may contain a large number of repeated values. For example, it may contain a large number of repeated int values ​​of 0, which means that the length occupied in memory is 4 bytes and the value is 0. Another example may contain a large number of repeated int values ​​of 1, 2, and so on. Of course, in addition to int types, it may also contain long long types (8 bytes), single-precision floating-point types (4 bytes), double-precision floating-point types (8 bytes), and so on.

[0141] For the above data, it may be repeated continuously in linear memory.

[0142] In addition, it can also include a large number of repeated values ​​of the same structured type. Structured types include structure types, union types, enumeration types, etc. This type of data may also be repeated continuously in linear memory.

[0143] This application proposes a method for optimizing wasm bytecode, as shown in Figure 14, including:

[0144] S141: Read and parse the wasm bytecode to obtain the wasm module object.

[0145] S143: Create linear memory according to the parsed wasm module object and fill the linear memory.

[0146] S145: Execute the start function in the wasm module object, compress the execution result data of the start function, and use the compressed execution result to modify the linear memory.

[0147] S147: Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object.

[0148] S149: Encode the wasm module after replacing the data segment and save it as wasm bytecode.

[0149] In the above S145, the compression is mainly to compress the data generated by the execution result of the start function in the memory. Generally speaking, compressing the data in the memory mainly includes the following means:

[0150] Coding compression: This is the process of converting data into a shorter binary code. The most common coding compression methods are Huffman coding and arithmetic coding.

[0151] Dictionary compression: This technique breaks data into unique segments and assigns each segment an identifier from a dictionary. Data is then stored and transmitted using only these identifiers. LZ77 and LZ78 are examples of dictionary compression algorithms.

[0152] Run-length encoding: This is a compression method for repetitive data. It replaces repeated elements with a single element plus the number of repetitions. This is very effective for situations with large amounts of repetitive data.

[0153] Transform compression: This method reduces the complexity of data by performing mathematical transformations. For example, the discrete cosine transform (DCT) is widely used in image compression.

[0154] Forecast Compression: This method uses historical data to predict future data and then stores only the prediction errors. This method is particularly suitable for time series data.

[0155] These are the main data compression methods that can be used in different situations. Different methods are suitable for different types and properties of data, and the appropriate compression method needs to be selected according to the specific situation.

[0156] For example, if the result of executing the start function includes a large number of repeated zeros, especially a large number of consecutive repeated zeros, run-length encoding (RLE) can be used. Run-length encoding is a very simple and very effective compression method for data with consecutive repeating values. It replaces consecutive repeating values ​​with two numbers, the first number represents the value, and the second number represents the number of consecutive occurrences of the value. For example, if there are 100 consecutive zeros in a section of memory, then this section of data can be compressed to (0,100). This method greatly reduces storage and transmission requirements. Of course, it can also compress a large number of other consecutive and repeated values, such as the aforementioned int type 1, 2, etc.

[0157] Similarly, a three-segment structure can be used to represent the data. For example, a string of data in memory is:

[0158] 3333,3333,0000,3333,0000,0000,0000,0000,0000,2222,

[0159] For the data in the above memory string, for example, the starting position is 0, the position and value can be represented by a table as follows:

[0160] In the table above, the first row indicates the position and the second row indicates the value.

[0161] Using a three-segment structure (offset, length, value), offset can indicate the starting position, length can indicate the length, and value can indicate the value. For the above string of data (for example, int type), then:

[0162] The 16 consecutive bits from bit 0 to bit 15 can be expressed as (0,16,3333333300003333);

[0163] The 20 consecutive bits from the 16th to the 35th can be expressed as (16, 20, 0);

[0164] The 4 consecutive bits from the 36th to the 39th can be expressed as (36, 4, 2222);

[0165] Then, the above whole can be expressed as (0, 16, 33333333300003333), (16, 20, 0), (36, 4, 2222).

[0166] In particular, for the repeated 0s, the three segments at these positions can be omitted to represent the above whole number (0, 16, 3333333300003333), (36, 4, 2222). The omitted 16th to 35th bits can represent the default value of 0.

[0167] By using the above scheme to optimize data segments in a WASM bytecode file containing a large number of zero values ​​using a number of consecutive zeros as delimiters, the size of the WASM bytecode file can be reduced while maintaining the same functionality. Of course, other compression schemes can also reduce the size of the WASM bytecode file while maintaining the same functionality, which will not be discussed in detail here.

[0168] Similarly, before encoding, the start function in the wasm module object may be removed. The removal of the start function in the wasm module object includes: deleting the start mark of the start function, or removing the entire content of the start function.

[0169] In the computer device, there may be a virtual logic unit that executes the optimized wasm bytecode method corresponding to Figure 14, which can be called an optimizer. To distinguish it from the aforementioned optimizer, it is set here as optimizer 2.

[0170] The execution process of the optimized and compressed wasm bytecode is shown in Figure 9, including:

[0171] S910: Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0172] S920: Create a linear memory according to the parsed wasm module object and fill the linear memory;

[0173] S930: Execute the code of the code segment in the wasm module object.

[0174] In S910, for the bytecode compressed by the process of Figure 14, the process includes: reading and parsing the optimized wasm bytecode, and recovering the compressed data contained therein by decompression to obtain a wasm module object.

[0175] For example, the data segments represented as (0, 16, 3333333300003333), (16, 20, 0), (36, 4, 2222) are restored as follows:

[0176] 3333,3333,0000,3333,0000,0000,0000,0000,0000,2222,

[0177] Alternatively, the data segment represented as (0, 16, 3333333300003333), (36, 4, 2222) can be restored as follows:

[0178] 3333,3333,0000,3333,0000,0000,0000,0000,0000,2222,

[0179] The above solution can reduce the size of large wasm files generated by large linear memory after compression. This reduces the copying time of the data segments in the wasm bytecode during startup of the wasm virtual machine, that is, reduces the time overhead of copying the data segments to linear memory.

[0180] The following describes a computer device of the present application, including:

[0181] processor;

[0182] and a memory storing a program, wherein when the processor executes the program, the following operations are performed:

[0183] Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0184] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0185] Executes the code in the code section of the wasm module object.

[0186] The following describes a storage medium of the present application, which is used to store a program, wherein the program performs the following operations when executed:

[0187] Read and parse the wasm bytecode to get the wasm module object;

[0188] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0189] Execute the start function in the wasm module object, compress the execution result data of the start function, and modify the linear memory using the compressed execution result;

[0190] Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object;

[0191] Encode the wasm module after replacing the data segment and save it as wasm bytecode.

[0192] As mentioned earlier, the WASM virtual machine was originally designed to solve the increasingly severe performance problems of Web programs. Due to its superior features, it is being adopted by more and more non-Web projects, such as replacing the blockchain smart contract execution engine EVM.

[0193] The Blockchain 1.0 era generally refers to the period between 2009 and 2014, when blockchain applications, exemplified by Bitcoin, primarily focused on decentralizing currency and payment methods. Starting in 2014, developers increasingly focused on addressing Bitcoin's technical and scalability shortcomings. At the end of 2013, Vitalik Buterin published the Ethereum white paper, "Ethereum: A Next-Generation Smart Contract and Decentralized Application Platform," which introduced smart contracts to the blockchain and opened up blockchain applications beyond currency, ushering in the Blockchain 2.0 era.

[0194] A smart contract is a self-executing computer contract based on predefined triggering rules. It can also be considered a digital version of a traditional contract. The concept of smart contracts was first proposed by Nick Szabo, a multidisciplinary legal scholar and cryptography researcher, in 1994. This technology was previously not adopted in industry due to a lack of programmable digital systems and related technologies. The emergence of blockchain technology and Ethereum provided a reliable execution environment. Because blockchain technology utilizes a block-chain ledger, data generated cannot be tampered with or deleted, and the entire ledger is continuously updated, ensuring the traceability of historical data. Furthermore, its decentralized operation mechanism avoids the influence of centralized factors. Smart contracts based on blockchain technology not only leverage the cost and efficiency advantages of smart contracts but also prevent malicious interference with the normal execution of contracts. By digitally storing smart contracts on the blockchain, the characteristics of blockchain technology ensure that the entire storage, access, and execution process is transparent, traceable, and tamper-proof.

[0195] A smart contract is essentially a computer-executable program. Like widely used computer programs, smart contracts can be written in high-level languages. For example, Ethereum and some consortium blockchains based on Ethereum typically natively offer smart contracts written in high-level languages ​​such as Solidity, Serpent, and LLL. These smart contracts can include complex logic to implement various business functions. At the core of Ethereum, a programmable blockchain, is the Ethereum Virtual Machine (EVM), which runs on every Ethereum node. The EVM is a Turing-complete virtual machine, meaning it can implement complex logic. Users publishing and calling smart contracts on Ethereum can run on the EVM. In reality, the virtual machine directly runs virtual machine code (bytecode). Smart contracts deployed on the blockchain can be in bytecode format.

[0196] Furthermore, as a decentralized, distributed system, blockchains must maintain distributed consistency. Specifically, each node in a distributed system has a built-in state machine. Each state machine must start from the same initial state and execute the same instructions in the same order, ensuring that each state change is consistent, ultimately achieving a consistent state. However, it's difficult for all nodes participating in the same blockchain network to have identical hardware configurations and software environments. Therefore, Ethereum, a representative of Blockchain 2.0, uses the Ethereum Virtual Machine (EVM), a virtual machine similar to the JVM, to ensure that the execution process and results of smart contracts are consistent across all nodes. The EVM shields differences in hardware configurations and software environments across nodes. Furthermore, this sandbox-like environment ensures that smart contract execution does not impact the host blockchain platform code, other programs, or the operating system. This allows developers to develop a set of smart contract code, compile it locally, and upload the resulting bytecode to the blockchain. Executing the same bytecode on each node using the same EVM in the same initial state yields the same final and intermediate results, shielding against differences in underlying hardware and environments.

[0197] For example, as shown in Figure 10, after Bob sends a transaction containing information to create a smart contract to the Ethereum network, the EVM on Node 1 executes the transaction and generates a corresponding contract instance. The transaction's data field can contain the contract's bytecode, and the transaction's to field can be an empty address. After the nodes reach consensus through the consensus mechanism, the smart contract is successfully created on the blockchain. "0x6f8ae93..." in Figure 10 represents the address of the successfully created smart contract, which users can subsequently call. After the contract is created, a contract account corresponding to the contract address "0x6f8ae93..." appears on the blockchain. The contract code and account storage can be stored in this contract account. The behavior of the smart contract is controlled by the contract code, while the smart contract's account storage stores the contract's state. In other words, the smart contract creates a virtual account on the blockchain that contains the contract code and account storage.

[0198] As mentioned above, the data field of a transaction that creates a smart contract may contain the bytecode for that smart contract. Bytecode consists of a series of bytes, each representing an operation. For reasons of development efficiency and readability, developers can choose to write smart contract code in a high-level language rather than directly writing bytecode. Smart contract code written in a high-level language is compiled by a compiler to generate bytecode. This bytecode can then be packaged into the initiated transaction and deployed to the blockchain through the consensus and execution processes described above, as shown in Figure 11.

[0199] As shown in Figures 11 and 12, still using Ethereum as an example, after Bob sends a transaction containing information to call a smart contract to the Ethereum network, the EVM on Node 1 executes the transaction and generates a corresponding contract instance. In Figure 12, the from field of the transaction is the address of the account invoking the smart contract, the "0x6f8ae93..." in the to field represents the address of the smart contract being called, the value field is the Ethereum value, and the data field of the transaction stores the method and parameters used to call the smart contract. After calling a smart contract, the balance value may change. Later, a client can view the current balance value through a blockchain node. Smart contracts can be independently executed on each node in the blockchain network in a prescribed manner. All execution records and data are stored on the blockchain. Therefore, once such a transaction is completed, the blockchain stores an immutable and unlosable transaction record.

[0200] As mentioned above, a transaction creating a smart contract is sent to the blockchain. After consensus, each blockchain node can execute this transaction. Specifically, the EVM virtual machine (EVM) of the blockchain node executes this transaction. A contract account corresponding to the smart contract appears on the blockchain (including, for example, the account's identity, the contract's hash value, and the contract's storage root, StorageRoot). This account has a specific address. The contract code and account storage are stored in the contract account's storage, as shown in Figure 13. The smart contract's behavior is controlled by the contract code, while the smart contract's account storage stores the contract's state. In other words, the smart contract creates a virtual account on the blockchain containing the contract code and storage. Contract deployment or contract update transactions generate or modify the Codehash value. Subsequently, blockchain nodes can receive transaction requests to invoke the deployed smart contract. This transaction request may include the address of the invoked contract, the function within the invoked contract, and the input parameters. Generally, after consensus is reached on this transaction request, each blockchain node can independently execute the designated smart contract.

[0201] The left side of Figure 13 shows an example of a smart contract written in Solidity. This smart contract is compiled using a compiler to generate bytecode. The solc command-line compiler in the figure represents Solidity. Ethereum smart contracts written in Solidity can be compiled using the solc command-line tool with parameters to generate bytecode that can be run on the EVM. After the contract deployment process described in Figures 10 and 11, the smart contract is successfully created on the blockchain. After the contract is deployed, a contract account corresponding to the smart contract is generated on the blockchain. This contract account includes, for example, the account's identity, the contract's hash value (Codehash), the contract's storage root (StorageRoot), and a specific address. The contract code and account storage can be stored in the contract account's storage. The codehash is typically the hash of the contract's bytecode. After the contract is deployed, the codehash is the hash of the contract's bytecode. When the contract is updated, the hash of the contract's bytecode typically changes, and the codehash is also typically updated.

[0202] The execution of a contract can be specifically illustrated in Figure 13. For example, a transaction calling a contract is sent to the blockchain network. After consensus is reached, each node can execute the transaction. The transaction's "to" field indicates the address of the called contract. Any node can use the contract's address to locate the contract account's storage, then read the codehash from the contract account's storage and, based on the codehash, find the corresponding contract bytecode. The node can load the contract's bytecode from storage into the virtual machine. The interpreter then interprets and executes the contract. For example, this involves parsing the called contract's bytecode (e.g., Push, Add, SGET, SSTORE, Pop), obtaining the opcode and function. These opcodes are then stored in memory allocated by the virtual machine (alloc, the corresponding memory release operation after program execution, as shown in the figure). The interpreter also obtains the jump code for the called function in memory. Generally, after calculating the gas required to execute the contract and ensuring that sufficient gas is available, the contract jumps to the corresponding address in memory, retrieves the OPcode of the called function, and begins execution. The data operated on by the called function's OPcode is computed (data computation), pushed onto / popped from the stack, and so on, completing the data computation. During this process, some contract context information may be required, such as the block number and information about the initiator of the contract call. This information can be obtained from the Context (Get operation). Finally, the resulting state is stored in the database storage by calling the storage interface. It should be noted that during the contract creation process, certain functions within the contract may be executed, such as the initialization function. This also involves parsing the code, generating jump instructions, storing them into memory, and manipulating data on the stack.

[0203] In reality, high-level languages ​​like C, C++, Java, Go, and Python each have their own advantages. For example, C has higher execution efficiency; C++ and Java have a wider audience, large developer base, and relatively mature communities and tools; Go is more modern; and Python is relatively simpler and easier to use. Currently, various blockchain platforms are expanding their smart contract support to include smart contracts developed in high-level languages ​​like C, C++, Java, Go, and Python. One implementation option for supporting smart contracts developed in these high-level languages ​​is to compile them to bytecode in the Wasm (WebAssembly) format. WebAssembly, an open standard developed by the W3C Community Group, is a secure, portable, low-level code format designed for efficient execution and compact representation, delivering near-native performance. It also provides a compilation target for languages ​​like C, C++, Java, and Go. The Wasm virtual machine was originally designed to address the increasingly severe performance issues faced by web applications. Due to its superior features, it is increasingly being adopted by non-web projects, such as replacing the EVM, the smart contract execution engine. The WebAssembly virtual machine (also known as the Wasm virtual machine or Wasm runtime environment, a virtual machine runtime environment for executing WASM bytecode), implemented according to the W3C community's open standards, loads Wasm bytecode at runtime and interprets it for execution. The execution process of Wasm bytecode in the Wasm virtual machine is similar to the EVM process described above, as shown in Figure 13.

[0204] Based on the above-mentioned optimization solution for wasm bytecode, this application provides a method for deploying smart contracts. Referring to the process shown in FIG15 , the method includes the following steps:

[0205] S150: The blockchain node receives a transaction for deploying the contract, which includes the wasm bytecode of the contract before optimization.

[0206] As mentioned above, the smart contract source code developed in high-level languages ​​such as C, C++, Java, and Go can be compiled by a compiler to generate contract bytecode in wasm format.

[0207] As mentioned above, a contract deployment transaction typically includes the transaction initiator's address, a to address, and a data field. The transaction initiator's address can be implicitly or explicitly included in the transaction. The to address and data fields can be similar to some implementations, where the to field is an empty address, indicating that the transaction is a contract deployment transaction; the data field contains the bytecode of the Wasm contract.

[0208] The transaction creating a smart contract is sent to the blockchain. After consensus, each blockchain node can execute the transaction. Specifically, for a Wasm contract, the transaction can be executed by the blockchain node's Wasm virtual machine. This Wasm virtual machine can be a thread within the running blockchain node process or a separate process from the blockchain node. The former can involve communication within the same process (IPC, Inter Process Communication), while the latter can involve communication between processes (such as RPC, Remote Procedure Call). In some implementations, the Wasm virtual machine can be deployed on a physical machine separate from the blockchain node, but this is not a limitation here.

[0209] S152: Optimize the pre-optimized wasm bytecode to obtain an optimized wasm bytecode.

[0210] The aforementioned optimizer 1 or optimizer 2 may be used to optimize the wasm bytecode before optimization to obtain the optimized wasm bytecode, which may specifically include the process shown in FIG4 , or the process shown in FIG14 .

[0211] S154: The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode.

[0212] The account address of a smart contract can be similar to the rules in Ethereum, such as being generated based on the transaction initiator address and nonce through a mapping function, or it can be generated based on the contract name and through a mapping function. There is no limitation here, as long as the rules are fixed.

[0213] The codehash can be calculated from the optimized WASM bytecode. Specifically, it can be calculated using a hash algorithm such as SHA256. Using the codehash, the corresponding WASM bytecode can be found in the blockchain database. Furthermore, the same hash operation can be performed on the found WASM bytecode. The consistency of the resulting hash value with the codehash can be used to determine whether the WASM bytecode is the WASM bytecode corresponding to the codehash.

[0214] S156: The blockchain node stores the generated smart contract account on the blockchain ledger, where the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

[0215] Based on the deployed wasm contract corresponding to FIG15 above, this application provides a method for executing a smart contract, referring to the process shown in FIG16, including the following:

[0216] S160: The blockchain node receives a transaction for calling a contract, wherein the transaction specifies the address of the called contract account, the called function, and the passed-in parameters. The contract is an optimized wasm contract.

[0217] The contract is an optimized wasm contract, specifically including the optimized wasm bytecode as described in the corresponding scheme of Figure 15 above.

[0218] As mentioned above, in a contract-calling transaction, the to field can be used to specify the account address of the contract being called. Furthermore, in a contract-calling transaction, the data field can also specify the function being called and the parameters passed in.

[0219] S162: The blockchain node determines the codehash of the wasm contract through the contract account address, and loads the wasm bytecode corresponding to the codehash into the wasm virtual machine.

[0220] As mentioned above, through the contract account address specified in the transaction, the blockchain node can find the contract account and its codehash from the blockchain ledger, and can find the contract bytecode corresponding to the codehash. Here is the wasm bytecode after optimization of the corresponding solution as shown in Figure 15 above.

[0221] For a Wasm contract, the transaction can be executed by a Wasm virtual machine. This Wasm virtual machine can be a thread running within the blockchain node process or a separate process. The former can involve intra-process communication (IPC, Inter Process Communication), while the latter can involve inter-process communication (such as RPC, Remote Procedure Call). In some implementations, the Wasm virtual machine can be deployed on a physical machine separate from the blockchain node, but this is not a limitation.

[0222] The wasm virtual machine can first load the wasm bytecode.

[0223] S164: The wasm virtual machine reads and parses the optimized wasm bytecode to obtain a wasm module object.

[0224] S166: The wasm virtual machine creates a linear memory according to the parsed wasm module object and fills the linear memory.

[0225] S168: The wasm virtual machine executes the code of the code segment in the wasm module object based on the filled linear memory and the passed-in parameters.

[0226] Among them, if the code segment in the wasm module object does not contain the start function, the start function will not be executed; if the code segment in the wasm module object still contains the start function, that is, the optimized wasm bytecode does not remove the start function, but cancels the code marked as the start function, the start function is skipped and the code segment in the wasm module object is executed directly.

[0227] In this way, in the subsequent process of loading and executing the optimized wasm bytecode, the overhead caused by repeatedly executing the start function is eliminated, thereby improving the program's running performance.

[0228] The following describes a blockchain node in this application, including:

[0229] processor;

[0230] and a memory storing a program, wherein when the processor executes the program, the following operations are performed:

[0231] Receive the transaction that deploys the contract, which includes the contract's pre-optimized wasm bytecode;

[0232] Optimizing the wasm bytecode before optimization to obtain optimized wasm bytecode;

[0233] The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode;

[0234] The blockchain node stores the generated smart contract account on the blockchain ledger, where the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

[0235] The following describes a storage medium of the present application, which is used to store a program, wherein the program performs the following operations when executed:

[0236] Receive a transaction that calls a contract, which specifies the address of the contract account, the function being called, and the parameters passed in. The contract is an optimized wasm contract.

[0237] Determine the codehash of the wasm contract through the contract account address, and load the wasm bytecode corresponding to the codehash into the wasm virtual machine;

[0238] Read and parse the optimized wasm bytecode to obtain a wasm module object;

[0239] Create linear memory based on the parsed wasm module object and fill the linear memory;

[0240] The code of the code segment in the wasm module object is executed based on the linear memory obtained by filling and the passed in parameters.

[0241] In the 1990s, technological improvements could be clearly distinguished as either hardware improvements (for example, improvements to circuit structures like diodes, transistors, and switches) or software improvements (improvements to process flows). However, with the advancement of technology, many process flow improvements today can now be considered direct improvements to hardware circuit structures. Designers almost always create the corresponding hardware circuit structure by programming the improved process flow into the hardware circuit. Therefore, it cannot be said that a process flow improvement cannot be implemented using hardware modules. For example, a programmable logic device (PLD), such as a field programmable gate array (FPGA), is an integrated circuit whose logical function is determined by user programming. Designers can "integrate" a digital system on a PLD by programming it themselves, without having to hire a chip manufacturer to design and manufacture a dedicated integrated circuit chip. Moreover, nowadays, instead of manually fabricating integrated circuit chips, this programming is mostly done using "logic compiler" software. This is similar to the software compiler used when developing programs. Before compilation, the original code must also be written in a specific programming language, called a hardware description language (HDL). There is not just one HDL, but many, such as ABEL (Advanced Boolean Expression Language), AHDL (Altera Hardware Description Language), Confluence, CUPL (Cornell University Programming Language), HDCal, JHDL (Java Hardware Description Language), Lava, Lola, MyHDL, PALASM, RHDL (Ruby Hardware Description Language), etc. The most commonly used are VHDL (Very-High-Speed ​​Integrated Circuit Hardware Description Language) and Verilog. Those skilled in the art will also understand that by simply programming the method flow in one of these hardware description languages ​​and then programming it into an integrated circuit, a hardware circuit that implements the logic method flow can be easily obtained.

[0242] The controller can be implemented in any suitable manner. For example, the controller can take the form of a microprocessor or processor and a computer-readable medium storing computer-readable program code (e.g., software or firmware) executable by the (micro)processor, logic gates, switches, application-specific integrated circuits (ASICs), programmable logic controllers, and embedded microcontrollers. Examples of controllers include, but are not limited to, the following microcontrollers: ARC 625D, Atmel AT91SAM, Microchip PIC18F26K20, and Silicone Labs C8051F320. The memory controller can also be implemented as part of the control logic of the memory. Those skilled in the art will also know that in addition to implementing the controller in a purely computer-readable program code format, the controller can be implemented in the form of logic gates, switches, application-specific integrated circuits, programmable logic controllers, and embedded microcontrollers by logically programming the method steps. Therefore, such a controller can be considered a hardware component, and the devices included therein for implementing various functions can also be considered as structures within the hardware component. Or even, the devices for implementing various functions can be considered as both software modules that implement the method and structures within the hardware component.

[0243] The systems, devices, modules or units described in the above embodiments may be implemented by computer chips or entities, or by products with certain functions. A typical implementation device is a server system. Of course, this application does not exclude that with the future development of computer technology, the computer that implements the functions of the above embodiments may be, for example, a personal computer, a laptop computer, an in-vehicle human-computer interaction device, a cellular phone, a camera phone, a smart phone, a personal digital assistant, a media player, a navigation device, an email device, a game console, a tablet computer, a wearable device, or a combination of any of these devices.

[0244] Although one or more embodiments of this specification provide method operation steps as described in the embodiments or flow charts, more or fewer operation steps may be included based on conventional or non-creative means. The order of steps listed in the embodiments is only one way of executing the order of many steps and does not represent the only execution order. When the device or terminal product in practice is executed, it can be executed in sequence or in parallel according to the method shown in the embodiments or the drawings (for example, a parallel processor or a multi-threaded processing environment, or even a distributed data processing environment). The term "comprise", "include" or any other variant thereof is intended to cover non-exclusive inclusion, so that the process, method, product or equipment including a series of elements includes not only those elements, but also includes other elements that are not clearly listed, or also includes elements inherent to such process, method, product or equipment. In the absence of more restrictions, it is not excluded that there are other identical or equivalent elements in the process, method, product or equipment including the elements. For example, if the words first, second, etc. are used to represent the name, they do not represent any particular order.

[0245] For the convenience of description, the above devices are described in terms of functions divided into various modules. Of course, when implementing one or more of the present specifications, the functions of each module can be implemented in the same or multiple software and / or hardware, or the module that implements the same function can be implemented by a combination of multiple sub-modules or sub-units, etc. The device embodiments described above are merely schematic. For example, the division of the units is only a logical function division. There may be other division methods in actual implementation, such as multiple units or components can be combined or integrated into another system, or some features can be ignored or not executed. Another point is that the mutual coupling or direct coupling or communication connection shown or discussed can be an indirect coupling or communication connection through some interfaces, devices or units, which can be electrical, mechanical or other forms.

[0246] The present invention is described with reference to the flowcharts and / or block diagrams of the methods, apparatus (systems), and computer program products according to embodiments of the present invention. It should be understood that each process and / or block in the flowchart and / or block diagram, as well as the combination of processes and / or blocks in the flowchart and / or block diagram, can be implemented by computer program instructions. These computer program instructions can be provided to a processor of a general-purpose computer, a special-purpose computer, an embedded processor, or other programmable data processing device to produce a machine, so that the instructions executed by the processor of the computer or other programmable data processing device produce a device for implementing the functions specified in one or more processes in the flowchart and / or one or more blocks in the block diagram.

[0247] These computer program instructions may also be stored in a computer-readable memory that can direct a computer or other programmable data processing device to operate in a specific manner, so that the instructions stored in the computer-readable memory produce a product including an instruction device that implements the functions specified in one or more processes in the flowchart and / or one or more boxes in the block diagram.

[0248] These computer program instructions can also be loaded onto a computer or other programmable data processing device so that a series of operating steps are executed on the computer or other programmable device to produce a computer-implemented process, so that the instructions executed on the computer or other programmable device provide steps for implementing the functions specified in one or more processes in the flowchart and / or one or more boxes in the block diagram.

[0249] In a typical configuration, a computing device includes one or more processors (CPUs), input / output interfaces, network interfaces, and memory.

[0250] Memory may include non-permanent storage in a computer-readable medium, random access memory (RAM) and / or non-volatile memory in the form of read-only memory (ROM) or flash RAM. Memory is an example of a computer-readable medium.

[0251] Computer-readable media include permanent and non-permanent, removable and non-removable media that can be implemented by any method or technology to store information. Information can be computer-readable instructions, data structures, program modules or other data. Examples of computer storage media include, but are not limited to, phase change memory (PRAM), static random access memory (SRAM), dynamic random access memory (DRAM), other types of random access memory (RAM), read-only memory (ROM), electrically erasable programmable read-only memory (EEPROM), flash memory or other memory technology, compact disc read-only memory (CD-ROM), digital versatile disc (DVD) or other optical storage, magnetic cassettes, magnetic tape, magnetic disk storage, graphene storage or other magnetic storage devices or any other non-transmission media that can be used to store information that can be accessed by a computing device. As defined herein, computer-readable media does not include transitory media such as modulated data signals and carrier waves.

[0252] Those skilled in the art will appreciate that one or more embodiments of this specification may be provided as a method, system, or computer program product. Thus, one or more embodiments of this specification may take the form of an entirely hardware embodiment, an entirely software embodiment, or an embodiment combining software and hardware. Furthermore, one or more embodiments of this specification may take the form of a computer program product implemented on one or more computer-usable storage media (including but not limited to magnetic disk storage, CD-ROM, optical storage, etc.) containing computer-usable program code.

[0253] One or more embodiments of this specification may be described in the general context of computer-executable instructions executed by a computer, such as program modules. Generally, program modules include routines, programs, objects, components, data structures, and the like that perform specific tasks or implement specific abstract data types. One or more embodiments of this specification may also be practiced in distributed computing environments where tasks are performed by remote processing devices connected via a communications network. In distributed computing environments, program modules may be located in local and remote computer storage media, including storage devices.

[0254] The various embodiments in this specification are described in a progressive manner. Similar or identical parts between the various embodiments can be referenced across them. Each embodiment focuses on the differences from the other embodiments. In particular, since the system embodiments are generally similar to the method embodiments, their description is relatively simple. For relevant parts, reference can be made to the description of the method embodiments. Throughout this specification, reference to the terms "one embodiment," "some embodiments," "examples," "specific examples," or "some examples" means that the specific features, structures, materials, or characteristics described in conjunction with that embodiment or example are included in at least one embodiment or example of this specification. In this specification, the schematic representations of these terms do not necessarily refer to the same embodiment or example. Furthermore, the specific features, structures, materials, or characteristics described may be combined in any suitable manner in any one or more embodiments or examples. Furthermore, those skilled in the art may combine and integrate the different embodiments or examples, and features of different embodiments or examples, described in this specification, without conflict.

[0255] The foregoing is merely an example of one or more embodiments of this specification and is not intended to limit the one or more embodiments of this specification. It will be apparent to those skilled in the art that various modifications and variations may be made to one or more embodiments of this specification. Any modifications, equivalent substitutions, or improvements made within the spirit and principles of this specification shall be included within the scope of the claims.

Claims

1. A method for deploying a smart contract, comprising: The blockchain node receives the transaction for deploying the contract, which includes the contract's pre-optimized wasm bytecode. Optimizing the wasm bytecode before optimization to obtain optimized wasm bytecode; The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode; The blockchain node stores the generated smart contract account on the blockchain ledger, and the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

2. The method according to claim 1, wherein optimizing the pre-optimized wasm bytecode comprises: Read and parse the wasm bytecode before optimization to get the wasm module object; Create linear memory and fill linear memory according to the parsed wasm module object; Execute the start function in the wasm module object, and modify the linear memory according to the execution result of the start function; Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object; Encode the wasm module after replacing the data segment and save it as optimized wasm bytecode.

3. The method according to claim 1, wherein optimizing the pre-optimized wasm bytecode comprises: Read and parse the wasm bytecode to get the wasm module object; Create linear memory and fill linear memory according to the parsed wasm module object; Execute the start function in the wasm module object, compress the execution result data of the start function, and modify the linear memory using the compressed execution result; Use the data in the modified linear memory to replace the corresponding data segment in the wasm module object; Encode the wasm module after replacing the data segment and save it as wasm bytecode.

4. The method according to claim 2 or 3 further comprises removing the start function in the wasm module object before encoding.

5. A method for executing a deployed smart contract as claimed in claim 1, comprising: The blockchain node receives a transaction for calling a contract, in which the address of the called contract account, the called function and the passed-in parameters are specified. The contract is an optimized wasm contract. The blockchain node determines the codehash of the wasm contract through the contract account address, and loads the wasm bytecode corresponding to the codehash into the wasm virtual machine; The wasm virtual machine reads and parses the optimized wasm bytecode to obtain a wasm module object; The wasm virtual machine creates a linear memory and fills the linear memory according to the parsed wasm module object; The wasm virtual machine executes the code of the code segment in the wasm module object based on the filled linear memory and the passed-in parameters.

6. The method according to claim 5, wherein the step of reading and parsing the optimized wasm bytecode to obtain a wasm module object comprises: The optimized wasm bytecode is read and parsed, and the compressed data contained therein is restored by decompression to obtain a wasm module object.

7. According to the method as claimed in claim 5, if the code segment in the wasm module object does not include a start function, the wasm virtual machine does not execute the start function when executing.

8. According to the method as claimed in claim 5, if the code segment in the wasm module object still contains the start function but the code marked as the start function is cancelled, the wasm virtual machine skips the start function and directly executes the code of the code segment in the wasm module object.

9. A computer device comprising: processor; and a memory, wherein a program is stored, wherein when the processor executes the program, the following operations are performed: Receive the transaction for deploying the contract, which includes the contract's pre-optimized wasm bytecode; Optimizing the wasm bytecode before optimization to obtain optimized wasm bytecode; The blockchain node generates a smart contract account on the blockchain and generates the codehash in the smart contract account based on the optimized wasm bytecode; The blockchain node stores the generated smart contract account on the blockchain ledger, and the smart contract account includes the codehash and the corresponding optimized wasm bytecode.

10. A storage medium for storing a program, wherein the program performs the following operations when executed: Receive a transaction that calls a contract, which specifies the address of the called contract account, the called function, and the passed-in parameters. The contract is an optimized wasm contract. Determine the codehash of the wasm contract through the contract account address, and load the wasm bytecode corresponding to the codehash into the wasm virtual machine; Read and parse the optimized wasm bytecode to obtain a wasm module object; Create linear memory and fill linear memory according to the parsed wasm module object; The code of the code segment in the wasm module object is executed based on the filled linear memory and the passed-in parameters.

Citation Information

Patent Citations

  • Intelligent contract virtual machine based on WebAssembly

    CN111179086A

  • Method for realizing reflection mechanism in block chain, compiling method, compiler and Wasm virtual machine

    CN115495087A

  • Method and device for calling function by WebAssembly module

    CN115982784A

  • Debugging method and device for smart contract

    CN116089280A

  • Wasm byte code optimization method and execution method, computer equipment and storage medium

    CN116931947A