assembly 如何在Solidity智能合约中使用汇编写入任意存储槽?

9w11ddsr  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(179)

我尝试使用Solidity assembly(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)
        }
    }
}

我做错了什么?

eqfvzcg8

eqfvzcg81#

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.

相关问题