Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return array of structs now support? #2948

Closed
EasonWang01 opened this issue Sep 21, 2017 · 31 comments
Closed

Return array of structs now support? #2948

EasonWang01 opened this issue Sep 21, 2017 · 31 comments

Comments

@EasonWang01
Copy link

EasonWang01 commented Sep 21, 2017

Is it support now for solidity?

struct User {
    uint id;
    string name;
    string age;
    uint salary;
}
User[] public users;
    
function queryuser () returns ( User[] ) {
    return users;
}

Thanks for reply.

@chriseth
Copy link
Contributor

Try pragma experimental ABIDecoderV2; on a 0.4.17 compiler.

@EasonWang01
Copy link
Author

EasonWang01 commented Sep 22, 2017

The remix IDE says below:

 SyntaxError: Unsupported experimental feature name.
pragma experimental ABIDecoderV2;

pragma experimental ABIDecoderV2;


contract test {
.....
}

Version:

Your current Solidity version is
0.4.17-nightly.2017.9.19+commit.1fc71bd7.Emscripten.clang

@chriseth
Copy link
Contributor

oh I'm sorry - it's ABIEncoderV2.

@EasonWang01
Copy link
Author

EasonWang01 commented Sep 23, 2017

When execute the return array function it says below

Value: "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000003656173000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000043078303000000000000000000000000000000000000000000000000000000000"
Decoded: Failed to decode output: Error: Unsupported or invalid type: tuple

function

    function queryuser() public constant returns(User[]) {
        return users;
    }

    function addUser(uint _salaryId, string _name, string _userAddress, uint _salary) public  
      returns(uint) {
        users.length++;
        users[users.length-1].salaryId = _salaryId;
        users[users.length-1].name = _name;
        users[users.length-1].userAddress = _userAddress;
        users[users.length-1].salary = _salary;
        return users.length;
    }

@axic
Copy link
Member

axic commented Sep 25, 2017

@EasonWang01 this seems to be a limitation in the decoding library you are using (possibly web3.js).

@EasonWang01
Copy link
Author

Was using Remix IDE,is it possible to decode it?

@axic
Copy link
Member

axic commented Sep 25, 2017

Not in Remix currently.

@EasonWang01
Copy link
Author

Do you know how to decode it if not using Remix?
Thanks

@VoR0220
Copy link
Member

VoR0220 commented Oct 11, 2017

@EasonWang01 that will need to be written up. I'm not sure if any of the ABIs support it just yet.

@mimitc123
Copy link

@EasonWang01 Has the problem been solved

@srameshr
Copy link

Still cant return array of struct?

@chriseth
Copy link
Contributor

Any help is appreciated!

@wjmelements
Copy link
Contributor

wjmelements commented Jan 29, 2018

Returning structs in general seems to work only for automatic public accessors and fail otherwise.

pragma solidity^0.4.19;
pragma experimental ABIEncoderV2;

library L {
    struct Data {
        uint c;
    }
    struct Storage {
        Data[] data;
    }

    function inc(Storage storage self)
    internal {
        self.data.push(Data(self.data.length));
    }
}
contract C {
    using L for L.Storage;
    L.Storage lib;
    L.Data[] data;
    L.Data[] public publicArray;
    L.Data public publicSingle;

    function push()
    external {
        lib.inc();
        data.push(L.Data(data.length));
        publicArray.push(L.Data(data.length));
    }
    function getLib(uint i)
    public view returns (L.Data) {
        return lib.data[i];
    }
    function get(uint i)
    public view returns (L.Data) {
        return data[i];
    }
}

In remix IDE the failure is "Failed to decode output: Error: Unsupported or invalid type: tuple". I get a similar error in web3.js.

@wjmelements
Copy link
Contributor

The difference in the ABI between the cases that decode and the cases that don't is the output type.

"outputs":[{"name":"c","type":"uint256"}] works

"outputs":[{"components":[{"name":"c","type":"uint256"}],"name":"","type":"tuple"}] fails to decode

Why is there indirection about "components"? The array of dictionaries was already sufficient to describe a struct type, and was already implemented by several decoders.

@wjmelements
Copy link
Contributor

wjmelements commented Jan 29, 2018

@chriseth
Copy link
Contributor

@wjmelements web3.js is still lacking an implementation for structs. ethers.js should already be fully compliant. The components-indirection was needed, because the type value is of type string. We considered making it either string or array, but people more used to JS/JSON advised against it.

@ThomasMW
Copy link

ThomasMW commented Feb 25, 2018

Is there any progress yet, in either Remix or Web3.js? I can't see the current workaround.

@wjmelements
Copy link
Contributor

@ThomasMW they renamed the repo, which killed that link. Here is the new link: https://github.com/ethereum/remix-ide/issues/920#issuecomment-348069589

@comeonbuddy
Copy link

comeonbuddy commented Mar 13, 2018

according to the answer in the url https://github.com/ethereum/remix-ide/issues/920#issuecomment-348069589 which is

function all(uint pos) public constant returns(uint id, uint value, uint time){ 
DonateInfo storage di = list[pos];
return (di.id, di.value, di.time)
} 

But it is not returning the whole list of array tho, it is taking in an uint and output a specific struct, similar to array[unit]?

@clrke
Copy link

clrke commented Mar 18, 2018

Yup, is it not possible to get all DonateInfos?

@kyriediculous
Copy link

kyriediculous commented Mar 20, 2018

Breaking down the struct into an array will not work either without converting strings to bytes and back, it's quite the messy workaround as well imo.

Using 0.4.22 and experimental ABIEncoderV2 still getting the error.

It would be really cool if this could receive some priority, I imagine many devs would like to see this feature. Not trying to be pushy here 😄 .

Wouldn't having a struct as a real object be an "easy" solution? Not that I have any clue what I'm talking about here.

Another workaround is constructing your array on the client side with .map() (from an array of integers) I guess...

@Ajit666
Copy link

Ajit666 commented Apr 6, 2018

"error": "Failed to decode output: Error: Unsupported or invalid type: tuple"

@chriseth chriseth closed this as completed Apr 6, 2018
@kyriediculous
Copy link

Why is this closed ?

@axic
Copy link
Member

axic commented Apr 9, 2018

Because it has been supported since 0.4.17 by the compiler.

@kyriediculous
Copy link

kyriediculous commented Jun 4, 2018

is it?. Using nightly builds or experimental encoders doesn't really qualifiy as supported imo.

@adrianmcli
Copy link

I agree that this should be re-opened. Trying to return an array of structs is still an active issue in the community.

@chriseth
Copy link
Contributor

You have to activate an experimental feature: #2948 (comment)

Having this issue open does not speed up the completion of the experimental feature.

@d-saravanan
Copy link

how do i return a mapping or a array from a solidity function

@wjmelements
Copy link
Contributor

You cannot return a mapping.

@erak
Copy link
Collaborator

erak commented Mar 20, 2019

@ANUDAVIS Could you please share an example? Without any code, it's hard to reason about your issue. In general, this should work:

pragma solidity >0.5.6;
pragma experimental ABIEncoderV2;

contract Contract {

    struct Entry {
        uint id;
    }
    
    function getEntries() public returns (Entry[] memory) {
        Entry[] memory entries = new Entry[](1);
        entries[0] = Entry(1);
        return entries;
    }
}

@01231
Copy link

01231 commented May 13, 2022

@d-saravanan

how do i return a mapping or a array from a solidity function

This is a good pattern to follow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests