EVM编译器与访问控制

本文讨论了EVM编译器如何为函数分派生成代码以及相关的风险,重点关注访问控制。编译器定义了智能合约中基本的访问控制机制。文章还探讨了函数分派的鸟瞰图,以及编译器可能出现的错误,例如不正确的可见性推断、遗漏中止指令、省略支付能力检查等,并强调了对编译器团队进行适当的资金支持以及在代码库中添加健全性检查测试的重要性。

本文讨论了EVM编译器如何为函数分发生成代码以及相关的风险,重点关注访问控制。

编译器定义了智能合约中基本的访问控制机制之一 - 哪些函数可以访问以及如何访问。

  • 每个私有函数应该只能通过调用路径来执行,该路径的根是一个外部函数。
  • 每个通向私有函数执行的路径都应该满足源代码的语义约束。

函数分发概览

在像Vyper或Solidity这样的语言中,分发是隐式设置的,也就是说,它被编译器抽象出来,并在没有来自源代码的指令的情况下创建。

合约就像服务器,每次传入输入(外部交易)都需要启动。加载器(evm运行时)加载合约,合约从一个隐式的 main 函数开始执行。

main 函数负责解析来自 calldata 的输入,并执行与 calldata 中编码的用户命令相对应的功能。

这些命令具有由 abicoder v2 定义的特定结构(这种编码被所有主要的 evm 编译器采用)。该编码定义了如何编码执行合约函数的请求,即如何定义要执行哪个函数以及如何编码其输入。

函数是通过函数选择器选择的,函数选择器被定义为函数签名的 keccak256 的 4B (例如:keccak256("transfer(address,uint256)")[0:4])。

一旦从 calldata 加载了 4B,我们必须检查合约中是否存在相应的函数。这是如何完成的?

分发代码,又名隐式 main

在语义分析期间,编译器会解析每个函数的可见性(私有/外部)。然后,在代码生成阶段,它会查看外部函数的集合并计算它们的函数选择器,这些选择器随后用于 main 函数中的函数分发。然后它可以构造 main 函数。

main 函数通常会执行以下操作:

  1. 从 calldata 中提取函数选择器
  2. 将选择器与给定合约的外部函数的选择器集合进行比较(例如,使用 if 链):
if calldata[0:4] == selector_foo:
    ...
    call foo
if calldata[0:4] == selctor_bar:
    ...
    call bar
if fallback_defined:
    ...
    call fallback
else:
    abort execution
  1. 如果选择器匹配,则会执行一些额外的检查(稍后会详细介绍),并调用相应的函数(执行跳转到其标签)
  2. 如果没有选择器匹配,那么我们要么调用 fallback 函数,要么中止执行

额外检查通常包括以下内容:

  • payability(可支付性)检查 - 如果函数不接受以太币,那么我们断言 msg.value == 0

可能出什么问题?

这与访问控制有什么关系? 让我们考虑一下可能出现的问题:

  • 如果编译器在语义阶段错误地推断了可见性会怎么样?
  • 如果编译器将私有函数插入到分发机制中会怎么样?
  • 如果编译器没有在选择器搜索的分发结束时插入 abort 并且代码继续执行会怎么样?
  • 如果省略了 payability 检查会怎么样?
  • 如果分发机制过于消耗 gas/size 会怎么样?
  • 如果编译器在某些情况下错误地计算了选择器会怎么样?
  • 如果 2 个选择器之间存在哈希冲突会怎么样?

如果其中任何一项失败,都可能产生严重的后果。如果公开了一个私有函数会怎么样? 所有私有函数都假定它们不能从顶层调用,因此不实现相应的访问控制。

假设所有这些点都已正确实现——这是否意味着访问控制已正确实现? 不,一般来说,编译器可能几乎具有任意的错误编译(编译成具有与原始源代码不同含义的字节码)。 为了确保正确实现访问控制,我们必须考虑代码中的所有可能路径,并确保它们都不会破坏源代码语义。

结论

我们已经展示了如何在 EVM 编译器中构造函数分发,并讨论了相关的风险。在合约开发期间,我们经常认为很多事情是理所当然的。 调用约定或函数分发中的错误可能会对整个生态系统产生灾难性的后果。 为你的编译器团队提供适当的资金,并在你的代码库中添加一些健全性检查测试!

  • 原文链接: hackmd.io/@cyberthirst/S...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
cyberthirst
cyberthirst
江湖只有他的大名,没有他的介绍。