【问题标题】:Why jumping into an instruction even if containing a JUMPDEST does not work?为什么即使包含 JUMPDEST 也无法跳入指令?
【发布时间】:2020-10-18 13:24:10
【问题描述】:

这是我的整个程序。其背后的原因是,以太坊上的程序越大,加载它的成本就越高(因为每字节的 gas 成本非常高)。

CALLER
CALLDATASIZE
ISZERO
PUSH1 0x07
JUMPI
PUSH3 0x5b6000
SSTORE

所以我要跳入PUSH3 0x5b6000,但如果我们反汇编0x5b6000,那就意味着

JUMPDEST
PUSH1 0x00

因此,既然 evm 操作码编码是 fully variable length(并且所有指令在 PUSHxx 旁边都是一个字节长)并且我正在跳转到 JUMPDEST,为什么 this transaction 会失败?

黄皮书的哪里指出,去JUMPDEST不是有效跳转目的地的唯一要求?

【问题讨论】:

  • 请注意,没有程序或工具可以组装完全用以太坊组装的程序。需要使用十六进制编辑器完全手工完成。
  • 为什么投反对票?
  • 请注意,这种跳到指令中间的方式,虽然在过去的“大师”中更为常见,但让任何人都难以理解正在发生的事情。但是,典型的事情要问适用。你试过在调试器中运行它吗?
  • @ThomasJager 然后它的行为就像问题的交易链接中描述的那样,它是invalid jump destination,但没有说明它为什么无效。请注意,与传统的云计算相比,以太坊的费用非常高,这是程序尽可能短的原因。
  • 将此问题迁移到Ethereum StackExchange 可能是值得的。

标签: assembly ethereum opcode evm stack-machine


【解决方案1】:

当最初提出这个问题时,我不确定 yellow paper 的哪个版本可用,但这里是伊斯坦布尔版本第 13 页的摘录:

9.4.3。跳转目的地有效性。我们之前使用 D 作为函数来确定一组有效的跳转目标,给定的代码是 正在运行。我们将其定义为代码中由 a 占用的任何位置 JUMPDEST 指令。

所有这些职位都必须在有效的指令下 边界,而不是坐在 PUSH 操作的数据部分 并且必须出现在代码的明确定义部分 (而不是在它后面隐式定义的 STOP 操作中)。

这是实现分析的代码的 geth source location

【讨论】:

    猜你喜欢
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多