0

I am currently writing a smart contract using Solidity in version 0.8.4 and I want to return a (dynamic) array or structs (comprising several strings each).

Now in remix, this seems to work just fine with code like this:

MyStruct {
    string a;
    string b;
}

function f() public returns (MyStruct[] memory) {
    MyStruct[] memory a;
    
    MyStruct s1 = MyStruct("s1a", "s1b");
    MyStruct s2 = MyStruct("s2a", "s2b");

    a[0] = s1;
    a[1] = s2;
    
    return a;
}

Now, when running this and calling f(), I get as decoded output from calling this function

{ "0": "tuple(string,string)[]: s1a,s1b,s2a,s2b" }

So here I have a simple string array with an "info" to interpret it as 2-tuples of strings. Is there a way to return this as an array of arrays, i.e.

{ "0": "struct[]: tuple(string, string)[]: s1a,s1b, tuple(string, string)[]: s2a,s2b" }

As it is it looks a bit mangled to me - am I doing something wrong or is this intentionally designed this way?

1

Generally this type of complex return values should be returned in Events. As solidity docs specifies here:

You cannot return some types from non-internal functions, notably multi-dimensional dynamic arrays and structs. If you enable the ABI coder v2 by adding pragma abicoder v2; to your source file then more types are available, but mapping types are still limited to inside a single contract and you cannot transfer them.

Here, I've slightly modified your code, compiled with 0.8.4. You may try this at remix, you'll see the value in event is going to be:

"event": "FCalled", "args": { "0": [ [ "s1a", "s1b" ], [ "s2a", "s2b" ] ], "_a": [ [ "s1a", "s1b" ], [ "s2a", "s2b" ] ] }

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;


contract TestContract {
    struct MyStruct {
        string a;
        string b;
    }
    
    event FCalled(MyStruct[] _a);

    function f() public {
        MyStruct[] memory a = new MyStruct[](2);
        
        MyStruct memory s1 = MyStruct("s1a", "s1b");
        MyStruct memory s2 = MyStruct("s2a", "s2b");
    
        a[0] = s1;
        a[1] = s2;
        
        emit FCalled(a);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.