Skip to content

Commit

Permalink
update ray 02-21
Browse files Browse the repository at this point in the history
  • Loading branch information
rayjun authored Feb 21, 2025
1 parent e29142e commit ab2b0e0
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions rayjun.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,4 +449,20 @@ EVM 中有一些关键的组件:
<img width="288" alt="eth1data" src="https://github.com/user-attachments/assets/f4afc0af-76ba-436f-9dcf-f26bd4753087" />


### 2025.02.21
- Solidity 编写的智能合约会被编译成字节码,字节码会被 EVM 执行,其中字节码中有很多被预先定义的操作码,由这些操作码串联整个字节码的执行
- 一个操作码的长度为 1 个字节,最多可以定义 256 种操作码,当前大约定义了 140 个操作码,后续还有很大的扩展空间
- 在 EVM 中调用函数需要函数选择器加上具体的参数,总长为 36 字节,函数选择器占 4个字节,参数占 32 个字节,这也有另一个让我们熟知的名字 calldata
- 函数签名是指函数名和参数列表组成,比如 store(uint256),不包括返回值
- 函数选择器是 Keccak256 哈希函数计算函数签名的哈希值的前 4 个字节,在合约调用时,通过这个 4 个字节来确定调用哪个函数,这里的函数选择器是有可能会重复的,在合约升级中需要注意这个问题
- 在这里可以查到当前以太坊的函数签名库(https://www.4byte.directory/signatures/)
- calldata 字节码可以由 abi.encodeWithSignature("stroe(uint256)", 10) 计算得到
- 这个调用 abi.encodeWithSelector(bytes4(keccak256("store(uint256)"), 10) 等价于上面的调用,都可以用来生成 calldata
- EVM 是栈结构,calldata 会被拆分成对应的操作码入栈执行
- 假如现在合约收到上面 store 函数的调用 calldata,这 36 字节的数据代表了想要调用的目标函数和对应的参数
- 首先 calldata 的的函数选择器会先被加载
- 在进入到合约之后,可以理解为合约中内置了一系列的 if 判断,依次去比对函数选择器对应合约中的哪个函数
- 找到对应的函数之后,就找到函数对应的程序计数器,这个代表合约中函数的字节码位置
- 然后通过 JUMP 操作码跳转到对应的函数开始执行

<!-- Content_END -->

0 comments on commit ab2b0e0

Please sign in to comment.