github.com/quinndk/ethereum_read@v0.0.0-20181211143958-29c55eec3237/go-ethereum-master_read/core/vm/interpreter.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "fmt" 21 "sync/atomic" 22 23 "github.com/ethereum/go-ethereum/common/math" 24 "github.com/ethereum/go-ethereum/params" 25 ) 26 27 // Config are the configuration options for the Interpreter 28 // 解释器配置类 29 type Config struct { 30 // Debug enabled debugging Interpreter options 31 // 启用调试 32 Debug bool 33 // Tracer is the op code logger 34 // 操作码记录器 35 Tracer Tracer 36 // NoRecursion disabled Interpreter call, callcode, 37 // delegate call and create. 38 // 禁用解释器调用,代码库调用,委托调用 39 NoRecursion bool 40 // Enable recording of SHA3/keccak preimages 41 // 启用SHA3/keccak 42 EnablePreimageRecording bool 43 // JumpTable contains the EVM instruction table. This 44 // may be left uninitialised and will be set to the default 45 // table. 46 // 操作码opcode对应的操作表 47 JumpTable [256]operation 48 } 49 50 // Interpreter is used to run Ethereum based contracts and will utilise the 51 // passed environment to query external sources for state information. 52 // The Interpreter will run the byte code VM based on the passed 53 // configuration. 54 // 用来运行智能合约的字节码 55 type Interpreter struct { 56 evm *EVM 57 // 解释器配置 58 cfg Config 59 // gas价格表,根据不同的以太坊阶段来决定 60 gasTable params.GasTable 61 intPool *intPool 62 63 readOnly bool // Whether to throw on stateful modifications 64 // 最后一个call调用的返回值 65 returnData []byte // Last CALL's return data for subsequent reuse 66 } 67 68 // NewInterpreter returns a new instance of the Interpreter. 69 // 3.创建解释器 70 func NewInterpreter(evm *EVM, cfg Config) *Interpreter { 71 // We use the STOP instruction whether to see 72 // the jump table was initialised. If it was not 73 // we'll set the default jump table. 74 if !cfg.JumpTable[STOP].valid { 75 switch { 76 case evm.ChainConfig().IsConstantinople(evm.BlockNumber): 77 cfg.JumpTable = constantinopleInstructionSet 78 case evm.ChainConfig().IsByzantium(evm.BlockNumber): 79 cfg.JumpTable = byzantiumInstructionSet 80 case evm.ChainConfig().IsHomestead(evm.BlockNumber): 81 cfg.JumpTable = homesteadInstructionSet 82 default: 83 cfg.JumpTable = frontierInstructionSet 84 } 85 } 86 87 return &Interpreter{ 88 evm: evm, 89 cfg: cfg, 90 gasTable: evm.ChainConfig().GasTable(evm.BlockNumber), 91 } 92 } 93 94 func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error { 95 if in.evm.chainRules.IsByzantium { 96 if in.readOnly { 97 // If the interpreter is operating in readonly mode, make sure no 98 // state-modifying operation is performed. The 3rd stack item 99 // for a call operation is the value. Transferring value from one 100 // account to the others means the state is modified and should also 101 // return with an error. 102 if operation.writes || (op == CALL && stack.Back(2).BitLen() > 0) { 103 return errWriteProtection 104 } 105 } 106 } 107 return nil 108 } 109 110 // Run loops and evaluates the contract's code with the given input data and returns 111 // the return byte-slice and an error if one occurred. 112 // 113 // It's important to note that any errors returned by the interpreter should be 114 // considered a revert-and-consume-all-gas operation except for 115 // errExecutionReverted which means revert-and-keep-gas-left. 116 // 执行合约代码 117 func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err error) { 118 if in.intPool == nil { 119 in.intPool = poolOfIntPools.get() 120 defer func() { 121 poolOfIntPools.put(in.intPool) 122 in.intPool = nil 123 }() 124 } 125 126 // Increment the call depth which is restricted to 1024 127 // 调用深度递增,evm执行栈的深度不能超过1024 128 in.evm.depth++ 129 defer func() { in.evm.depth-- }() 130 131 // Reset the previous call's return data. It's unimportant to preserve the old buffer 132 // as every returning call will return new data anyway. 133 // 重置上一个call的返回数据 134 in.returnData = nil 135 136 // Don't bother with the execution if there's no code. 137 // 合约代码为空 138 if len(contract.Code) == 0 { 139 return nil, nil 140 } 141 142 var ( 143 op OpCode // current opcode 144 mem = NewMemory() // bound memory 145 stack = newstack() // local stack 146 // For optimisation reason we're using uint64 as the program counter. 147 // It's theoretically possible to go above 2^64. The YP defines the PC 148 // to be uint256. Practically much less so feasible. 149 pc = uint64(0) // program counter 150 cost uint64 151 // copies used by tracer 152 pcCopy uint64 // needed for the deferred Tracer 153 gasCopy uint64 // for Tracer to log gas remaining before execution 154 logged bool // deferred Tracer should ignore already logged steps 155 ) 156 contract.Input = input 157 158 // Reclaim the stack as an int pool when the execution stops 159 // 执行停止时将栈回收为int值缓存池 160 defer func() { in.intPool.put(stack.data...) }() 161 162 if in.cfg.Debug { 163 defer func() { 164 if err != nil { 165 if !logged { 166 in.cfg.Tracer.CaptureState(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) 167 } else { 168 in.cfg.Tracer.CaptureFault(in.evm, pcCopy, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) 169 } 170 } 171 }() 172 } 173 // The Interpreter main run loop (contextual). This loop runs until either an 174 // explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during 175 // the execution of one of the operations or until the done flag is set by the 176 // parent context. 177 // 解释器主循环,循环运行直到执行显式STOP,RETURN或SELFDESTRUCT,发生错误 178 for atomic.LoadInt32(&in.evm.abort) == 0 { 179 if in.cfg.Debug { 180 // Capture pre-execution values for tracing. 181 // 捕获预执行的值进行跟踪 182 logged, pcCopy, gasCopy = false, pc, contract.Gas 183 } 184 185 // Get the operation from the jump table and validate the stack to ensure there are 186 // enough stack items available to perform the operation. 187 // 从合约的二进制数据i获取第pc个opcode操作符 opcode是以太坊虚拟机指令,一共不超过256个,正好一个byte大小能装下 188 op = contract.GetOp(pc) 189 // 从JumpTable表中查询op对应的操作 190 operation := in.cfg.JumpTable[op] 191 if !operation.valid { 192 return nil, fmt.Errorf("invalid opcode 0x%x", int(op)) 193 } 194 if err := operation.validateStack(stack); err != nil { 195 return nil, err 196 } 197 // If the operation is valid, enforce and write restrictions 198 // 操作有效,强制执行 199 if err := in.enforceRestrictions(op, operation, stack); err != nil { 200 return nil, err 201 } 202 203 var memorySize uint64 204 // calculate the new memory size and expand the memory to fit 205 // the operation 206 // 计算新的内存大小以适应操作,必要时进行扩容 207 if operation.memorySize != nil { 208 // memSize不能大于64位 209 memSize, overflow := bigUint64(operation.memorySize(stack)) 210 if overflow { 211 return nil, errGasUintOverflow 212 } 213 // memory is expanded in words of 32 bytes. Gas 214 // is also calculated in words. 215 // 扩容按32字节的字扩展 216 if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow { 217 return nil, errGasUintOverflow 218 } 219 } 220 // consume the gas and return an error if not enough gas is available. 221 // cost is explicitly set so that the capture state defer method can get the proper cost 222 // 计算执行操作所需要的gas 223 cost, err = operation.gasCost(in.gasTable, in.evm, contract, stack, mem, memorySize) 224 // gas不足 225 if err != nil || !contract.UseGas(cost) { 226 return nil, ErrOutOfGas 227 } 228 if memorySize > 0 { 229 mem.Resize(memorySize) 230 } 231 232 if in.cfg.Debug { 233 in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, contract, in.evm.depth, err) 234 logged = true 235 } 236 237 // execute the operation 238 // 执行操作 239 res, err := operation.execute(&pc, in.evm, contract, mem, stack) 240 // verifyPool is a build flag. Pool verification makes sure the integrity 241 // of the integer pool by comparing values to a default value. 242 // 验证int值缓存池 243 if verifyPool { 244 verifyIntegerPool(in.intPool) 245 } 246 // if the operation clears the return data (e.g. it has returning data) 247 // set the last return to the result of the operation. 248 // 将最后一次返回设为操作结果 249 if operation.returns { 250 in.returnData = res 251 } 252 253 switch { 254 case err != nil: 255 return nil, err 256 case operation.reverts: 257 return res, errExecutionReverted 258 case operation.halts: 259 return res, nil 260 case !operation.jumps: 261 pc++ 262 } 263 } 264 return nil, nil 265 }