Smart Contract Schema Tool
Smart contracts need to be very robust. The generic nature of WasmLib allows for a lot of flexibility, but it also a lot of opportunities to make mistakes. In addition, there is a lot of repetitive coding involved. The setup code that is needed for every smart contract must follow strict rules. You want to assure that certain functions can only be called by specific entities, and that function parameters values have been properly checked before their usage.
The best way to increase robustness is by using a code generator that will take care of most repetitive coding tasks. A code generator only needs to be debugged once, after which the generated code is 100% accurate and trustworthy. Another advantage of code generation is that you can regenerate code to correctly reflect any changes to the smart contract interface. A code generator can also help you by generating wrapper code that limits what you can do to mirror the intent behind it. This enables compile-time enforcing of some aspects of the defined smart contract behavior. A code generator can also support multiple different programming languages.
During the initial experiences creating demo smart contracts for WasmLib, we quickly identified a number of areas where there was a lot of repetitive coding going on. Some examples of repetition were:
- Setting up the
on_loadfunction and keeping it up to date
- Checking function access rights
- Verifying function parameter types
- Verifying the presence of mandatory function parameters
- Setting up access to state, params, and results maps
- Defining common strings as constants
To facilitate the code generation, we decided to use a schema definition file for smart contracts. All aspects of a smart contract that should be known by someone who wants to use the contract are clearly defined in a schema definition file. This schema definition file then becomes the source of truth for how the smart contract works.
The schema definition file defines things like the state variables that the smart contract uses, the Funcs and Views that the contract implements, the access rights for each function, the input parameters and output results for each function, and additional data structures that the contract uses.
With detailed schema information readily available in a single location, it becomes possible to do a lot more than just generating repetitive code fragments. You can use the schema information to generate interfaces for functions, parameters, results, and state that use strict compile-time type-checking. This reduces the likelihood of introducing errors significantly.
Another advantage of knowing everything about important smart contract aspects is that it is possible to generate constants to prevent repeating of typo-prone key strings, and precalculate necessary values like Hnames and encode them as constants instead of having the code recalculate them every time they are needed.
Similarly, since you know all static keys that are going to be used by the smart contract
in advance, you can now generate code that will negotiate the corresponding key IDs with
the host only once in the
on_load function, and cache those values for use in future
The previous two optimizations mean that the code becomes both simpler and more efficient. Note that all the improvements described above are independent of the programming language used.
In the next section we will look at how the schema tool works.