bytecode - 以太坊字节码 JUMP 和 JUMPDEST 是如何解决的?

标签 bytecode ethereum smartcontracts evm

我一直在寻找有关以太坊如何处理跳转和跳转目的地的信息。从各种博客和黄皮书中我发现如下:

JUMP 所采用的操作数和 JUMPI 所采用的两个操作数中的第一个是 PC 设置的值(假设在 JUMPI 的情况下,第一个堆栈值 != 0)。

但是,看看 this合约的创建代码(作为操作码)前几个操作码/值是:

PUSH1 0x60 推1 0x40 微商城 调用数据大小 伊泽罗 推2 0x00f8 JUMPI

据我了解,这意味着如果 ISZERO 插入堆栈的值!= 0,则 PC 将更改为 0x00f8 ,如下所示JUMPI 从堆栈中取出两个,检查第二个是否为 0,如果不是,则将 PC 设置为其第一个操作数的值。

我遇到的问题是十进制的0x00f8248。合约中的第 248 个位置似乎是 MSTORE 而不是 JUMPDEST,这会导致合约执行失败,因为 JUMP* 可以仅指向有效的 JUMPDEST

大概合约不会故意跳转到无效目的地?

如果有人能解释如何解决跳转和跳转目的地,我将非常感激。

最佳答案

如果它对其他人有帮助:

困惑是由 EVM 逐字节读取而不是逐字读取引起的。

从问题中的示例来看,0x00f8将是第 248 个字节,而不是第 248 个字。

由于每个操作码都是 1 字节长 PC读取操作码时通常加 1。

但是在 PUSH 的情况下指令中,还包括以下字节数作为其操作数的信息。

例如PUSH2取其后的 2 个字节,PUSH6占用其后的 6 个字节,依此类推。这里PC对于 PUSH 将增加 1然后对于 PUSH 使用的数据的每个字节分别为 2 或 6 .

关于bytecode - 以太坊字节码 JUMP 和 JUMPDEST 是如何解决的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47520515/

相关文章:

bash - 在私有(private)以太坊区 block 链上生成 Enode?

java - Android 上的离线钱包 : can't access the JSON file

c++ - 严重错误:找不到 'boost/uuid/uuid.hpp'文件

java - Scala 生成的字节码到 Java 代码的转换

ethereum - 创建结构会导致 remix ide 出现奇怪的行为

java - 如何使用注释 @MyFormat ("%td.%<tm.%<tY"格式化 getBirthday()

ethereum - 所需气体超出区 block 气体限制回退功能

node.js - Openzeppelin 中已为 Context.sol 声明了标识符

java - 为什么 javac 有时会创建不必要的变量副本?

python - 是否可以通过代码对象访问内部函数和类?