EIP-3: 增加 CALLDEPTH 操作码
Authors | Martin Holst Swende <martin@swende.se> |
---|---|
Created | 2015-11-19 |
摘要
这是一个提议,增加一个新的操作码 CALLDEPTH
。 CALLDEPTH
操作码将返回剩余的可用调用栈深度。
动机
存在一个限制,用于指定合约可以调用其他合约的深度;即调用栈。该限制目前是 256
。如果一个合约调用另一个合约(通过 CALL
或 CALLCODE
),如果已达到调用栈深度限制,则该操作将失败。
这种行为使得可以对合约进行“调用栈攻击”[1]。在这种攻击中,攻击者首先创建适当的栈深度,例如通过递归调用。完成此步骤后,攻击者调用目标合约。如果目标调用另一个合约,该调用将失败。如果没有正确检查返回值以查看调用是否成功,则后果可能是灾难性的。
例子:
- 合约
A
希望被定期调用,并在每个区块中向调用者支付以太币。 - 当合约
A
被调用时,它会调用合约B
和C
,这会消耗大量 gas。调用后,合约A
向调用者支付以太币。 - 恶意用户
X
确保在调用 A 之前栈深度较浅。对B
和C
的调用都会失败,但X
仍然可以收取奖励。
可以通过两种方式防御此问题:
- 调用后检查返回值。
- 通过实验检查调用栈深度。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.