0

If I need to access a large array from my contract... say for my front end. Should I be using external to make it cheaper for myself?

A comment by William Entriken on this question is what got me thinking about this: https://ethereum.stackexchange.com/a/19391/40675

What might be the limitations with this if it is a good idea in terms of fixed vs dynamic array?

3

The issue with reading large arrays is that if takes too much time (depends on the node's settings), the call will fail and you won't get any data.

In order to read large arrays, the safest way is to use a pagination pattern. It's exactly like memory pagination used in every computer, instead of cutting the memory in pages, we cut our array (which is in memory too ;) ).

Here's a very simple example to illustrate how pagination works :

contract Contract {
    uint[] public large_array;

    function read(uint cursor, uint length) public view returns (uint[] memory) {
        uint[] memory array = new uint[](length);
        for (uint i = cursor; i < cursor+length; i++) {
            array[i] = large_array[i];
        }
        return array;
    }
}

You can read more on the link above, which uses safer methods for reading.

Edit

As Lauri wrote, if your function doesn't modify the state of your contract, you can mark it as view so calling it will be free, with the exception of calling it within a smart contract.

  • Hi @Eli, thanks so much for the reply! This pattern is very useful I really want to try it out! But I am interested in learning about the functionality of external with this question. Let's say a huge array of pixels for the most wasteful way to use an array on EVM: a large picture. The combination of calling, concat, and rendering everything exceeds the avg block time and just isn't fast enough. So I want to pay for a call to return it all at once (I haven't tried this but as far as I know it should work). The question remains should I add external to this function to make it cheaper? – Duncan Brain May 10 at 12:29
  • 1
    Since you are reading, you don't care about the gas cost (except if it might reach the block gaslimit). Using external will only make the call marginally cheaper (I think), since the parameters in read are just two unsigned integers. – Eli Drion May 10 at 12:35
  • Yeah, that's a really useful thought, I have had to consider the gas limit reading my arrays. My first blockchain DApp project was this: ourplace.io, which is basically a big canvas. I think if I were to do it again the pagination would work well, but I think external could possibly increase my limit as is(currently around bytes9[1000000] works using infura). The reason I was considering making transactions was because I understood it to be the only way to read variable sized arrays. For some reason I was under impression you can't do much with view functions other than return state variables. – Duncan Brain May 11 at 1:11
1

Just to add to @Eli's answer: you don't need to worry about gas costs as you are only performing a read operation. Just mark your function as view and issue a call instead of a transaction - the data is then read directly from the node you use and the blockchain is not consulted at all. All calls are free.

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.