以太坊源码解读(6)以太坊VM源码解读之指令集与操作码解释器

EthVM:EthVM:开源处理引擎和以太坊的区块浏览器 :high_voltage: EthVM:基于Apache Kafka的以太坊的开源处理引擎和Block Explorer :high_voltage: 由 / 提供支持 EthVM:开源处理引擎和以太坊的区块浏览器 关于 什么是EthVM? EthVM是带有客户端Block Explorer的开源区块链数据处理和分析引擎,尽管随着时间的推移将支持其他网络和分支。 EthVM由团队构建,并受(GNU Affero许可证v3的一个很小的变体)保护,并以多种语言混合编写。 我们的核心基础架构基于众所周知的语言: (块浏览器) Javascript(API /处理器) 并且还得到了流行框架的支持: 我们的区块浏览器目前处于Beta版 立即下载

以太坊指令集与操作码解释器

EVM事实是个堆栈机器。指令可能会使用栈上的数值作为参数,也会将值作为结果压入栈中,而指令的构成是由我们所编写的合约的ABI文件所生产,大致结构为

编写合约 > 生成ABI > 解析ABI得出指令集 > eth会将指令通过core/vm/opcodes.go文件中的操作码映射,映射成操作码集 > 生成一个operation[256] >

type operation struct {
   
   
    //下列函数在core/vm/jump_table.go文件中定义了模板
   //操作函数
   execute executionFunc 
   // gas函数,返回执行所需的gas
   gasCost gasFunc
   // 验证操作的堆栈(大小)
   validateStack stackValidationFunc
   // 返回操作所需的内存大小
   memorySize memorySizeFunc

   halts   bool // 指示操作是否应停止进一步执行
   jumps   bool // 指示程序计数器是否不应递增
   writes  bool // 确定此操作是否为状态修改操作
   valid   bool // 指示检索的操作是否有效和已知
   reverts bool // 确定操作是否恢复状态(隐式停止)
   returns bool // 确定操作是否设置返回的数据内容
}
type (
   executionFunc       func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, 							memory *Memory, stack *Stack) ([]byte, error)
   gasFunc             func(params.GasTable, *EVM, *Contract, *Stack, *Memory, uint64) 							(uint64, error) 
   stackValidationFunc func(*Stack) error
   memorySizeFunc      func(*Stack) *big.Int
)

根据当前的版本选择对应的操作码生成函数

var (
	frontierInstructionSet       = newFrontierInstructionSet()
	homesteadInstructionSet      = newHomesteadInstructionSet()
	byzantiumInstructionSet      = newByzantiumInstructionSet()
	constantinopleInstructionSet = newConstantinopleInstructionSet()
)

例如:家园版本

//家园阶段可以执行的指令。
func newHomesteadInstructionSet() [256]operation {
   
   
   instructionSet := newFrontierInstructionSet()
   instructionSet[DELEGATECALL] = operation{
   
   
      execute:       opDelegateCall,
      gasCost:       gasDelegateCall,
      validateStack: makeStackFunc(6, 1),
      memorySize:    memoryDelegateCall,
      valid:         true,
      returns:       true,
   }
   return instructionSet
}

这样,对evm的操作实际上是操作码对程序的操作。

core/vm/opcodes.go:部分代码,实际上就是一堆的常量操作符,这些操作符会在core/vm/jump_table.go这个文件中映射成对应的操作函数,用于执行

const (
   STOP OpCode = iota
   ADD
   MUL
   SUB
   DIV
   SDIV
   MOD
   SMOD
   ADDMOD
   MULMOD
   EXP
   SIGNEXTEND
)

// 0x10 range - comparison ops.
const (
   LT OpCode = iota + 0x10
   GT
   SLT
   SGT
   EQ
   ISZERO
   AND
   OR
   XOR
   NOT
   BYTE
   SHL
   SHR
   SAR

   SHA3 = 0x20
)

// 0x30 range - closure state.
const (
   ADDRESS OpCode = 0x30 + iota
   BALANCE
   ORIGIN
   CALLER
   CALLVALUE
   CALLDATALOAD
   CALLDATASIZE
   CALLDATACOPY
   CODESIZE
   CODECOPY
   GASPRICE
   EXTCODESIZE
   EXTCODECOPY
   RETURNDATASIZE
   RETURNDATACOPY
   EXTCODEHASH
)

// 0x40 range - block operations.
const (
   BLOCKHASH OpCode = 0x40 + iota
   COINBASE
   TIMESTAMP
   NUMBER
   DIFFICULTY
   GASLIMIT
)

// 0x50 range - 'storage' and execution.
const (
   POP OpCode = 0x50 + iota
   MLOAD
   MSTORE
   MSTORE8
   SLOAD
   SSTORE
   JUMP
   JUMPI
   PC
   MSIZE
   GAS
   JUMPDEST
)

// 0x60 range.
const (
   PUSH1 OpCode = 0x60 + iota
   PUSH2
   PUSH3
   PUSH4
   PUSH5
   PUSH6
   PUSH7
   PUSH8
   PUSH9
   PUSH10
   PUSH11
   PUSH12
   PUSH13
   PUSH14
   PUSH15
   PUSH16
   PUSH17
   PUSH18
   PUSH19
   PUSH20
   PUSH21
   PUSH22
   PUSH23
   PUSH24
   PUSH25
   PUSH26
   PUSH27
   PUSH28
   PUSH29
   PUSH30
   PUSH31
   PUSH32
   DUP1
   DUP2
   DUP3
   DUP4
   DUP5
   DUP6
   DUP7
   DUP8
   DUP9
   DUP10
   DUP11
   DUP12
   DUP13
   DUP14
   DUP15
   DUP16
   SWAP1
   SWAP2
   SWAP3
   SWAP4
   SWAP5
   SWAP6
   SWAP7
   SWAP8
   SWAP9
   SWAP10
   SWAP11
   SWAP12
   SWAP13
   SWAP14
   SWAP15
   SWAP16
)

// 0xa0 range - logging ops.
const (
   LOG0 OpCode = 0xa0 + iota
   LOG1
   LOG2
   LOG3
   LOG4
)

// unofficial opcodes used for parsing.
const (
   PUSH OpCode = 0xb0 + iota
   DUP
   SWAP
)

core/vm/jump_table.go:都是对操作码的映射解释,可以将jump理解为操作码解释器,将opcodes理解为指令解释器

func newFrontierInstructionSet() [256]operation {
   
   
   return [256]operation{
   
   
      STOP: {
   
   
         execute:       opStop,
         gasCost:       constGasFunc(0),
         validateStack: makeStackFunc(0, 0),
         halts:         true,
         valid:         true,
      },
      ADD: {
   
   
         execute:       opAdd,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      MUL: {
   
   
         execute:       opMul,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SUB: {
   
   
         execute:       opSub,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      DIV: {
   
   
         execute:       opDiv,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SDIV: {
   
   
         execute:       opSdiv,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      MOD: {
   
   
         execute:       opMod,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SMOD: {
   
   
         execute:       opSmod,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      ADDMOD: {
   
   
         execute:       opAddmod,
         gasCost:       constGasFunc(GasMidStep),
         validateStack: makeStackFunc(3, 1),
         valid:         true,
      },
      MULMOD: {
   
   
         execute:       opMulmod,
         gasCost:       constGasFunc(GasMidStep),
         validateStack: makeStackFunc(3, 1),
         valid:         true,
      },
      EXP: {
   
   
         execute:       opExp,
         gasCost:       gasExp,
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SIGNEXTEND: {
   
   
         execute:       opSignExtend,
         gasCost:       constGasFunc(GasFastStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      LT: {
   
   
         execute:       opLt,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      GT: {
   
   
         execute:       opGt,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SLT: {
   
   
         execute:       opSlt,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SGT: {
   
   
         execute:       opSgt,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      EQ: {
   
   
         execute:       opEq,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      ISZERO: {
   
   
         execute:       opIszero,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(1, 1),
         valid:         true,
      },
      AND: {
   
   
         execute:       opAnd,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      XOR: {
   
   
         execute:       opXor,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      OR: {
   
   
         execute:       opOr,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      NOT: {
   
   
         execute:       opNot,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(1, 1),
         valid:         true,
      },
      BYTE: {
   
   
         execute:       opByte,
         gasCost:       constGasFunc(GasFastestStep),
         validateStack: makeStackFunc(2, 1),
         valid:         true,
      },
      SHA3: {
   
   
         execute:       opSha3,
         gasCost:       gasSha3,
         validateStack: makeStackFunc(2, 1),
         memorySize:    memorySha3,
         valid:         true,
      },
      ADDRESS: {
   
   
         execute:       opAddress,
         gasCost:       constGasFunc(GasQuickStep),
         validateStack: makeStackFunc(0, 1),
         valid:         true,
      },
      BALANCE: {
   
   
         execute:       opBalance,
         gasCost:       gasBalance,
         validateStack: makeStackFunc(1, 1)
evm-opcodes:以太坊操作码和指令参考 立即下载

相关推荐

EVM:以太坊虚拟机(EVM)字节码反编译器

EVM字节码反编译器 解释器和反编译器,以及用于从字节码中以编程方式提取信息的其他几种工具。 用法 npm我evm 产品特点 将字节码转换为操作码 从字节码或TX数据中读取事件或函数之类的信息 从字节码中提取(如果有) API 方法 getBytecode() -获取原始字节码(不是真正有用;与输入相同) getOpcodes() -返回包括pc和pushData的操作码(如果包含) getFunctions() -使用字节码从函数签名中解析函数 getEvents() -从事件签名中以字节码解析事件 getJumpDestinations() -从JUMPDEST操作码获取程序计数器数

Open3D 教程学习指南 (持续整理)

Open3D 是一个开源库,旨在为 3D 数据处理提供高效且易用的工具。它由 Intel 开发和维护,支持多种 3D 数据处理任务,如点云处理、3D 重建、几何处理和可视化等。

Chase Blog 5925

开发者体验度量:构建DevEx评估体系的方法论与工具

在深入讨论度量方法前,我们需要明确什么是开发者体验(DevEx)。许多人将其简化为"开发工具好不好用",这是一个危险的误解。开发者体验是指开发者在完成工作过程中的整体感受和效率,它由三大核心维度组成:工具与基础设施:开发、测试、部署工具链的效能流程与协作:工作流程的顺畅度和团队协作的效率文化与成长:支持实验、学习和专业发展的环境这三个维度相互作用,共同决定了开发者能否高效且愉悦地完成工作。开发者体验不是一个目的地,而是一段持续的旅程。

2401_88760782的博客 1429

FPGA AXI DDR3读写时序调试与FIFO缓存实战解析

本文深入解析FPGA中AXI协议与DDR3的读写时序调试,重点探讨FIFO缓存在数据流控制中的关键作用。通过实战案例详细讲解突发传输中的地址对齐、数据分片等常见问题,并提供状态机设计、仿真波形分析和性能优化技巧,帮助开发者高效解决高速数据存储场景下的时序同步与数据一致性问题。

blockchain9miner的博客 1117

基于zynq在linux下的AXI-CAN实战

从petalinux的搭建,到uboot、kernel、rootfs的调试、打包提示:以下是本篇文章正文内容,下面案例可供参考本次要讲述的zynq的AXI-CAN实战小知识就说到这里了,兄弟萌要有什么指导意见或疑问可以在评论区留下"足迹"。

qq_45521099的博客 3164

软件可靠性测试与评价

本文系统介绍了软件可靠性工程的核心内容,包括可靠性概念、模型分类、测试方法和评价体系。重点解析了可靠性测试的三大步骤:定义运行剖面、设计测试用例和实施测试收集数据,并以智能安防系统为例说明具体应用。可靠性评价需结合业务场景,通过量化指标(MTBF、失效率等)和模型预测持续优化系统。文章强调可靠性需贯穿软件全生命周期,通过闭环反馈实现持续改进,为关键系统提供质量保障。

moton2017的博客 2048

【置顶】TEE从入门到精通-[目录]

此专栏讲解包含不限于optee、商用TEE、常规的安全业务设计。但主要基于optee最新代码,深度讲解和剖析各项原理和机制...

baron-周贺贺-代码改变世界ctw 6422

tongweb中间件selectApp.jsp存在任意文件上传(含批量验证poc)

tongweb中间件selectApp.jsp存在任意文件上传(含批量验证poc)

weixin_43567873的博客 1983

STM32CubeMX之DAC产成正弦波

“在之前的文章中曾经介绍过用TIM产生PWM做DAC用,STM32定时器输出PWM做DAC。部分型号的STM32单片机内部有专用的DAC,本篇文章将介绍如何用内部DAC+DMA产生正弦波...

zhang062061的专栏 1513

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: 以太坊源码分析(3)Accounts源码分析与逻辑结构之交易源码
下一篇: Java复习之-基础
Debug_lll
博客等级 码龄8年 10粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值