Alert Source Discuss
🛑 Withdrawn Standards Track: Core

EIP-3: 增加 CALLDEPTH 操作码

Authors Martin Holst Swende <martin@swende.se>
Created 2015-11-19

Table of Contents

摘要

这是一个提议,增加一个新的操作码 CALLDEPTHCALLDEPTH 操作码将返回剩余的可用调用栈深度。

动机

存在一个限制,用于指定合约可以调用其他合约的深度;即调用栈。该限制目前是 256。如果一个合约调用另一个合约(通过 CALLCALLCODE),如果已达到调用栈深度限制,则该操作将失败。

这种行为使得可以对合约进行“调用栈攻击”[1]。在这种攻击中,攻击者首先创建适当的栈深度,例如通过递归调用。完成此步骤后,攻击者调用目标合约。如果目标调用另一个合约,该调用将失败。如果没有正确检查返回值以查看调用是否成功,则后果可能是灾难性的。

例子:

  1. 合约 A 希望被定期调用,并在每个区块中向调用者支付以太币。
  2. 当合约 A 被调用时,它会调用合约 BC,这会消耗大量 gas。调用后,合约 A 向调用者支付以太币。
  3. 恶意用户 X 确保在调用 A 之前栈深度较浅。对 BC 的调用都会失败,但 X 仍然可以收取奖励。

可以通过两种方式防御此问题:

  1. 调用后检查返回值。
  2. 通过实验检查调用栈深度。Piper Merriam 的一个库 [2] 适用于此目的。这种方法在 gas 方面相当昂贵。

[1] 又名“浅栈攻击”和“栈攻击”。但是,准确地说,“栈”这个词在 EVM 中有不同的含义,不要与“调用栈”混淆。

[2] https://github.com/pipermerriam/ethereum-stack-depth-lib

规范

操作码 CALLDEPTH 应该返回剩余的调用栈深度。值为 0 表示调用栈已耗尽,无法进行进一步的调用。

理由

实际的调用栈深度以及调用栈深度限制在执行期间都存在于 EVM 中,但 EVM 内部无法访问。该实现应该相当简单,并且将提供一种廉价且有效的方式来防止调用栈攻击。

实现

未实现。

Citation

Please cite this document as:

Martin Holst Swende <martin@swende.se>, "EIP-3: 增加 CALLDEPTH 操作码 [DRAFT]," Ethereum Improvement Proposals, no. 3, November 2015. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3.