10

In OOP languages, composition over inheritance is a well-known best practice. Solidity is an OOP language too but there is also the gas efficiency issue.

Question is, in Solidity, how do composition and inheritance compare to each other considering respective gas costs?

P.S. Also asked in SO: https://stackoverflow.com/questions/52515714/composition-over-inheritance-in-solidity-gas-efficiency

1
  • I would also add the case of using library, which is a great way to save gas usages when you have multiple instances of the same contract code. Commented Oct 4, 2018 at 20:11

4 Answers 4

12
+50

We have two approaches:

Inheritance

contract Parent {
    string w;

    function Set(string _w) public {
        w = _w;
    }

    function Greet(string name) internal view returns(string) {
        return string(abi.encodePacked(w, name));
    }
}

contract Child is Parent {
    function Get() public view returns(string) {
        return Greet("Bob");
    }
}

Composition

contract Greeting {
    string w;

    function Set(string _w) public {
        w = _w;
    }

    function Greet(string name) public view returns(string) {
        return string(abi.encodePacked(w, name));
    }
}

contract User {
    address greeting;

    constructor(address _greeting) public {
        greeting = _greeting;
    }

    function Set(string w) public {
        Greeting(greeting).Set(w);
    }

    function Get() public view returns(string) {
        return Greeting(greeting).Greet("Bob");
    }
}

Results:

Inheritance

  • Deployment: 264164 gas (Child)
  • Execution: 42966 gas (Child.Set("Hello"))

Composition

  • Deployment: 266416 gas (Greeting) + 309393 gas (User) = 575809 gas
  • Execution: 45412 gas (User.Set("Hello"))
1
  • 4
    Just doing the last step of math here, these numbers say that in this case, composition was ~118% more expensive to deploy and 5% more expensive to call. These specific numbers will vary between contracts and functions, but in a general case, deploying more contracts will always be more expensive than deploying fewer, and calls within contracts will always be cheaper than calls across them.
    – ohsully
    Commented Oct 10, 2018 at 2:26
5

In a 1-1 comparison Composition is more expensive to deploy, and execute. That said, if you need to deploy many instances, you could use the Library pattern and use composition in that way.

Libraries can lower deployment costs if you're going to be deploying many copies of the same code. If you imagine deploying 100 copies of the same code, you may only have to deploy one Library, and then the more code you can push into the Library the cheaper each dependent contract deployment will be. But calling that library increases execution costs.

Another thing to consider with libraries: there are significant security concerns to shared libraries. The Parity hack which locked up funds was due to usage of composition.

Inheritance is a much simpler model and will always be cheaper to execute.

But, you will have to make the call as to what fits your use case. Will there be many versions of this contract? If so, will each instance be executed often enough to make up for deployment costs?

4

From the perspective of gas usage, composition will be more expensive, mainly because you will have more CALL opcodes and more contracts instantiations. See Appendix G Fee Schedules (G_call, G_create, G_callvalue, ...) in the yellow paper -> https://ethereum.github.io/yellowpaper/paper.pdf

1
  • I don't see any numbers here. I need data to justify my decisions.
    – ferit
    Commented Oct 9, 2018 at 9:02
0

Note that libraries which implement internal functions are in fact inlined i the contract that uses them. The gas savings from deploying contracts that have code in libraries will only occur when you make external library calls from the contract into the linked library. The linking step introduces an error surface, and there have been attacks based on the wrong library address having been used when deploying a contract linked to (lets say) an incorrect library address -- e.g., when you update the library code and someone accidentally references the old library address.

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.