I am trying to unit test a Solidity Library contract function using truffle and web3. My simplified Library contract looks like this:
pragma solidity >=0.5.16;
pragma experimental ABIEncoderV2;
library BrickLib {
struct ECSignature {
uint8 v;
}
function checkSig(ECSignature memory sig)
public pure returns(bool) {
return true;
}
}
I am attempting to call that function using web3/truffle in my unit test as follows:
const v = 1
await brickLib.checkSig.call({ v })
When this call is made, I get the following error:
Error: Returned error: VM Exception while processing transaction: revert
The same error also appears in the remix UI when I try to call the checkSig method from the user interface by deploying the library contract and entering "[1]" in the parameter. The exact error in Remix is:
call to BrickLib.checkSig errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.
However, any of the following modifications to the contract rectify the issue:
- Changing the contract from a
library
to acontract
. - Removing the
memory
parameter completely, even if there are other non-memory parameters present. - Calling the
checkSig
function from within another contract that is importing the library contract. - Changing the data type of the memory parameter from a struct to a standard type such as
bytes memory
.
I suspect this all has to do with how Solidity calls library methods and that the call method changes when memory arguments are introduced, but it is not exactly clear what is happening. Maybe I need to use a delegatecall
instead of a regular call
?
As I am writing unit tests for my contract library in Javascript, I would prefer not to have to deploy a second contract using the library in order to test it. I would also prefer to write my tests in Javascript and not Solidity. I'd rather also maintain the use of a struct, as my real code is more complex and structs assist in maintainability.