Changing constant variable in inline assembly #1744
-
In hardhat-upgrades bytes32 private constant _IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; Which is basically declaring and initializing a constant storage variable. function setImplementation(address newImplementation) public {
assembly {
sstore(_IMPLEMENTATION_SLOT, newImplementation) // Changing the constant variable
}
} Can constant variables be changed using inline assembly in solidity, why?? A constant shouldn't be a constant?? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 13 replies
-
Well, this will be complicated as Assembly is basically accessing the EVM, which is very low level. So, I would suggest going through this first to understand what is happening here: #1219 sstore(p, v) is equivalent to storage[p] := v where p denotes the position on the stack. So, to answer your question, yes -- we are assigning the constant variable here. |
Beta Was this translation helpful? Give feedback.
-
We are not updating the constant variable here. I am not sure if you have cleared the concepts about proxy contracts or not. but let me give you an idea. Proxies are one of the ways of upgrading smart contracts. How does it work? Whenever we want to upgrade our smart contract we create a new smart contract with all of the upgraded logins inside it and we call this implementation contract. Our proxy contract is like a Parent contract, its work is to redirect the users' function calls to the latest implementation contract. Now, this is the location of the implementation contract storage slot according to EIP 1967: bytes32 private constant _IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; We will update the implementation contract (if later any changes required) but the location of implementation contract remains same. Hope it clears your query. |
Beta Was this translation helpful? Give feedback.
-
I got it. According to docs
In this case : //SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract changeConstant {
uint256 private constant v = 5;
function increment() public {
assembly{
sstore(v, add(sload(v), 1))
}
}
function getValue() public view returns(uint256 result){
assembly {
result := sload(v)
}
}
} When sstore(_IMPLEMENTATION_SLOT, newImplementation) solidity compiler converts it into : sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation) And read / write is done at this location in storage slot. (bytes32 converted to number and then used as index for read / write operations in storage array). |
Beta Was this translation helpful? Give feedback.
I got it.
According to docs
In this case :
When
sstore(v, add(sload(v), 1))
is run, solidity compiler converts it intosstore(5, add(sload(5), 1))
, and storage is an array, so it read / write in storage array at i…