[英]How to write to an arbitrary storage slot using assembly in Solidity smart contracts?
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():我试图通过更改变量的存储插槽并尝试在之后读取它以查看它是否存储在正确的插槽中,但我没有得到我期望的返回值,从而了解使用 Solidity 程序集 (Yul) 进行存储操作的基础知识调用 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()
:让我们跟随seeSlot()
的执行:
uint _age = age;
Here age
is read from storage and saved in the variable _age
on the stack.这里从存储中读取age
并保存在堆栈上的变量_age
中。 So _age = 30
.所以_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.在这里,我们从插槽_age
的存储中读取,因此在插槽 30 处sl
是堆栈上的变量。 sl = 0
since at slot 30 there's nothing. sl = 0
因为在插槽 30 处什么都没有。
sl:= age.slot
The value of sl
is overwritten with slot age
is saved in storage, so 0
. sl
的值被slot age
覆盖,存储在storage 中,所以0
。
return (sl, 0x20)
return
returns the memory from sl
to sl+0x20
. return
将 memory 从sl
返回到sl+0x20
。 Since we haven't saved anything in memory it returns 0
.由于我们没有在 memory 中保存任何内容,因此它返回0
。
The correct function is something like this:正确的 function 是这样的:
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.关于更改 state 变量的存储槽,这是无法完成的,并且会导致 Solidity 代码中的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.