[Ethereum] Best practices to solve the problem of a contract that is too large

contract-developmentsolidity

My contract is too large to deploy (gas cost) and I can't remove any functionality from it, so I need to split it up into two contracts that interact with each other. The first contract will be the only one the users interact with and the second one will throw any calls to it that are not from the first contract.

However, in my attempts at doing this, I've wrestled with how I should split up my variables and code between the contracts.

  • Q1: Is there a standard architecture/technique for doing this? How would you go about it?

Also, some questions:

  • Q2: Do mappings and arrays have automatic accessor functions? What about
    mixtures of mapping and array?If so, what is the syntax for these?

  • Q3: What are the gas concerns related to splitting up a contract in this
    way?

Best Answer

For Q1: Assuming your contract is too large because you have complex data structures in it and therefore complex business logic to manipulate them, my approach has been to review the data model and consider some of these data structures to be contract themselves. For instance, your main contract holds a mapping of structure that contains array. If it is functionally relevant consider converting the structure into a contract and defining some business logic into this contract. In other words, try defining your object model by creating different contract for elements that have independent or different life cycles.

Q2: Rob already answered to this. I will just add that mapping and array automatic getter do not provide a length function. And mapping cannot be iterated over if you do not have already the list of keys.

Q3: here it depends if you can break your business logic to manipulate your data structure independently. From a gas perspective the more straightforward the VM process is the lower the gas will be. Also, with complex data structure one can assume searching in arrays, mapping, sorting and remapping that have a tendency of being loop intensive. So structure your internal data so you have a way to speed up the algorithms. For instance, i needed a sorted list of dates, i built it in a way that the inserting function keep it sorted. Another example is to delegate to the external caller more work to do, ie more separate transactions when possible. Update attributes of a contract in different calls versus one single call will all values.

Good luck and share your findings

Related Topic