


























在浏览器中打开 Remix IDE: https://remix.ethereum.org/,在 contracts 目录下创建如下合约:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;
contract MyTest {
function bytesInMemory() public pure returns (bytes memory) {
bytes memory a = "hello";
bytes memory b = "hi";
return bytes.concat(a, b);
}
function bytesArrayInMemmory(uint a) public pure returns (bytes[] memory) {
if (a == 0)
++a;
bytes[] memory result = new bytes[](a);
for(uint i = 0; i<a; i++){
result[i] = "hello world";
}
return result;
}
}


bytesInMemory(),分析 bytes 的 Memory Layout
{
"0x0": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x20": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x40": "0000000000000000000000000000000000000000000000000000000000000127\t????????????????????????????????",
"0x60": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x80": "0000000000000000000000000000000000000000000000000000000000000005\t????????????????????????????????",
"0xa0": "68656c6c6f000000000000000000000000000000000000000000000000000000\thello???????????????????????????",
"0xc0": "0000000000000000000000000000000000000000000000000000000000000002\t????????????????????????????????",
"0xe0": "6869000000000000000000000000000000000000000000000000000000000000\thi??????????????????????????????",
"0x100": "0000000000000000000000000000000000000000000000000000000000000007\t????????????????????????????????",
"0x120": "68656c6c6f686900000000000000000000000000000000000000000000000000\thellohi?????????????????????????",
"0x140": "0000000000002000000000000000000000000000000000000000000000000000\t?????? ?????????????????????????",
"0x160": "0000000000000768656c6c6f6869000000000000000000000000000000000000\t???????hellohi??????????????????",
"0x180": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????"
}
将相关字节染上相同颜色,方便观察;黄色阴影背景部分数据为 return 返回的 ABI 编码后的结果

mem[0x40:0x60):
mem[0x80:0xc0):
mem[0xc0:0x100):
mem[0x100:0x127):
mem[0x127:0x187):
将返回值进行 ABI 编码后的结果,共计 0x60 个字节 --- 对应 RETURN 命令执行时 stack 中的 【0x0127,0x60】;
前 0x20 个字节的值为 0x20,表明数据编码起始地址 offset 为 0x20;
第二个 0x20 个字节的值为 0x07,表明 bytes 长度为 7;
第三个 0x20 个字节为 right-padding 后的字节编码。
bytesArrayInMemmory(4),分析 bytes[] 的 Memory Layout
{
"0x0": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x20": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x40": "0000000000000000000000000000000000000000000000000000000000000220\t??????????????????????????????? ",
"0x60": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????",
"0x80": "0000000000000000000000000000000000000000000000000000000000000004\t????????????????????????????????",
"0xa0": "0000000000000000000000000000000000000000000000000000000000000120\t??????????????????????????????? ",
"0xc0": "0000000000000000000000000000000000000000000000000000000000000160\t????????????????????????????????",
"0xe0": "00000000000000000000000000000000000000000000000000000000000001a0\t??????????????????????????????? ",
"0x100": "00000000000000000000000000000000000000000000000000000000000001e0\t????????????????????????????????",
"0x120": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x140": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x160": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x180": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x1a0": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x1c0": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x1e0": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x200": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x220": "0000000000000000000000000000000000000000000000000000000000000020\t??????????????????????????????? ",
"0x240": "0000000000000000000000000000000000000000000000000000000000000004\t????????????????????????????????",
"0x260": "0000000000000000000000000000000000000000000000000000000000000080\t????????????????????????????????",
"0x280": "00000000000000000000000000000000000000000000000000000000000000c0\t????????????????????????????????",
"0x2a0": "0000000000000000000000000000000000000000000000000000000000000100\t????????????????????????????????",
"0x2c0": "0000000000000000000000000000000000000000000000000000000000000140\t????????????????????????????????",
"0x2e0": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x300": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x320": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x340": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x360": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x380": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x3a0": "000000000000000000000000000000000000000000000000000000000000000b\t???????????????????????????????\u000b",
"0x3c0": "68656c6c6f20776f726c64000000000000000000000000000000000000000000\thello world?????????????????????",
"0x3e0": "0000000000000000000000000000000000000000000000000000000000000000\t????????????????????????????????"
}
将相关字节染上相同颜色,方便观察;黄色阴影背景部分数据为 return 返回的 ABI 编码后的结果

mem[0x40:0x60):
mem[0x80:0xa0):
mem[0xa0:0xc0):
mem[0xc0:0xe0)、mem[0xe0:0x100)、mem[0x100:0x120) 分别是 result[1] ~ result[3] 中存储的 bytes 起始地址的指针。mem[0x120:0x160):
mem[0x120:140) 是字符串的长度,mem[0x140:160) 是 right-padding 后的字符串。mem[0x160:0x1a0)、mem[0x1a0:0x1e0)、mem[0x1e0:0x220) 分别是 result[1] ~ result[3] 对应的 bytes 的实际编码。mem[0x220:0x3e0):
对 result 进行 ABI 编码后的结果,共计 0x1c0 个字节 --- 对应 RETURN 命令执行时 stack 中的 【0x0220,0x1c0】。这一块数据编码是遵照 合约ABI规范 独立进行的编码,其中的 offset 与实际的 memory 地址无关,而是相对于这块数据自身计算出的 offset。
由于返回值类型 bytes[] 是动态类型,所以起始位置的 mem[0x220:0x240) 是 head(X(1)),为 0x20,表明 0x20 个byte 后是 bytes[] 的实际编码;
mem[0x240:0x260) = 4,表明 bytes[] 有4个元素;
mem[0x260:0x3e0) 是对 bytes[] 4个元素的编码;
mem[0x260:0x280) = 0x80,是 result[0] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;
mem[0x280:0x2a0) = 0xc0,是 result[1] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;
mem[0x2a0:0x2c0) = 0x100,是 result[2] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;
mem[0x2c0:0x2e0) = 0x140,是 result[3] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;
mem[0x2e0:0x320)、mem[0x320:0x360)、mem[0x360:0x3a0)、mem[0x3a0:0x3e0) 分别是 result[0] ~ result[3] 的实际数据编码结果。
posted on 2024-09-11 17:04 HorseShoe2016 阅读(108) 评论() 收藏 举报
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。