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?

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.

  • 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 '18 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 '18 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 '18 at 11:37
  • Other than that, it's of course not possible yet to return dynamically sized data yet. – Nikita Fuchs Jul 23 '18 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, privacy policy and cookie policy

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