【Solidity Yul Assembly】2.3 | Dangers of Memory Misuse

  • 0xE
  • 更新于 2024-08-23 11:04
  • 阅读 512

一些内存使用的注意事项。

注意事项

  • 内存指针管理:如果你不遵循 Solidity 的内存布局和空闲内存指针规则,你可能会遇到一些严重的 bug。
  • 内存解包行为:内存不会尝试将小于 32 字节的数据类型打包在一起。当数据从存储加载到内存时,即使这些数据在存储中是打包的(如 uint8bool),在加载到内存中后,每个数据项都会占用完整的 32 字节空间。

示例一:内存指针的误用

function breakFreeMemoryPointer(uint256[1] memory foo) external view returns (uint256) {
    assembly {
        mstore(0x40, 0x80) // 人为修改空闲内存指针
    }
    uint256[1] memory bar = [uint256(6)];
    return foo[0]; // 返回 foo[0] 的值
    // input [1000]
    // return 6
}

假如我们传入参数 [1000],正常情况下,这个参数会被写入内存槽 0x80,空闲内存指针此时指向 0xa0。然而,我们将空闲内存指针强制设为 0x80,此时内存中再装入定长数组bar,其值 6 会被写入到 0x80 处,覆盖原有的值。因此,return foo[0] 将会返回 0x80 地址处的内容,即 6

示例二:内存中的数据解包

uint8[] foo = [1,2,3,4,5,6];
function unpacked() external {
    uint8[] memory bar = foo;
}

1.png 在这个示例中,虽然 foo 在存储槽中是紧密打包在一个槽中,但当它被读取到内存中时,数据会被解包。每个 uint8 数据类型的元素在内存中都会单独占用 32 字节空间。

关于作者 0xE: Twitter Telegram

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
0xE
0xE
0x59f6...a17e
17年进入币圈,做过FHE,联盟链,现在是智能合约开发者。 刨根问底探链上真相,品味坎坷悟Web3人生。