Anyone used the "proxy" pattern to write upgradable smart contracts? I am planning to upgrade/extend my old smart contract, originally, my code looks like this:
mapping(address => uint256) balance;
I am planning to write it like this:
struct PackedBalance {
uint256 balance;
uint256 locked_balance; // to support a new feature.
}
mapping(address => PackedBalance) balance;
My concern is if the "storage" is compatible to the "old version smart contract".
I just read the "Layout of State Variables in Storage". As I understand it, it is compatible. But I am a newbie, so I would like to seek help from some experts.
"compatible" means: I can still read correct "balance" of the existing storage slots. And I can write "locked_balance" without breaking anything(like overwritten).
Yes, it's safe to expand the uint256
within a mapping to the struct
within the same mapping.
Lets debug these two example contracts:
pragma solidity ^0.8;
contract MyContract {
mapping(address => uint256) balance;
function setBalanceForAddress(address _address, uint256 _balance) external {
balance[_address] = _balance;
}
}
pragma solidity ^0.8;
contract MyContract {
struct PackedBalance {
uint256 balance;
uint256 locked_balance;
}
mapping(address => PackedBalance) balance;
function setBalanceForAddress(address _address, uint256 _balance, uint256 _lockedBalance) external {
balance[_address] = PackedBalance(_balance, _lockedBalance);
}
}
The address
is always going to be 0x1231231231231231231231231231231231231231
(for debugging purposes).
The first contract stores the uint256
field to storage slot 0xf100689cc6bb188feb3c0ef4658bee6e8042e58e79daebcd84870d7f336a8422
Tx data:
0x4fa1007300000000000000000000000012312312312312312312312312312312312312310000000000000000000000000000000000000000000000000000000000000064
Remix debugger screenshot:
The second contract stores the struct
to slots 0xf100689cc6bb188feb3c0ef4658bee6e8042e58e79daebcd84870d7f336a8422
(same as the first contract) and 0xf100689cc6bb188feb3c0ef4658bee6e8042e58e79daebcd84870d7f336a8423
(right next to it).
Tx data:
0x6f7223d9000000000000000000000000123123123123123123123123123123123123123100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000064
Remix debugger screenshot: