1

I'm trying to return a dynamic array of structures from a Solidity function to a client. Since I need to build the result, I'm declaring a storage variable and add elements to it:

function conversations(address user) public view returns (Conversation[]){
    Conversation[] userConversations;
    userConversations.push(conversations[0]);
    return userConversations;
}

However, I keep getting an out of gas exception in my Truffle tests. How can it run out of gas when it's a view function? I understand that userConversations is a storage variable (or I won't be able to execute push on it), but does it really modify the state of the contract? If it does, how do you rewrite it so that you can get a dynamic array?

1

2 Answers 2

0

userConversations.push(conversations[0]);

definitely modifies the state, so this cannot be used in a view function. You basically need to write a getter function to this setter function or make userConversations public, in that case it will get a getter function automatically.

4
  • userConversations is a temp variable created just to build up an array to return. Also, a getter for an array cannot return this array -- it's a function that requires an index and returns an element of this array. Am I right?
    – ulu
    Jul 23, 2018 at 11:22
  • When I try to return a field which is a dynamic array, it says ` Error: invalid solidity type!: tuple[]`
    – ulu
    Jul 23, 2018 at 11:27
  • 1
    You can't return struct as of now, it's available only in experimental version. I'm wondering why compiler won't throw error. Edit: also i think userConversations actually is being written to storage, as it doesn't have memory keyword.
    – Maxpeinas
    Jul 23, 2018 at 11:37
  • Other than that, it's of course not possible yet to return dynamically sized data yet.
    – n1cK
    Jul 23, 2018 at 22:31
4

You get an out of gas because your Conversation[] userConversations; that you believe is in memory is actually on storage.

Try to change it to Conversation[] memory userConversations; and you will see that it no longer compiles because .push is not available on memory arrays.

How about you try that:


function getConversations() public view returns (Conversation [] userConversations) {
    uint length = conversations.length;
    userConversations = new Conversation[](length);
    for (uint i = 0; i < length; i++) {
        userConversations[i] = conversations[i];
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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