28

Let`s say I need to store and manipulate collection of complex data in the smart contract. There maybe complex rules defining who and how can change an item. There maybe be several millions of items in the collection.

There are 2 ways how that logic can be implemented

  1. Using child contract:
contract DataItem {
    bytes32 key;
    string value;

    function DataItem(bytes32 k, string v) {
        key = k;
        value = v;
    }
}
contract DAppInterface {
    mapping(bytes32 => address) public dataItems;

    function addDataItem(bytes32 k, string v) external {
        dataItems[k] = new DataItem(k, v);
    }
}
  1. Using struct:
contract DAppInterface {

    struct DataItem {
        bytes32 key;
        string value;
    }

    mapping(bytes32 => DataItem) public dataItems;

    function addDataItem(bytes32 k, string v) external {
        dataItems[k].key = k;
        dataItems[k].value = v;
    }
}

What is advantage of using one vs another approach? What are the guidelines for picking one vs another?

1 Answer 1

30

Under most circumstances, data structures, even complicated ones, should be structs.

Here are some reasons to choose structs:

  • Contracts are more expensive. You'll have to pay for the contract's creation initially, and every time you access it, you'll need to pay for a call to another contracts. This is much, much more expensive than a sha3 for a lookup inside the contract's own storage.
  • Contracts must replicate code. Every contract must contain the logic for setting and altering values, which you must pay for in gas. A struct needs only set of functions.
  • Contracts are exposed. Anyone can send a message to a contract. If you use a contract for storing data structures, you'll have to manage access manually.
  • Libraries might be what you're actually looking for. If you find yourself looking for functions on a data structure (i.e. foo.bar()), you can use a library contract to do it without the additional complexity of creating contracts for every instance.

Here are some reasons where contracts would be superior:

  • Contracts can be polymorphic. A contract could potentially contain arbitrary code. This allows multiple types to be intermingled, or even to have users bring their own logic.
  • The logic will be split. In this registrar contract each Deed could have been a struct. By making Deeds their own contracts, there is less of an attack surface for the Deeds themselves, reducing the chance of another TheDAO-scale disaster.
  • Contracts are exposed. If users have to configure their data structures, having a unique address they can interface with directly may prove simpler.
  • Contracts are contracts. A child contract can do anything a contract can do. If the data structures, for some reason, would own things as an address would, then having a contract would be far superior. A contract can directly hold Ether, as opposed to a struct sharing the main contract's balance with other structs.

However, these are less common. My advice: try it with structs first, and use data structure contracts as a last resort.

3
  • Is number of transactions and amount of data stored in the contract may affect the decision to use child contract or struct? Let say I have auction DApp where every item for sale would have a number of transactions related to it (bids, payment, shipping info added, etc). That DApp can be implemented with structs and a single contract. But in that case there will be a lot of transactions executing concurrently against that contract and storage for that contract will grow really fast. Child contract would allow isolate transactions and storage for sold item. Commented Sep 13, 2016 at 4:41
  • 1
    In the current version Ethereum, there's no concurrent transactions (this is projected to change). Whether it's one contract or several, transactions still happen one at a time. Similarly, the same amount is stored whether in the same contract or multiple (overhead aside). After a certain level of complexity, individual contract starts to make sense. If each auction is its own contract, you'll have a much easier time working with the balances of users, for example. Commented Sep 13, 2016 at 16:49
  • What to know if using child contract going to be better in upgradability? Since data structure layout is not fixed to a single contract we could upgrade anything
    – kitta
    Commented Oct 24, 2021 at 3:49

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.