2

I have a function that, according to the Unique ID of the car, gives me all its characteristics:

function getCarArray(uint _carId) 
        public 
        view 
        returns (uint[12] memory) 
    {
        CarData memory car = cars[_carId];

        uint[12] memory carInfo;

        carInfo[0] = car.statusEnd;
        carInfo[1] = car.number;
        carInfo[2] = car.load;
        carInfo[3] = car.capacity;
        carInfo[4] = car.region;
        carInfo[5] = car.status;
        carInfo[6] = car.abrasion;
        carInfo[7] = car.repairs;
        carInfo[8] = uint(car.currentOwner);
        carInfo[9] = uint(car.movingTo);
        carInfo[10] = car.resourceType;
        carInfo[11] = car.resourceAmount;

        return carInfo;
    }

When I call this method on the front end, in order to display all the cars and their characteristics, I have a very long time to process this whole. Suppose I have 1000 cars. I go through all the auto cycle

for(i=0;i<1000;i++){
     contractAddress.getCarArray(i)….
}

And then I get 1000 calls to the node, which results in a long time loading all the information.

That's the question - Is there any mechanism that will reduce the time to get all the available cars and information about them? Or on the front end side or on the Solidity side?

3 Answers 3

2

You could have a getCarsArray that returns an array of length 12*cars.length and populates all the cars' data in it. Also, if you use the v2 abi encoder, you can just return an array of structs I believe, which will be much cleaner to work with.

This will make it so you only have to wait for the response of 1 eth_call.

3
  • Thank you. They say that it is not necessary to use experimental features (Abi Encoder V2) on live deployments. ethereum.stackexchange.com/a/64566/44887 And you can read more explain how "returns an array of length 12*cars.length and populates all the cars' data in it"? Don't understand how to implement it
    – I. Simonov
    Feb 20, 2019 at 15:27
  • It's not recommended, no, but the ABIEncoderV2 has been usable and stable (also supported in the latest versions of web3.js) for over 6 months. We've been using it in production at totle.com. After further thought, I realized that you also can't return a dynamic array without the ABIEncoderV2, which would be required to return all cars, assuming the number of cars changes . You can instead do pagination to return the cars in large chunks (say 10 or 100) to cut down on eth_calls.
    – natewelch_
    Feb 20, 2019 at 15:33
  • I understand what you're talking about! But I don't understand how can I modify your code to return information about 10 cars in 1 function call getCarsArray
    – I. Simonov
    Feb 20, 2019 at 15:45
1

Solved my problem with this code

function getCarsInfo()
    public view
    returns (uint[] memory)
{   
    uint i;
    uint j = 0;
    uint carCount = 10; 
    uint[] memory carIdArray = new uint[](carCount);
    for (i = 0; i < carCount; i++){
        carIdArray[j] = i;
        j++;
    }

    uint lengthArray = carCount*12;
    uint[] memory allCarInfoBigArray = new uint[](lengthArray);
    i=0;
    for (j = 0; j < carIdArray.length; j++) {
        CarData memory car = cars[carIdArray[j]];

        allCarInfoBigArray[i] = car.statusEnd;
        allCarInfoBigArray[i+1] = car.number;
        allCarInfoBigArray[i+2] = car.load;
        allCarInfoBigArray[i+3] = car.capacity;
        allCarInfoBigArray[i+4] = car.region;
        allCarInfoBigArray[i+5] = car.status;
        allCarInfoBigArray[i+6] = car.abrasion;
        allCarInfoBigArray[i+7] = car.repairs;
        allCarInfoBigArray[i+8] = uint(car.currentOwner);
        allCarInfoBigArray[i+9] = uint(car.movingTo);
        allCarInfoBigArray[i+10] = car.resourceType;
        allCarInfoBigArray[i+11] = car.resourceAmount;
        i = i + 12;
    }
    return allCarInfoBigArray;
}

At the output I get an array in which all the parameters of each car are written in order

    allCarInfoBigArray = [
        1550702844,0,0,20,1,0,0,0,address,0,0,0,
        1550702849,1,0,20,1,0,0,0,address,0,0,0,
        1550702851,2,0,20,1,0,0,0,address,0,0,0
        1550702855,3,0,20,1,0,0,0,address,0,0,0
        1550702860,4,0,20,1,0,0,0,address,0,0,0
        1550702865,5,0,20,1,0,0,0,address,0,0,0
        1550702870,6,0,20,1,0,0,0,address,0,0,0
        1550702875,7,0,20,1,0,0,0,address,0,0,0
        1550702880,8,0,20,1,0,0,0,address,0,0,0
        1550702885,9,0,20,1,0,0,0,address,0,0,0]
0

The fastest way to do this would be to create your own block explorer that stores relevant data in a DB. Your front end would read the data from.the DB (as opposed to the blockchain).

To do this, you would create a worker that watches for changes on your contract. It would store the relevant changes in your off-chain database, and index relevant items. The front end can read the values from the database much quicker than from.the distributed network.

Your Answer

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

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