ZeppelinOS proxy pattern and structs

Hi guys,

Anyone knows how zeppelin’s low level upgradable proxy pattern handles upgrading of contract library and structs? I couldn’t find much information around this in the documentations.

Hi @YumingHe, I found this blog entry very useful, it goes much into the technical details of how proxies work.

1 Like

thanks! I’ll check it out.

I’m using zeppelinos’s low level upgradability contracts (aka unstructured-storage pattern). I realize that for this pattern, all future logic contracts must inherit the storage variables declared by their ancestor versions due to the layout of storage variables in soldity. But my questions is on how will this rule be applied on complex structs and library logics? Are we able to append to variables in a struct? Will we be able to upgrade logics in an internal library of the contract?

The problem is storage collision, that occurs when storage in the proxy contract is overwritten by a new variable that does not respect storage hierarchy. To avoid this, your new statically-sized variables should be appended to the end of the storage.
I believe that if in your new contract you add a variable to a struct, whole new storage would be used. Because to find the starting position of the array data Keccak-256 hash computation would be used to find the starting position of the value or the array data.

That is what I think, but I’m really not sure. Maybe the best way to know is to play around.
Here more about storage collision.

2 Likes

Agree with @scammi here, the best way to be sure is to actually test it.

That said, adding fields to a struct will heavily depend on where you are actually using such structs. If you have a contract variable of the struct type, then you most likely won’t be able to add any fields (unless the variable is the last one on your contract). If the struct is contained in a mapping, then you probably will, since structs will be stored sparsely in storage.

Feel free to share your code here if that helps!

1 Like