solidity – How to Convert Staticcall Result from Bytes to a String Array

solidity

I've been able to use staticcall to retrieve values from smart contracts based on the name of a parameterless function, like this:

bytes memory bresult;
bool success;
(success, bresult) = address(this).staticcall(abi.encodeWithSignature(functionName.concat("()")));

If I know the return type, for simple type (string, uints, bools, addresses) I've been able to figure out how to convert the bytes array returned by staticcall into a value of the appropriate type.

But for functions which return a string array, I'm not sure how to do this.

i.e. a function like this:

 function nameList() public view returns (string[] memory) {
    string[] returnValue = new string[](3);
    returnValue[0]="John";
    returnValue[1]="Paul";
    returnValue[2]="Luke";
    return returnValue;
 }

if I call
(success, bresult) = address(contractAddress).staticcall(abi.encodeWithSignature("nameList()");

How can I convert result back into the string array returned by the function?

Best Answer

So with abi.encodeWithSignature() , the function needs to be in quotes.

abi.encodeWithSignature("myFunc(string)","myString")

followed by the argument(s)

and then you can simply use abi.decode which needs the bytes[] you want to decode and the type, such as:

abi.decode(retVal,(string))

here are the resources (yay official docs have the answer!) https://docs.soliditylang.org/en/v0.8.9/units-and-global-variables.html#abi-encoding-and-decoding-functions

And for your specific situation something like this works:

contract StringArrayContract {
 string[] public blob= ["joe","joel","janine"];

  function stringArrayFunc() public view returns(string[] memory){
    return blob;
  }
} 

 contract callReceiver {

  function callAndReturn(address _add) external view returns (string[] memory){
     string[] memory temp;
     (bool success, bytes memory retVal) = _add.staticcall(abi.encodeWithSignature("stringArrayFunc()"));
     if(success){ temp = abi.decode(retVal, (string[]));}
     return temp;
    }
   }