In a simple solidity contract, without inheritance, storage variables get assigned sequentially starting from slot 0.
But in case of inheritance, the inherited variables appear before or afterwards?
The assignment is as follows: first to the inherited variables, from the leftmost contract to the rightmost, finishing with the current contract you're in.
In the following example C
inherits from Base
and Base2
, in that order. The slot assignment will start from Base
, following Base2
, and finally C
.
pragma solidity ^0.5;
contract Base {
uint256 basevar = 0;
constructor() public {
basevar = 1;
}
}
contract Base2 {
uint256 basevar2 = 2;
constructor() public {
basevar2 = 1;
}
}
contract C is Base, Base2 {
uint256 cvar = 0;
function getCvar() public view returns(uint256) {
return cvar;
}
function getBasevar () public view returns(uint256) {
return basevar;
}
}
basevar
gets assigned slot 0,
basevar2
gets assigned slot 1,
and cvar
gets assigned slot 2.
I had done some extensive testing so I wanted to add another answer to clarify things.
Simple Example:
contract A is B, C, D {}
The Storage will be arranged like this:
Storage B;
Storage C;
Storage D;
Storage A;
Now, if you want to Add E
to your already written contract (And not cause memory collisions), this is how you go about doing it.
NOTE: A2
should be an empty contract, so it takes no slots. (Just in case), and thus can be ignored as it will have no storage.
Contract A2 is A, E { }
The storage will be arranged like this:
Storage B;
Storage C;
Storage D;
Storage A;
Storage E;
This will make it safe to upgrade.
If you do it the opposite way:
Contract A2 is E, A { }
E
will be set on the top, and you will mess up the order of your storage slots.
Storage E;
Storage B;
Storage C;
Storage D;
Storage A;