Hello,
I have a quick question. Can i change a private variable to public when upgrading a contract?
Hello,
I have a quick question. Can i change a private variable to public when upgrading a contract?
Hey, happy new year!
Yes, I think so, maybe later I can have a test to confirm.
Cause I think all variables in the contract can be got, just with different levels of difficulty. For public and external, you can get them from the contract directly, but for the private and internal, you should use another way, such as by the method web3.eth.getStorageAt in the web3.js
Hi @Dellybro,
I assume visibility has no impact on how state variables are stored. As long as you are not changing type or order of state variables this should be fine, though I recommend (as @Skyge said) trying it out yourself.
@skyge do you think the same would be for adding “override”?
Could you please show your code?
Hi @Dellybro,
The keyword override applies to functions, and not state variables: https://docs.soliditylang.org/en/v0.8.0/contracts.html?highlight=override#function-overriding
So we are using this variable in another contract, so we use the override keyword so it “implements” it’s interface
https://docs.soliditylang.org/en/v0.5.3/contracts.html#visibility-and-getters
Hi @Dellybro,
I am still not sure what you mean. Can you give a simple example. Something like the following?
// contracts/A.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.5.0;
contract A {
uint256 public value;
}
// contracts/B.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.5.0;
import "./A.sol";
contract B is A {
uint256 public value;
}
Hi @Dellybro,
Is this what you were referring to: Is public state var auto getter override upgrade safe? - #2 by Skyge
I have a similar cuestion using OwnedUpgradeabilityProxy:
Lets say I have this contract:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.8.0;
contract ERC721V1_0 {
// Mapping from token ID to owner
mapping (uint256 => address) internal _tokenOwner;
//upgradability
bool internal _initialized;
function initialize() public {
require(!_initialized, "Contract already initialized");
_initialized = true;
}
function ownerOf(uint256 tokenId) internal view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
}
Once deployed, I want to change the function visibility to external, so I go to the same ERC721V1_0 contract and change the function to (please note that the function name now changed from ownerOf to _ownerOf:
function _ownerOf(uint256 tokenId) internal view returns (address) {
address owner = _tokenOwner[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
Then I create a new contract which will upgrade the latest:
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.8.0;
import "./ERC721V1_0.sol";
contract ERC721V1_1 is ERC721V1_0 {
//upgradability
bool internal _initializedV11;
function initializeV11() public {
require(!_initializedV11, "contract already upgraded");
_initializedV11 = true;
}
function ownerOf(uint256 tokenId) external virtual view returns (address) {
return _ownerOf(tokenId);
}
}
Is this a way to go? I checked some values and it seems to be working but not sure in the long term if the storage somehow will get corrupted