Packing and Unpacking
Learn how to unpack inputs and pack outputs.
In this first segment of examining the contract.go
file generated for us, we will go over the packing and unpacking functions in this file.
The Notion of Packing
Those eager to implement the MD5 algorithm might be wondering why we're discussing packing. However, there is good reason to discuss packing, and it comes down to the specification of the staticcall
function in Solidity.
We begin by referring to the example of calling the SHA-256 precompiled contract:
As seen above, the staticcall
function accepts input in bytes format, generated by abi.encode
, and returns a boolean value indicating success, along with a bytes format output.
Therefore, our precompiled contract should be designed to accept and return data in bytes format, involving the packing and unpacking of values. Since packing is a deterministic process, there's no concern about data corruption during translation. However, some preprocessing or postprocessing is necessary to ensure the contract functions correctly.
Unpacking Inputs
In contract.go
, the function UnpackHashWithMd5Input
unpacks our data and converts it into a type relevant to us. It takes a byte array as an input and returns a Go string. We will look at more complex precompiles that have multiple functions that may take multiple inputs later.
Packing Outputs
Ignoring hashWithMD5
for now, note that whatever value hashWithMD5
outputs, we will need to postprocess it (i.e. pack it). PackHashWithMD5Output
does just this, taking in an input of type [16]byte and outputting a byte array which can be returned by staticcall
.
This may seem trivial, but if our Solidity interface defined our function to return a uint or string, the type of our input to this function would differ accordingly.