繁体   English   中英

如何使用 Solidity 智能合约中的程序集写入任意存储槽?

[英]How to write to an arbitrary storage slot using assembly in Solidity smart contracts?

我试图通过更改变量的存储插槽并尝试在之后读取它以查看它是否存储在正确的插槽中,但我没有得到我期望的返回值,从而了解使用 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)
        }
    }
}

我究竟做错了什么?

有一些错误。 让我们跟随seeSlot()的执行:

  • uint _age = age;

这里从存储中读取age并保存在堆栈上的变量_age中。 所以_age = 30

  • let sl:= sload(_age)

在这里,我们从插槽_age的存储中读取,因此在插槽 30 处sl是堆栈上的变量。 sl = 0因为在插槽 30 处什么都没有。

  • sl:= age.slot

sl的值被slot age覆盖,存储在storage 中,所以0

  • return (sl, 0x20)

return将 memory 从sl返回到sl+0x20 由于我们没有在 memory 中保存任何内容,因此它返回0

正确的 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
        }
    }

关于更改 state 变量的存储槽,这是无法完成的,并且会导致 Solidity 代码中的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM