I'm a bit puzzled about multiple inheritance and providing arguments for different constructors. Solidity documentation has long explanations about this (http://solidity.readthedocs.io/en/develop/contracts.html#arguments-for-base-constructors) but (in my opinion) not enough information about base contracts' arguments. It states:
If the base constructors have arguments, derived contracts need to specify all of them
How does this exactly work when there is a complicated inheritance chart? An example:
pragma solidity ^0.4.0;
contract A {
constructor(uint paramA) public {
}
}
contract B is A {
constructor(address paramB) public {
}
}
contract C is A {
constructor(string paramC) public {
}
}
contract D is B, C {
constructor(uint paramForA, address paramForB, string paramForC) public // stuff here to call A, B and C constructors with non-static parameters
{
}
}
How should contract D
specify its constructor arguments for contracts A
B
and C
to provide all required parameters and in what order? Is there only one correct order?
Best Answer
In Solidity you specify base constructor arguments in two ways (according to http://solidity.readthedocs.io/en/latest/contracts.html#arguments-for-base-constructors):
Your inheritance structure is as follows: D->C->B->A.
If we change the order a little bit (just to be sure that constructor executions are different than the code sequence) and add some logging we get:
You get the following execution od constructors: A->B->C->D
Note that if you change the order of inheritance and rewrite D as follows:
You will get different order of execution A->C->B->D
So the order does matter.
EDIT1: As the above was not exactly to the point below I try to address question: "How should contract D specify its constructor arguments for contracts A B and C to provide all required parameters and in what order? Is there only one correct order?"directly.
You can assign parameters to parent contract constructors in two ways:
1. Directly in the declaration of inheritance:
where 0x0b and 0x0a are address literals.
2. Via assigning them using syntax similar to Solidity modifiers if you want to use constructor D arguments:
There is not other way to initialize parent contract constructors that I'm aware of. If you would like to initialize state variables of parent contract you can make it within the D constructor. Those state variables has to be either public or internal in the parent contract. Hope this helps.