2

I have a smart contract written, which stores a file ID alongwith its description.

struct AllFiles
 {

    string fileDesc;        //Description of a file
    uint fileId;            //Corresponding file ID
}

This is mapped to a uint value, which basically corresponds to the file ID here, as

mapping (uint =>AllFiles) public allFiles;

I want to return all the contents of this mapping just like we return the entire structure array in OOP. Is there any way to do that in Solidity? I read it somewhere long back (can't find the resource now) that arrays can't be returned. But since this is a mapping, I wonder if it is possible.

2 Answers2

2

@bumi says some useful things about mappings. The for loop jumps out as an anti-pattern because this will stop working when there are too many files.

You can make a scalable solution by pushing iteration to clients. Clients ask for rows one by one so each call to the contract is consistent in gas cost. Some ideas over here: Are there well-solved and simple storage patterns for Solidity?

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
1

mappings are not iterable. see: mapping type documentation but you can build the iteration on top of it, for example: iterable_mapping.sol (which is a good inspiration)

IF your uint key is reliably incremented you could store something like a filesCount and use that in a for iteration. something like (pseudo code):

contract Files {
    struct AllFiles{
        string fileDesc;        //Description of a file
        uint fileId;            //Corresponding file ID
    }
    uint filesCount;

    mapping (uint =>AllFiles) public allFiles;

    function addFile(string _desc) {
        uint id = filesCount+1;
        allFiles[id] = AllFiles({fileDesc: _desc, fileId: id});
    }

    function iterate() {
        for(uint256 i = 1; i<=filesCount; i++) {
            allFiles[i];
        }

    }
}

Or you keep an array with the ids and iterate similarly over that one.

hope that helps

bumi
  • 348
  • 1
  • 2
  • 9