1

I need to iterate through a mapping in one of my contracts to return the list of all owners of a particular NFT. In fact, it is a mapping inside of another mapping.

    mapping(uint256 => uint256) public numberOfOwners;
    mapping(uint256 => mapping(uint256 => address)) public listOwners;

    /* get list of owners */
    function getOwners(uint256 _id) public view returns (address[] memory) {
        address[] memory owners = new address[](numberOfOwners[_id]);
        for (uint256 i = 0; i < numberOfOwners[_id]; i++) {
            owners[i] = listOwners[_id][i];
        }
        return owners;
    }

That is a pretty inefficient code and I want to optimize it. Due to the expensive SLOAD and SSTORE opcodes, managing a variable in storage is much more expensive than managing variables in memory.

Does anyone have any idea (and how to implement it) about how to optimize the code above? Probably creating a temporary variable inside of the function like the variable owners and iterate through a memory element.

1 Answer 1

0

A few ideas:

  1. When uint256 is created it has a default value of 0, so no need to set it to 0 again just use uint256 i;....
  2. since i can't be overflown, you can use unchecked {++i} which is cheaper than normal i++ (++i costs 5 gas less than i++)
  3. If possible use private instead of public mappings (since there's no getter they are cheaper to instantiate)
  4. Maybe another idea would be to call the function off-chain. Since its a view function it will cost you no gas and then use data in a separate non-view call.
1

Your Answer

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

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