String array as parameter input in public function

Hey, my good friend @dan-i, I need some expert advice! :nerd_face:
I’m having some trouble using string[] as an input parameter to a public function, I got tips from @rph in the Moralis Discord channel to use https://ethereum.stackexchange.com/a/1623, but I don’t understand how to use this, and I cannot find any good examples on how to use it.

I’ve tried to create a function that takes in a string and divides it by commas. but there is something wrong with my code, and I can’t figure out where the error is.
It gets reverted when trying to set a byte equal to another.

I’m grateful for any response!
Thank you for taking the time to read and get me in the right direction :smiley:

function createArray(string memory test) public returns(string[] memory){
        bytes1 comma = ",";
        bytes memory input = bytes(test);
        
        bytes memory temp;
        string[] memory array;

        uint j = 0;
        uint k = 0;

        for(uint i = 0; i < input.length; i++){
            if(input[i] != comma ){
                temp[k] = input[i];     // This is where it get reverted when trying it in Remix
                k++;
            } else {
                array[j] = string(temp);
                j++;
                k=0;
                
            }
        }
        return array;
    }

Hey @voljumet

Not sure what you are trying to achieve :smiley:
You mentioned:

I’m having some trouble using string[] as an input parameter to a public function

But the parameter requested in your function is a string.

Can you please give me an example of the input and the output you want to have?

As far as I understand

I’ve tried to create a function that takes in a string and divides it by commas.

You want something like:

input: “test”
output “t,e,s,t”

Let me know,
Dani

Ah yes, sorry for the bad explanation :sweat_smile:

I wanted a function “ceateCase” in my code to have a string array ([“alternative1”,“alternative2”,“alternative3”]) as input, but found out that it won’t work because the function is public.
So I tried to rebuild the function to take in a string instead (“alternative1,alternative2,alternative3”), and then just use the function I posted to split the string and store it as an array, so I can use it in the “createCase” function.

function createCase(string memory input) public { 
    lots of code.... 
// input = "alternative1,alternative2,alternative3"
string[] memory array = createArray(input);
// array = ["alternative1","alternative2","alternative3"]
}

function createArray(string memory input) internal returns(string[] memory){
    ...code that takes input and crates an array out of it...
return array
}

I hope that made it a bit clearer :blush:

Hi @voljumet

By trying to split a string and divide it into multiple words you are trying to use solidity for something that it is not programmed for.
Something like that should surely be done in another language such as JS or python.
Keep in mind that there are different programming languages because they serve for different purposes.

This was a mandatory clarification I had to do, I can still give suggestions for the array split (in solidity you cannot access strings by using an index which is something you can do in most of the other languages).

Follows an example that takes an array of strings and copy each word in another array.

pragma solidity 0.8.0;

contract test {
    
    function splitString(string [] memory _toSplit) public view returns (string [] memory) {    
        string [] memory _result = new string [](_toSplit.length);
        for(uint i = 0; i < _toSplit.length; i++) {
            _result[i] = _toSplit[i];
        } 
        return _result;
    }
}

Screenshot 2021-04-03 at 13.13.17

1 Like

Ok, thank you for the answer, but the function still takes a string [] as input?
Does this mean that the input parameter in a function in solidity should not be dynamically sized?

What I wanted for my function was to let the user choose how many alternatives to vote on.
in one instance, a user would want maybe two alternatives, and in another instance, a user would maybe want five alternatives, what you are saying is basically that I have to decide in advance how many alternatives the users should be able to pick from right?

Hi @voljumet

I have to decide in advance how many alternatives the users should be able to pick from right?

No, you can just send an array of strings as in my example above.
The array can have a length of 10, 100 or 1 does not make any difference.

Regards,
Dani

Edit: Thank you for the help so far, we have found a solution to the function, so no need to waste time on our code :nerd_face:

Hmm, alright, then the function with a string array as input should work fine, but it doesn't 😅
Can you see where I made a mistake in the code?
The code is here: https://github.com/voljumet/ChainVote/tree/6bd918389e0ad85377bf3356065601aac6903d9b
but we have pushed some new code that has been merged into main, so you will have to look at the commit that I have linked to see the function as I want it to be.
the function is called "createCase" and will give an error message when sending all the inputs required from our front end to ganache/truffle.

And I want to thank you again for all your help, it would be awesome if we can figure out a solution 😃

Edit: 
The info I have used to come to my conclusion so far:
``
One of the features which solidity is missing is that it cannot return or take multi-dimensional arrays as input. Well, that does not seem important but when we talk about strings, we realize that they are just arbitrary-length byte array(i.e.  `byte[]` ). So when you create a string array, you are creating a two-dimensional byte array(i.e.  `byte[][]` ).
``
https://hackernoon.com/serializing-string-arrays-in-solidity-db4b6037e520
1 Like