Solidity Gas Optimizations - Data Compression
In the process of developing smart contract, because we want to be able to achieve matching function, we have implemented a function that can input multiple orders. As more and more features are added to our function and more and more arguments are required to ensure contractual fairness, such as miners’ fees, taker’s fee, maker’s fee and payment method of fee. We encounter to the variable too much and can not compile, and a lot of data consumed gas has also become a problem.
In our matching function, we will have this information for each order:
1 | uint256 amountSell, |
So we tried to find ways to reduce the number of variables. One day I looked at a transaction in Etherscan which shows the following information:
1 | Function: trade(address tokenGet, uint256 amountGet, address tokenGive, uint256 amountGive, uint256 expires, uint256 nonce, address user, uint8 v, bytes32 r, bytes32 s, uint256 amount) *** |
I found that all arguments are 256 bits, regardless of the type is byte32
, address
or uint8
. So most of the arguments on the left have a large number of “0” is unused bits. It is easy to think of using these “spaces”.
Data Merging
First, uin256
and byte32
will fill the entire variable space, so the amount and signature r, s can not be used. I chose the address
variable to use. In addition, We made adjustments that do not require too many bits of type:
1 | nonce -> 40 bits |
A address
variable, for example:
1 | 000000000000000000000000a92f038e486768447291ec7277fff094421cbe1c |
It can be stuffed into the above information into:
The above information corresponds to the following:
1 | nonce: 0181bfeb |
The original arguments can be reduced to:
1 | uint256 amountSell, |
Of course, v can also be stuffed into another address
variables. I will not repeat them.
Numbering
This has saved a lot of arguments, but I have a new idea: token address
should be limited, it is better to use the automatically increment to number just like database? So we further number token and user. The final data becomes:
The three rightmost ones represent tokenSell, tokenBuy, and user. The orange one indicates the signature v. In the end, our order information is compress to:
1 | uint256 amountSell, |
Save from the original 14 variables to 6 variables.
Further Reading
Previous Post: Solidity Gas Optimizations - Function Name
Next Post: Solidity Gas Optimizations - Variable Ordering