-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document the resiliency of storage usage #5293
Comments
This has been part of the documentation for a very long time: https://solidity.readthedocs.io/en/v0.4.25/miscellaneous.html#layout-of-state-variables-in-storage There is a pending pull request to improve the specification: #5023 There is also a pending PR to extract the storage layout from the compiler (don't remember the number for now). We could add to the documentation that this layout is considered to be part of the API, although in my opinion, it is obvious that any change there would be a breaking change because of the way library calls work. |
Thank you for the reference, I totally missed that. And to be honest, I'm embarrassed, I should have asked on SO first. Now that I am reading it, "starting from position 0" could be stronger. Does this mean that all inherits come before inheriting contracts? I am assuming this would be a depth-first search of dependencies based on the order of inheritance declared. |
The storage is laid out according to the C3-linearized order of contracts starting with the most base-ward contract. One issue to document is whether state variables from different contracts can share a storage slot - that should be checked. Would you like to add that to the documentation? |
I have stolen your nugget and another into
Can you please explain "whether state variables from different contracts can share a storage slot". If referring to two inherited contracts of the same inheriting contract, then yes this is a tautology. Yes, as soon as you have two arrays they will share storage because, theoretically, keccak256 could collide. Or if you are asking "does EVM isolate storage for each account or are we just lucky that there are no collisions?" Then answer is "they are isolated" as per the Yellow Paper section 4.1 -- the world state is a mapping of accounts to state and therefore the states are isolated. |
I took the liberty to modify your PR a little to answer the request above. |
Cool, thank you |
Production applications are using upgradeable contract patterns. This includes some models where storage for one contract is shared between multiple logical implementations (
DELEGATECALL
).A critical assumption of these implementations is that the storage "API" for Solidity is the same between any Solidity versions as long as the variable name is the same.
Example:
Deployment strategy:
Proxy
,Version1
andVersion2
Proxy
to delegate toVersion1
backend implementationProxy
to delegate toVersion2
Test case:
meaningOfLife
onProxy
Expected outcome:
Version2
implementation accesses the same storage thatVersion1
did in the same wayActual outcome:
Work plan
Discussion
A naive person might think you just sha3(variableName, [class::functionName]) to choose the storage location. If that is the case then we need to document what happen for two contracts that share the same private variable name.
A naive person might think you just sha3(contractName, [functionName,] variableName). This means that contract names are significant to byte code compilation. This would be surprising.
In both cases, this is related to the contract inheritance model because we are considering how private variables will work and if names can be reused.
REFERENCE: #3729
The text was updated successfully, but these errors were encountered: