I am trying to understand the basics of storage manipulation using Solidity assembly (Yul) by changing the storage slot for a variable and trying to read it afterwards to see if it's stored in the correct slot but I don't get the return value I expect when calling seeSlot():
//SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
contract Assembly {
uint public age = 30;
function changeStorageSlot(uint newSlot) pure external {
bytes storage _age;
assembly {
_age.slot := newSlot
}
}
function seeSlot() external view returns(uint) {
uint _age = age;
assembly {
let sl:= sload(_age)
sl := age.slot
return (sl, 0x20)
}
}
}
What am I doing wrong?
There are some errors. Let's follow the execution of seeSlot()
:
uint _age = age;
Here age
is read from storage and saved in the variable _age
on the stack. So _age = 30
.
let sl:= sload(_age)
Here we are reading from storage at slot _age
, so at slot 30. sl
is a variable on the stack. sl = 0
since at slot 30 there's nothing.
sl:= age.slot
The value of sl
is overwritten with slot age
is saved in storage, so 0
.
return (sl, 0x20)
return
returns the memory from sl
to sl+0x20
. Since we haven't saved anything in memory it returns 0
.
The correct function is something like this:
function seeSlot() external view returns(uint) {
assembly {
let sl:= sload(age.slot) // => sl = 30
mstore(0x00, sl) // store in memory at 0x00
return (0x00, 0x20) // return first word of memory
}
}
Regarding changing the storage slot of a state variable, it can't be done and can lead to bugs in the solidity code.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.