当前位置: 首页 > news >正文

【源码阅读】EVMⅢ

参考[link](https://blog.csdn.net/weixin_43563956/article/details/127725385
大致流程如下:
编写合约 > 生成abi > 解析abi得出指令集 > 指令通过opcode来映射成操作码集 > 生成一个operation

以太坊虚拟机的工作流程:
由solidity语言编写的智能合约,通过编译器编译成bytecode,之后发到以太坊上,以太坊底层通过evm模块支持合约的执行和调用,调用时根据合约获取代码,即合约的字节码,生成环境后载入到 EVM 执行。

1、操作码opcodes.go

合约编译出来的bytecode中,一个OpCode就是上面的一位。opcodes按功能分为9组,以第一位十六进制数来分类,例如0x1x,0x2x。

opCodeRange对应操作
0x0arithmetic ops算数操作
0x10comparison ops比较操作
0x20crypto加密操作
0x30closure state状态闭包
0x40block operations区块操作
0x50‘storage’ and execution存储和执行操作
0x60pushes压栈操作
0x80dups克隆操作
0x90swaps交换操作
0xa0logging ops日志操作
0xf0closures闭包

2、合约contract.go

NewContract函数构造了新的合约,且如果是被合约调用,则复用该合约的 jumpdests。
validJumpdest函数用于验证给定的目标地址是否为有效的跳转目标。通过获取目标地址对应的操作码,判断是否为JUMPDEST类型。如果不是,则返回false,表示无效的跳转目标。调用c.isCode(udest)方法来进一步验证目标地址是否为有效的代码位置。如果是有效的代码位置,则返回true,表示有效的跳转目标;否则返回false

func (c *Contract) validJumpdest(dest *uint256.Int) bool {udest, overflow := dest.Uint64WithOverflow()// PC cannot go beyond len(code) and certainly can't be bigger than 63bits.// Don't bother checking for JUMPDEST in that case.if overflow || udest >= uint64(len(c.Code)) {return false}// Only JUMPDESTs allowed for destinationsif OpCode(c.Code[udest]) != JUMPDEST {return false}return c.isCode(udest)
}

isCode函数判断给定的地址是否为有效的代码段。

3、jump_table.go

这是跳转表。在不同的以太坊版本中,会填充不一样的字段。对指令的真正的解释函数是在这个部分里面,而不是在解释器当中。
版本
其中frontierInstructionSet 这个对象包含了最基本的指令信息,其它是对这个集合的扩充,最全的一个是 constantinopleInstructionSet
operation使用的时候以指令的opcode值为索引。其中包括指令的解释执行函数、要消耗的gas值、栈空间大小和消耗的内存空间大小函数(在memory.go中实现)。

type operation struct {// execute is the operation functionexecute     executionFuncconstantGas uint64dynamicGas  gasFunc// minStack tells how many stack items are requiredminStack int// maxStack specifies the max length the stack can have for this operation// to not overflow the stack.maxStack int// memorySize returns the memory size required for the operationmemorySize memorySizeFunc
}

针对不同的jump-table有不同的函数,里面有不同的解释执行函数。
类型
在每一种类型中,实现不同的operation对象。
validate函数用来检查jump_table中的操作是否为空。

func validate(jt JumpTable) JumpTable {for i, op := range jt {if op == nil {panic(fmt.Sprintf("op %#x is not set", i))}if op.memorySize != nil && op.dynamicGas == nil {panic(fmt.Sprintf("op %v has dynamic memory but not dynamic gas", OpCode(i).String()))}}return jt
}

4、其它文件

gas.go和gas_table.go
这两个文件是用来计算所消耗的gas值,在具体的gas_table.go文件中,针对不同的操作有不同的函数来进行不同的计算。例如
例子
contracts,go文件用于存放预编译好的合约
common.go用于存放一些常用的工具方法

http://www.lryc.cn/news/321225.html

相关文章:

  • .Net Core 中间件验签
  • Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client
  • 七:分布式
  • 1-postgresql数据库高可用脚本详解
  • 【亲测】Onlyfans年龄认证怎么办?Onlyfans需要年龄验证?
  • ASP.NET Core新特性
  • 26-Java访问者模式 ( Visitor Pattern )
  • 电子科技大学链时代工作室招新题C语言部分---题号G
  • 体育运动直播中的智能运动跟踪和动作识别系统 - 视频分析如何协助流媒体做出实时决策
  • Avalon总线学习
  • Sentinel(熔断规则)
  • Hive借助java反射解决User-agent编码乱码问题
  • Linux下安装Android Studio及创建桌面快捷方式
  • 【析】一类动态车辆路径问题模型和两阶段算法
  • 从基础入门到学穿C++
  • 代码随想录算法训练营第二十四天|leetcode78、90、93题
  • Java学习笔记NO.20
  • 关系型数据库mysql(1)基础认知和安装
  • WanAndroid(鸿蒙版)开发的第三篇
  • 全国农产品价格分析预测可视化系统设计与实现
  • 堆排序(数据结构)
  • 使用DMA方式控制串口
  • ModbusTCP转Profinet网关高低字节交换切换
  • OpenvSwitch VXLAN 隧道实验
  • GPT能复制人类的决策和直觉吗?
  • 权限设计种类【RBAC、ABAC】
  • C语言经典面试题目(十九)
  • VSCode 远程调试C++程序打开/dev/tty设备失败的问题记录
  • 亮相AWE 2024,日立中央空调打造定制空气新体验
  • KY61 放苹果(用Java实现)