You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何对长度32的动态bytes调用SSTORE结果恒为0x000...080?

问题分析与解决

问题根源

核心问题出在Yul汇编对参数的处理逻辑上:

  • bytes memory是动态内存数组,在汇编层面它本质是一个内存指针(指向内存中存储该数组的起始位置,Solidity里动态内存数组默认从0x80开始分配)。
  • 你直接写sstore(key, val)时,存进存储的不是val里的实际数据,而是这个指针本身的值(也就是0x80),所以不管val内容是什么,sload读出来都是0x000...080。
  • 换成bytes32类型就正常,是因为它是值类型,传递给sstore的就是实际的32字节数据,而非指针。

修复代码

要把bytes memory里的实际数据存入存储,得手动跳过长度字段读取内存中的内容。因为你用abi.encodePacked生成的刚好是32字节数据,直接读取指针偏移0x20位置的内容即可:

bytes32 key = bytes32(0);
bytes memory val = abi.encodePacked(bytes32(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
bytes32 result;
assembly {
    // 跳过bytes memory的长度字段(前32字节),读取实际数据
    let actualVal := mload(add(val, 0x20))
    sstore(key, actualVal)
    result := sload(key)
}
// 此时result会等于预期的0xFFF...FFF
result;

补充说明

  • Solidity中bytes memory的内存布局:前32字节存储数组长度,从val + 0x20开始才是实际的字节内容。
  • 如果你的bytes memory长度不是32字节,需要根据实际长度处理,但本例中abi.encodePacked(bytes32(...))刚好生成固定32字节,所以这个方法完全适用。

内容的提问来源于stack exchange,提问作者Sam Goldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:10:37