What is the reasoning in inheriting every class from
openzeppelin-eth even interfaces inherit from
Initializable. Not to mention classes without the
Wouldn’t it be better to remove inheritance from
Initializable in these classes?
Hey @ZumZoom! I don’t really know the answer to this so I’m gonna tag @spalladino to help you out!
I’m going to pass the ball to @frangio here, who is the lead of OpenZeppelin, but the reason is basically how Solidity linearizes the inheritance graph. If you didn’t add
Initializable to every contract, you may end up in situations (with multiple inheritance involved) where compilation would fail due to being unable to linearize the base classes (see here for an explanation of the problem).
@spalladino is correct, this is related to the linearization of the inheritance graph. But it’s not that if we don’t add
Initializable everywhere some contracts may not linearize. It’s that we want the linearization to be exactly the same in
openzeppelin-eth, not only of the contracts in OpenZeppelin but of any contracts that users build by extending them. This prevents headaches when users adapt a contract to be upgradeable, and guarantees that the tests and analyses performed on
openzeppelin-solidity carry over to
Initializable everywhere guarantees this will happen because of the way C3 linearization works. That is very complex to explain in detail in this post, but essentially if
Initializable is first in every list of parent contracts, it will end up first in the resulting linearized list, and the rest of the linearization will proceed as if
Initializable wasn’t there.
Compatibility of linearisations between
oz-solidity is a nice feature. That explains why it is required in contracts without
initialize method. But still why is it required in interfaces?
It may not be required in some places, but we added it everywhere to make it a straightforward mechanical process, to reduce the possibility of human error.