Returning Struct Array in solidity

Viewed 7354

This is my contract code. Here I'm trying to store the coordinates of a particular trip. While storing the information contract executing fine. But When I retrieve the data, It should give the array of coordinates. But it is throwing an error.

reason: 'insufficient data for uint256 type'

contract TripHistory {
       struct Trip {
           string lat;
           string lon;
       }
        mapping(string => Trip[]) trips;

        function getTrip(string _trip_id) public view returns (Trip[]) {
            return trips[_trip_id];
        }
        function storeTrip(string _trip_id, string _lat, string _lon) public  {
           trips[_trip_id].push(Trip(_lat, _lon));
        }

}

What I'm missing here. Is there any other way to achieve what I'm trying here?

P.S: I'm new to solidity.

3 Answers

First of returning structs is not supported in Solidity directly. Instead you need to return every individual element in the struct as below.

Function xyz(uint256 _value) returns(uint256 User.x, uint256 User.y)
public {}

But then there’s an experimental feature that will help you with returning struct. All that you need to do is add the following after your first pragma line

pragma experimental ABIEncoderV2;

then continue with your code. That should work with no changes to your code.

An example of abiencoderv2 returning struct can be found at this link

It is not possible in solidity to return struct array.

As jlo said in this link, after version 0.8.0, it is possible to return a struct. jlo describes how to set and return an element of array of struct. Here I describe how to set, reset, and return a struct type variable.

I tested it and my test environment is:

  1. private Ethereum network
  2. Geth version 1.10.9-stable (for private network)
  3. Slocjs Compiler version 0.8.7
  4. web3js version 1.5.1

Note, you have to first define the struct type outside of any function inside the contract.

A supper intuitive example code is as follows:

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
    
contract testContract {


    struct funcResultType {
        uint[] var1;
        string[] var2;
        string message;
    }

    funcResultType private funcResult;


    function testSetFunc(string memory inputVar) public payable {
        funcResult.var1.push(123);
        funcResult.var2.push(inputVar);
        funcResult.message = "Done!";
    }

    function testResetFunc() public payable {
        delete funcResult; // reset variales
    }

    function testGetFunc() public view returns (funcResultType memory){
        return funcResult;
    }
}

The result of the test with Web3js in the console is as follow:

enter image description here

As you can see the whole variables are accessible. I upload its web3js code in Github in this link.

Related