0

I wonder the exact mechanism of copying code that involves "super" keyword for supporting inheritance in Solidity.

Below is an example code that elaborates my question.

contract C { 
    function test() public {  } 
}

contract B is C {
    function bbb() public {  }
    function test() public {
       bbb(); 
       super.test(); 
    }
} 

contract A is B {
}

If we deploy the contract A and calls the function A.test(), then the actual (and desirable) effect is a call sequence of bbb()->C.test() (where super is replaced with C).

However, literally following the below explanation on inheritance in Solidity docs

the code from all the base contracts is copied into the created contract.

may produce undesirable behaviors. For clarification, let me perform the copy process for the example code above:

contract C { 
    function test() public {  } 
}

contract B is C {
    function bbb() public {  }
    function test() public {
       bbb(); 
       super.test(); 
    }
} 

contract A is B {
    function bbb() public {  }
    function test() public {
       bbb(); 
       super.test(); 
    }
}

Again, if we deploy A and calls A.test(), then we have a call sequence of bbb() -> B.test() -> bbb() -> C.test(), where the supers in A and B are replaced by B and C, respectively.

Do I have any missing point?

  • A.test() -> A.bbb() -> B.test() -> B.bbb() -> C.test(); You can test it out by emitting events in each of them and running in remix. – Micky Socaci Nov 5 '18 at 2:45
  • @MickySocaci Before performing the copy, we only have a sequence of bbb -> C.test(). You may have tested the code after copied. – Sunbeom So Nov 5 '18 at 2:51
0

Inheritance will not "copy" inherited methods instead once a contract is compiled there will be a single contract containing all methods from the base contracts.

For example if we start with

contract C { 
    function test() public { log0(0x1111); } 
}

contract B is C {
    function bbb() public { log0(0xbbbb); }
    function test() public {
       bbb(); 
       super.test(); 
    }
} 

contract A is B {
}

The compiled contract will look like

contract A_compiled {
    function test_internal() private { log0(0x1111); } 
    function bbb() public { log0(0xbbbb); }
    function test() public {
       bbb(); 
       test_internal(); 
    }
}
  • Can you please explain more about the mechanical process of how the super.test in B is changed into test_internal ? Did you refer to any documentation? I really want to know the exact mechanism, but I was not able to find relevant materials. – Sunbeom So Nov 6 '18 at 0:58
  • @SunbeomSo You have to understand that in Solidy inheritance is resolved at compile time. The result of compilation is a single bytecode. All contracts are merged together, to resolve which methods will appears it uses C3 linearization. – Ismael Nov 6 '18 at 4:00
  • Yes I know, but my curious point was that the process of "how they are merged". For example, the contracts should not be merged in a way that I described in my original question. Instead, the contracts should be merged in a way that you examplified. But what is the exact process of merging? (e.g., how is super.test in B converted into test_internal before merged into A? – Sunbeom So Nov 6 '18 at 12:22
  • @SunbeomSo Sorry, but I can't help you there. The specifics are in the solidity compiler source code, that I'm not familiar with. – Ismael Nov 6 '18 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.