October 9, 2022
Multiple Inheritance in Solidity
There are lots of documentation about C3 and so on, but I feel that example is better. Jump with me, it won't take long.
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; abstract contract A { event E(int); function Hello() external virtual; function Hello2() external virtual; } contract B is A { function Hello() public override virtual { emit E(2); } function Hello2() public override virtual { emit E(2); } } contract C is A { function Hello() public override virtual { emit E(3); } function Hello2() public override virtual { emit E(3); } } contract D is B, C { function Hello() public override(B, C) { super.Hello(); } function Hello2() public override(C, B) { super.Hello2(); } } contract D2 is C, B { function Hello() public override(B, C) { super.Hello(); } function Hello2() public override(C, B) { super.Hello2(); } } contract D3 is C, B { function Hello() public override(B, C) { B.Hello(); C.Hello(); } function Hello2() public override(C, B) { C.Hello2(); B.Hello2(); } }
And results (printing events):
D.Hello ["0x0000000000000000000000000000000000000000000000000000000000000003"] D.Hello2 ["0x0000000000000000000000000000000000000000000000000000000000000003"] D2.Hello ["0x0000000000000000000000000000000000000000000000000000000000000002"] D2.Hello2 ["0x0000000000000000000000000000000000000000000000000000000000000002"] D3.Hello ["0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000003"] D3.Hello2 ["0x0000000000000000000000000000000000000000000000000000000000000003","0x0000000000000000000000000000000000000000000000000000000000000002"]
If you are familiar with Python, this is confusing, as in Python super() traverses the whole hierarcy:
class A: def Hello(self): print("A") class B(A): def Hello(self): print("B") super().Hello() class C(A): def Hello(self): print("C") super().Hello() class D(B,C): def Hello(self): print("D") super().Hello() class D2(C,B): def Hello(self): print("D2") super().Hello() D().Hello() D2().Hello()
D B C A D2 C B A