简体   繁体   English

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

[英]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.

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