4

i'm new to solidity and trying to understand the better storage option for the factory contract. i want:

  1. to be able to get all deployed contracts.
  2. to be able to get all deployed contracts by creator

The option i see is to create an array to track all contracts and mapping to reference the creators, ex:

contract CampaignFactory {

    Campaign[] campaigns;
    mapping(address => Campaign[]) campaignsByOwner;

    function createCampaign(uint min_contrib) public {
        Campaign newCampaign = new Campaign(min_contrib, msg.sender);
        campaignsByOwner[msg.sender].push(newCampaign);
        campaigns.push(newCampaign);
    }

    function getAllCampaigns() public view returns (Campaign[] memory) {
        return campaigns;
    }

    function getCampaignByAddress(address creator) public view returns (Campaign[] memory) {
        return campaignsByOwner[creator];
    }
}

alternatively, i could use a struct like:

struct CampaignDeployed() {
    address creator;
    address[] campaigns;
}

but in that case as i understand, to get a campaigns by owner i will have to iterate over all in for cycle, which is something possibly too expensive (?).

So, the questions is, what is the typical approach to tackle such problem? does the solution with array + mapping acceptable?

2

Your solution is good, but if the arrays get too big, you may not be able to return them all at once. Different nodes impose different limits, but there's often a timeout and a maximum allowed payload on calls to view functions.

You may be interested in pagination (specifically the "paging through an array" section): https://programtheblockchain.com/posts/2018/04/20/storage-patterns-pagination/.

1

Check this simple storage patterns in Solidity. It talks about pros/cons using different combinations of data structures.

In may opinion, it depends on your needs. For example, can the need "to be able to get all deployed contracts" be solved by calling externally getCampaignByAddress() multiple times? It would involve multiple smart contract calls and the knowledge about all addresses with at least a campaign, but may save your support array data struct.

I struggled a lot about this issue before, hope my contribution helps.

  • it is possible to get all the data by calling getCampaignByAddress() theoretically, but practically there will be to much constraints to use it - all the creator addresses not always available when this call need to be made for example. Thanks for list, seen that. – user1935987 Dec 19 '18 at 21:34

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.