Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-1109: PRECOMPILEDCALL 操作码 (移除预编译合约的 CALL 开销)

Authors Jordi Baylina (@jbaylina)
Created 2018-05-22
Discussion Link https://ethereum-magicians.org/t/eip-1109-remove-call-costs-for-precompiled-contracts/447

简短概要

这个 EIP 创建一个特定的操作码,名为 PRECOMPILEDCALL,用于调用预编译合约,而无需普通 CALL 的开销。

摘要

这个 EIP 试图解决以小额 gas 成本调用预编译合约时 gas 消耗过高的问题。使用此操作码调用预编译合约允许定义有效成本小于 700 的预编译合约。

动机

每个预编译合约都有一个已定义的调用成本。没有理由增加 CALL 操作码的隐式额外 gas 成本。

例如,SHA256 预编译合约成本为 60,ECADD 成本为 500(在 EIP-1108 中提议仅需 50)。当调用预编译合约时,除了预编译合约的成本外,仅 CALL 操作码就会消耗 700 gas。

这是没有意义的,而且现在不可能定义一个使用它的有效成本低于 700 的预编译合约。

规范

如果 block.number >= XXXXX,则定义一个名为 PRECOMPILEDCALL 的新操作码,其代码值为 0xfb

操作码的 gas 成本为 2 (Gbase) 加上为每个特定预编译智能合约定义的特定 gas 成本。

操作码从堆栈中获取 5 个字并将 1 个字返回到堆栈。

输入堆栈值是:

mu_s[0] = 被调用的预编译智能合约的地址。 mu_s[1] = 输入参数的内存指针。 mu_s[2] = 输入参数的长度(以字节为单位)。 mu_s[3] = 存储输出的内存指针 mu_s[4] = 输出缓冲区长度。

如果成功调用,则返回 1,在以下任何情况下返回 0:

1.- mu_s[0] 是未定义的预编译智能合约的地址。 2.- 预编译的智能合约失败(如每个智能合约上定义的那样)。例如,无效的输入参数。

预编译的智能合约不执行操作码,因此无需像普通 CALL (0xf1) 那样传递 gas 参数。如果可用 gas 小于 2 加上特定预编译智能合约所需的 gas,则上下文只会因“Out of Gas”错误而停止执行。

此调用没有堆栈检查。

对预编译智能合约的普通 CALL 继续以完全相同的行为工作。

对常规地址或常规智能合约的 PRECOMPILEDCALL 被认为是调用“未定义的智能合约”,因此 VM 必须不执行它,并且操作码必须返回 0x0。

理由

最初有一个删除 CALL 的 gas 成本的提案,但看起来实现和测试一个新的操作码更容易。

该代码只是 STATICCALL 操作码之后可用的下一个操作码。

向后兼容性

此 EIP 是向后兼容的。从现在开始,使用此新操作码调用预编译合约的智能合约成本将降低。

使用 CALL 方法调用预编译智能合约的旧合约将继续工作。

测试用例

  • 正常调用已定义的预编译合约。
  • 调用未定义的预编译合约。
  • 调用常规合约
  • 调用常规帐户
  • 调用 0x0 智能合约(不存在)。
  • 调用偏移指针和长度的大值
  • 调用剩余的 gas 恰好需要调用智能合约。
  • 调用剩余的 gas 恰好减一需要调用智能合约。

实现

尚未实施。

版权

CC0 下放弃版权及相关权利。

Citation

Please cite this document as:

Jordi Baylina (@jbaylina), "EIP-1109: PRECOMPILEDCALL 操作码 (移除预编译合约的 CALL 开销) [DRAFT]," Ethereum Improvement Proposals, no. 1109, May 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1109.