首页 > 其他分享 >Ethereum学习笔记 ---- 使用 Remix 调试功能理解 bytes 在 memory 中的布局

Ethereum学习笔记 ---- 使用 Remix 调试功能理解 bytes 在 memory 中的布局

时间:2024-09-11 17:04:34浏览次数:1  
标签:编码 Remix 字节 mem bytes 0x260 ---- result memory

目录

编写合约

在浏览器中打开 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;
    }
}

编译、部署、调用合约

调试交易

1. 调用函数 bytesInMemory(),分析 bytes 的 Memory Layout

执行 RETUR 前的最后一刻,stack 快照如下

执行完毕时刻的 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 编码后的结果

对 Memory Layout 的分析

mem[0x40:0x60):

  • 空闲地址指针,值为 0x127; 从 0x127 开始存储的内容实际是返回给调用者的 ABI 编码的结果,由于不会再继续执行新命令了,所以没有更新这里的空闲地址指针。

mem[0x80:0xc0):

  • a 在内存中的布局,前32个字节用于表示字节长度,是5;后续的5个字节是 'hello' 的字节码;后续 right-padding 为32字节的倍数。

mem[0xc0:0x100):

  • b 在内存中的布局。

mem[0x100:0x127):

  • bytes.concat(a, b) 拼接后的结果,字节长度为7;在对返回值进行ABI编码之前,也是 right-padding 为32字节的倍数。

mem[0x127:0x187):

  • 将返回值进行 ABI 编码后的结果,共计 0x60 个字节 --- 对应 RETURN 命令执行时 stack 中的 【0x01270x60】;

  • 前 0x20 个字节的值为 0x20,表明数据编码起始地址 offset 为 0x20

  • 第二个 0x20 个字节的值为 0x07,表明 bytes 长度为 7;

  • 第三个 0x20 个字节为 right-padding 后的字节编码。

2. 调用函数 bytesArrayInMemmory(4),分析 bytes[] 的 Memory Layout

执行 RETUR 前的最后一刻,stack 快照如下

执行完毕时刻的内存布局

{
  "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 编码后的结果

对 Memory Layout 的分析

mem[0x40:0x60):

  • 空闲地址指针,值为 0x220;从 0x220 开始存储的内容实际是返回给调用者的 ABI 编码的结果,由于不会再继续执行新命令了,所以没有更新这里的空闲地址指针。

mem[0x80:0xa0):

  • 动态数组 result 的元素数量,为4,因为我们是以 4 为参数调用的 bytesArrayInMemmory().

mem[0xa0:0xc0):

  • result[0] 对应的 bytes 所在的起始地址,值为 0x120,表明 result[0] 对应的字符串起始地址在 0x120; 后续 mem[0xc0:0xe0)mem[0xe0:0x100)mem[0x100:0x120) 分别是 result[1] ~ result[3] 中存储的 bytes 起始地址的指针。

mem[0x120:0x160):

  • result[0] 对应的 bytes 的实际编码;其中 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 编码后的 结果。这一块数据编码是遵照 合约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[0x260:0x280) = 0xc0,是 result[1] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;

    • mem[0x260:0x280) = 0x100,是 result[2] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;

    • mem[0x260:0x280) = 0x140,是 result[3] 编码结果的起始位置相对于 mem[0x260:0x3e0) 这块数据起始位置的 offset;

    • mem[0x2e0:0x320)mem[0x320:0x360)mem[0x360:0x3a0)mem[0x3a0:0x3e0) 分别是 result[0] ~ result[3] 的实际数据编码结果。

标签:编码,Remix,字节,mem,bytes,0x260,----,result,memory
From: https://www.cnblogs.com/dongling/p/18408521

相关文章

  • PHP8面向对象快速入门六 trait
    PHP中的trait是一种代码复用机制,允许你在多个类中共享方法而无需使用继承。与类和接口不同,trait不能实例化,也不能定义构造函数或属性。trait中不能有常量。可以在一个类中使用多个trait,并在trait中定义公共的方法,这样可以避免代码重复.。trait中可使用抽象方法trait中可......
  • 嵌套集合模型(Nested set model)介绍
    嵌套集合模型(Nestedsetmodel)介绍pilishen /更新于5年前本文翻译自维基百科Nestedsetmodel 此文档是 nestedset-无限分类正确姿势的扩展阅读 nestedsetmodel(嵌套集合模型)是一种在关系型数据库中表示nestedsets(嵌套集合) 的特殊技术。[nestedsets]通常......
  • 基于OpenSSL的密码管理系统-应用密码学课程报告
    第1章概要设计1.1设计目的本研究旨在设计并实现一个基于OpenSSL的密码管理系统,该系统具备密钥对的生成、密钥上传、密钥的核对、身份认证、文件与邮件的加密和解密、数字签名及数字证书管理等常用功能。研究的意义主要体现在以下几个方面:提升网络信息安全水平:通过集成多种密......
  • Vue中列表渲染中的v-for的使用
    v-for的使用:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</tit......
  • 【开源分享】PHP 在线客服系统源码 全开源无加密,支持自动刷新 网页即时接收消息
    智能化在线客服系统也是其中一个必备功能。其智能化主要体现在细节中,在保持客服人员工作正常进行的情况下,让效率变高。智能化在线客服系统采取“轮询”的工单分配方式,让合适的客服人员处理合适的问题;提供“视图”功能,让客服人员专注于重要工单;强大的“搜索”功能,迅速锁定目标客户......
  • 软件测试学习笔记丨Docker 安装、管理、搭建服务
    本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/32192容器(Docker)技术的价值保证环境一致性,只要使用相同镜像部署就可以保证一致性。轻量级虚拟化访问,运行更快,资源更小。同时也可以荣期间的隔离性。封装部署的负载型,云原生与微服务的首选技术方案。未来测试人员必学的技术......
  • 云服务器有必要安装clamav吗
    ClamAV是一个开源的病毒扫描工具,主要用于检测恶意软件、病毒、特洛伊木马和其他恶意威胁。对于云服务器来说,是否安装ClamAV取决于多种因素:以下情况建议安装ClamAV:数据安全性要求高:如果你的服务器上存储或处理的数据对安全性有较高要求,安装ClamAV可以帮助你定期扫描和检测潜在的恶意......
  • AE2024最新版下载全攻略,不限速安装包助你设计更出色!
    #AE2024最新版下载全攻略,不限速安装包助你设计更出色!AdobeAfterEffects(简称AE)是一款强大的视频特效和动态图形设计软件,广泛应用于电影、电视、广告和网络视频制作等领域。随着技术的不断进步,Adobe公司推出了AE2024最新版,带来了更多创新功能和性能优化,帮助设计师们创作出更加出色......
  • AE2024安装不求人,详细图文教程带你轻松搞定,设计师加油包!
    #AE2024安装不求人,详细图文教程带你轻松搞定,设计师加油包!AdobeAfterEffects(简称AE)是一款强大的视觉效果和动态图形设计软件,广泛应用于电影、电视、广告等领域。随着AE2024的发布,许多设计师都迫不及待地想要体验新版本带来的新功能和改进。本文将为你提供一份详细的AE2024安装教......
  • c# 异常捕获
    //错误有两种运行错误和编译错误//运行错误是看不到的需要程序运行时才能知道代码是否出错//编译错误是我们可以通过编辑器直接看到的错误//编译错误常见就是语法出错类型不对数据不存在//C#是一种编译型语言,代码需要通过编译器成机器可识别的代码才能运行!//inta......