@@ -34,6 +34,110 @@ by the above rules, state variables from different contracts do share the same s
3434The elements of structs and arrays are stored after each other, just as if they were given
3535as individual values.
3636
37+ If a contract specifies a :ref: `custom storage layout<custom-storage-layout> `, the slots assigned
38+ to static storage variables are shifted according the value defined as the layout base.
39+ Locations of dynamic arrays and mappings are also indirectly affected by this due to shifting
40+ of the static slots they are based on.
41+ The custom layout is specified in the most derived contract and, following the order explained
42+ above, starting from the most base-ward contract's variables, all storage slots are adjusted.
43+
44+ In the following example, contract ``C `` inherits from contracts ``A `` and ``B `` and also
45+ specifies a custom storage base slot.
46+ The result is that all storage variable slots of the inheritance tree are adjusted according to
47+ the value specified by ``C ``.
48+
49+ .. code-block :: solidity
50+
51+ // SPDX-License-Identifier: GPL-3.0
52+ pragma solidity ^0.8.29;
53+
54+ struct S {
55+ int32 x;
56+ bool y;
57+ }
58+
59+ contract A {
60+ uint a;
61+ uint128 transient b;
62+ uint constant c = 10;
63+ uint immutable d = 12;
64+ }
65+
66+ contract B {
67+ uint8[] e;
68+ mapping(uint => S) f;
69+ uint16 g;
70+ uint16 h;
71+ bytes16 transient i;
72+ S s;
73+ int8 k;
74+ }
75+
76+ contract C is A, B layout at 42 {
77+ bytes21 l;
78+ uint8[10] m;
79+ bytes5[8] n;
80+ bytes5 o;
81+ }
82+
83+ In the example, the storage layout starts with the inherited
84+ state variable ``a `` stored directly inside the base slot (slot ``42 ``).
85+ Transient, constant and immutable variables are stored in separate
86+ locations, and thus, ``b ``, ``i ``, ``c `` and ``d `` have no effect on the storage layout.
87+ Then we get to the dynamic array ``e `` and mapping ``f ``.
88+ They both reserve a whole slot whose address will be used to :ref: `calculate<storage-hashed-encoding> `
89+ the location where their data is actually stored.
90+ The slot cannot be shared with any other variable, because the resulting addresses must be unique.
91+ The next two variables, ``g `` and ``h ``, need 2 bytes each and can be packed together into
92+ slot ``45 ``, at offsets ``0 `` and ``2 `` respectively.
93+ Since ``s `` is a struct, its two members are packed contiguously, each taking up 5 bytes.
94+ Even though they both would still fit in slot ``45 ``, structs and arrays always start a new slot.
95+ Therefore, ``s `` is placed in slot ``46 `` and the next variable, ``k ``, in slot ``47 ``.
96+ Base contracts, on the other hand, can share slots with derived ones, so ``l `` does not require an new one.
97+ Then variable ``m ``, which is an array of 10 items, gets into slot ``48 `` and takes up 10 bytes.
98+ ``n `` is an array as well, but due to the size of its items, cannot fill its first slot perfectly
99+ and spills over to the next one.
100+ Finally, variable ``o `` ends up in slot ``51 ``, even though it is of the same type as items of ``n ``.
101+ As explained before, variables after structs and arrays always start a new slot.
102+
103+ Putting it all together, the storage and transient storage layouts of contract ``C `` can be illustrated as follows:
104+
105+ - Storage:
106+ ::
107+
108+ 42 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
109+ 43 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee]
110+ 44 [ffffffffffffffffffffffffffffffff]
111+ 45 [ hhgg]
112+ 46 [ yxxxx]
113+ 47 [ lllllllllllllllllllllk]
114+ 48 [ mmmmmmmmmm]
115+ 49 [ nnnnnnnnnnnnnnnnnnnnnnnnnnnnnn]
116+ 50 [ nnnnnnnnnn]
117+ 51 [ ooooo]
118+
119+ - Transient storage:
120+ ::
121+
122+ 00 [iiiiiiiiiiiiiiiibbbbbbbbbbbbbbbb]
123+
124+ Note that the storage specifier affects ``A `` and ``B `` only as a part of ``C ``'s inheritance hierarchy.
125+ When deployed independently, their storage starts at ``0 ``:
126+
127+ - Storage layout of ``A ``:
128+ ::
129+
130+ 00 [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
131+
132+ - Storage layout of ``B ``:
133+ ::
134+
135+ 00 [eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee]
136+ 01 [ffffffffffffffffffffffffffffffff]
137+ 02 [ hhgg]
138+ 03 [ yxxxx]
139+ 04 [ k]
140+
37141.. warning ::
38142 When using elements that are smaller than 32 bytes, your contract's gas usage may be higher.
39143 This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller
@@ -463,4 +567,4 @@ Transient Storage Layout
463567 "numberOfBytes" : " 32"
464568 }
465569 }
466- }
570+ }
0 commit comments