Search code examples
arraysethereumsolidity

Is there a way to pass fixed array as parameter to utility function is Solidity?


I have two arrays with fixed lengths which I want to send to a utility function, but it gives the following error since arrays length are different.

TypeError: Invalid type for argument in function call. Invalid implicit conversion from string storage ref[2] storage ref to string storage ref[] storage pointer requested.

Is there a way to make a utility function that will take fixed arrays with arbitrary lengths?

Full code snippet

contract test {
    string[2] internal list1 = ["str1", "str2"];
    string[3] internal list2 = ["str3", "str4", "str5"];

    function entryPoint() public view returns (uint256) {
        return utilityFunction(list1, list2);
    }
    
    function utilityFunction(string[] storage _list1, string[] storage _list2) internal pure returns (uint256 result) {
        // some logic here
    }
}

Solution

  • You can have the function accept the predefined fixed length

    // changed `string[]` to `string[2]` and the other `string[]` to `string[3]`
    function utilityFunction(string[2] storage _list1, string[3] storage _list2) internal pure returns (uint256 result) {
    

    Or you can convert the arrays to dynamic-size at first, and them pass them to the dynamic-size accepting function

    function entryPoint() public view returns (uint256) {
        // declare a dynamic-size array in memory with 2 empty items
        string[] memory _list1 = new string[](2);
        // assign values to the dynamic-size array
        _list1[0] = list1[0];
        _list1[1] = list1[1];
    
        string[] memory _list2 = new string[](3);
        _list2[0] = list2[0];
        _list2[1] = list2[1];
        _list2[2] = list2[2];
    
        // pass the dynamic-size in-memory arrays
        return utilityFunction(_list1, _list2);
    }
    
    // changed location to memory, now you can accept dynamic-size arrays with arbitrary length
    function utilityFunction(string[] memory _list1, string[] memory _list2) internal pure returns (uint256 result) {
    }
    

    But there's currently (v0.8) no way to accept fixed-size arrays with arbitrary length. Just with the predefined length.


    Note: There's some space for gas optimization in my entryPoint() example (by making in-memory copies of the list1 and list2 at first, and then reading from the in-memory copies when assigning the _list1 and _list2 values). But my goal was to make a clearer example of assigning to the dynamic-size array instead of worsening code readability by optimizations.