github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/core/vm/instructions.go (about) 1 // Copyright 2015 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 "errors" 21 "math/big" 22 23 "github.com/ethereum-optimism/optimism/l2geth/common" 24 "github.com/ethereum-optimism/optimism/l2geth/common/math" 25 "github.com/ethereum-optimism/optimism/l2geth/core/types" 26 "github.com/ethereum-optimism/optimism/l2geth/params" 27 "github.com/ethereum-optimism/optimism/l2geth/rollup/rcfg" 28 "golang.org/x/crypto/sha3" 29 ) 30 31 var ( 32 bigZero = new(big.Int) 33 tt255 = math.BigPow(2, 255) 34 errWriteProtection = errors.New("evm: write protection") 35 errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") 36 errExecutionReverted = errors.New("evm: execution reverted") 37 errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded") 38 errInvalidJump = errors.New("evm: invalid jump destination") 39 ) 40 41 func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 42 x, y := stack.pop(), stack.peek() 43 math.U256(y.Add(x, y)) 44 45 interpreter.intPool.put(x) 46 return nil, nil 47 } 48 49 func opSub(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 50 x, y := stack.pop(), stack.peek() 51 math.U256(y.Sub(x, y)) 52 53 interpreter.intPool.put(x) 54 return nil, nil 55 } 56 57 func opMul(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 58 x, y := stack.pop(), stack.pop() 59 stack.push(math.U256(x.Mul(x, y))) 60 61 interpreter.intPool.put(y) 62 63 return nil, nil 64 } 65 66 func opDiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 67 x, y := stack.pop(), stack.peek() 68 if y.Sign() != 0 { 69 math.U256(y.Div(x, y)) 70 } else { 71 y.SetUint64(0) 72 } 73 interpreter.intPool.put(x) 74 return nil, nil 75 } 76 77 func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 78 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 79 res := interpreter.intPool.getZero() 80 81 if y.Sign() == 0 || x.Sign() == 0 { 82 stack.push(res) 83 } else { 84 if x.Sign() != y.Sign() { 85 res.Div(x.Abs(x), y.Abs(y)) 86 res.Neg(res) 87 } else { 88 res.Div(x.Abs(x), y.Abs(y)) 89 } 90 stack.push(math.U256(res)) 91 } 92 interpreter.intPool.put(x, y) 93 return nil, nil 94 } 95 96 func opMod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 97 x, y := stack.pop(), stack.pop() 98 if y.Sign() == 0 { 99 stack.push(x.SetUint64(0)) 100 } else { 101 stack.push(math.U256(x.Mod(x, y))) 102 } 103 interpreter.intPool.put(y) 104 return nil, nil 105 } 106 107 func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 108 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 109 res := interpreter.intPool.getZero() 110 111 if y.Sign() == 0 { 112 stack.push(res) 113 } else { 114 if x.Sign() < 0 { 115 res.Mod(x.Abs(x), y.Abs(y)) 116 res.Neg(res) 117 } else { 118 res.Mod(x.Abs(x), y.Abs(y)) 119 } 120 stack.push(math.U256(res)) 121 } 122 interpreter.intPool.put(x, y) 123 return nil, nil 124 } 125 126 func opExp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 127 base, exponent := stack.pop(), stack.pop() 128 // some shortcuts 129 cmpToOne := exponent.Cmp(big1) 130 if cmpToOne < 0 { // Exponent is zero 131 // x ^ 0 == 1 132 stack.push(base.SetUint64(1)) 133 } else if base.Sign() == 0 { 134 // 0 ^ y, if y != 0, == 0 135 stack.push(base.SetUint64(0)) 136 } else if cmpToOne == 0 { // Exponent is one 137 // x ^ 1 == x 138 stack.push(base) 139 } else { 140 stack.push(math.Exp(base, exponent)) 141 interpreter.intPool.put(base) 142 } 143 interpreter.intPool.put(exponent) 144 return nil, nil 145 } 146 147 func opSignExtend(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 148 back := stack.pop() 149 if back.Cmp(big.NewInt(31)) < 0 { 150 bit := uint(back.Uint64()*8 + 7) 151 num := stack.pop() 152 mask := back.Lsh(common.Big1, bit) 153 mask.Sub(mask, common.Big1) 154 if num.Bit(int(bit)) > 0 { 155 num.Or(num, mask.Not(mask)) 156 } else { 157 num.And(num, mask) 158 } 159 160 stack.push(math.U256(num)) 161 } 162 163 interpreter.intPool.put(back) 164 return nil, nil 165 } 166 167 func opNot(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 168 x := stack.peek() 169 math.U256(x.Not(x)) 170 return nil, nil 171 } 172 173 func opLt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 174 x, y := stack.pop(), stack.peek() 175 if x.Cmp(y) < 0 { 176 y.SetUint64(1) 177 } else { 178 y.SetUint64(0) 179 } 180 interpreter.intPool.put(x) 181 return nil, nil 182 } 183 184 func opGt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 185 x, y := stack.pop(), stack.peek() 186 if x.Cmp(y) > 0 { 187 y.SetUint64(1) 188 } else { 189 y.SetUint64(0) 190 } 191 interpreter.intPool.put(x) 192 return nil, nil 193 } 194 195 func opSlt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 196 x, y := stack.pop(), stack.peek() 197 198 xSign := x.Cmp(tt255) 199 ySign := y.Cmp(tt255) 200 201 switch { 202 case xSign >= 0 && ySign < 0: 203 y.SetUint64(1) 204 205 case xSign < 0 && ySign >= 0: 206 y.SetUint64(0) 207 208 default: 209 if x.Cmp(y) < 0 { 210 y.SetUint64(1) 211 } else { 212 y.SetUint64(0) 213 } 214 } 215 interpreter.intPool.put(x) 216 return nil, nil 217 } 218 219 func opSgt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 220 x, y := stack.pop(), stack.peek() 221 222 xSign := x.Cmp(tt255) 223 ySign := y.Cmp(tt255) 224 225 switch { 226 case xSign >= 0 && ySign < 0: 227 y.SetUint64(0) 228 229 case xSign < 0 && ySign >= 0: 230 y.SetUint64(1) 231 232 default: 233 if x.Cmp(y) > 0 { 234 y.SetUint64(1) 235 } else { 236 y.SetUint64(0) 237 } 238 } 239 interpreter.intPool.put(x) 240 return nil, nil 241 } 242 243 func opEq(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 244 x, y := stack.pop(), stack.peek() 245 if x.Cmp(y) == 0 { 246 y.SetUint64(1) 247 } else { 248 y.SetUint64(0) 249 } 250 interpreter.intPool.put(x) 251 return nil, nil 252 } 253 254 func opIszero(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 255 x := stack.peek() 256 if x.Sign() > 0 { 257 x.SetUint64(0) 258 } else { 259 x.SetUint64(1) 260 } 261 return nil, nil 262 } 263 264 func opAnd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 265 x, y := stack.pop(), stack.pop() 266 stack.push(x.And(x, y)) 267 268 interpreter.intPool.put(y) 269 return nil, nil 270 } 271 272 func opOr(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 273 x, y := stack.pop(), stack.peek() 274 y.Or(x, y) 275 276 interpreter.intPool.put(x) 277 return nil, nil 278 } 279 280 func opXor(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 281 x, y := stack.pop(), stack.peek() 282 y.Xor(x, y) 283 284 interpreter.intPool.put(x) 285 return nil, nil 286 } 287 288 func opByte(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 289 th, val := stack.pop(), stack.peek() 290 if th.Cmp(common.Big32) < 0 { 291 b := math.Byte(val, 32, int(th.Int64())) 292 val.SetUint64(uint64(b)) 293 } else { 294 val.SetUint64(0) 295 } 296 interpreter.intPool.put(th) 297 return nil, nil 298 } 299 300 func opAddmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 301 x, y, z := stack.pop(), stack.pop(), stack.pop() 302 if z.Cmp(bigZero) > 0 { 303 x.Add(x, y) 304 x.Mod(x, z) 305 stack.push(math.U256(x)) 306 } else { 307 stack.push(x.SetUint64(0)) 308 } 309 interpreter.intPool.put(y, z) 310 return nil, nil 311 } 312 313 func opMulmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 314 x, y, z := stack.pop(), stack.pop(), stack.pop() 315 if z.Cmp(bigZero) > 0 { 316 x.Mul(x, y) 317 x.Mod(x, z) 318 stack.push(math.U256(x)) 319 } else { 320 stack.push(x.SetUint64(0)) 321 } 322 interpreter.intPool.put(y, z) 323 return nil, nil 324 } 325 326 // opSHL implements Shift Left 327 // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2, 328 // and pushes on the stack arg2 shifted to the left by arg1 number of bits. 329 func opSHL(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 330 // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards 331 shift, value := math.U256(stack.pop()), math.U256(stack.peek()) 332 defer interpreter.intPool.put(shift) // First operand back into the pool 333 334 if shift.Cmp(common.Big256) >= 0 { 335 value.SetUint64(0) 336 return nil, nil 337 } 338 n := uint(shift.Uint64()) 339 math.U256(value.Lsh(value, n)) 340 341 return nil, nil 342 } 343 344 // opSHR implements Logical Shift Right 345 // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2, 346 // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. 347 func opSHR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 348 // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards 349 shift, value := math.U256(stack.pop()), math.U256(stack.peek()) 350 defer interpreter.intPool.put(shift) // First operand back into the pool 351 352 if shift.Cmp(common.Big256) >= 0 { 353 value.SetUint64(0) 354 return nil, nil 355 } 356 n := uint(shift.Uint64()) 357 math.U256(value.Rsh(value, n)) 358 359 return nil, nil 360 } 361 362 // opSAR implements Arithmetic Shift Right 363 // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, 364 // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. 365 func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 366 // Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one 367 shift, value := math.U256(stack.pop()), math.S256(stack.pop()) 368 defer interpreter.intPool.put(shift) // First operand back into the pool 369 370 if shift.Cmp(common.Big256) >= 0 { 371 if value.Sign() >= 0 { 372 value.SetUint64(0) 373 } else { 374 value.SetInt64(-1) 375 } 376 stack.push(math.U256(value)) 377 return nil, nil 378 } 379 n := uint(shift.Uint64()) 380 value.Rsh(value, n) 381 stack.push(math.U256(value)) 382 383 return nil, nil 384 } 385 386 func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 387 offset, size := stack.pop(), stack.pop() 388 data := memory.GetPtr(offset.Int64(), size.Int64()) 389 390 if interpreter.hasher == nil { 391 interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) 392 } else { 393 interpreter.hasher.Reset() 394 } 395 interpreter.hasher.Write(data) 396 interpreter.hasher.Read(interpreter.hasherBuf[:]) 397 398 evm := interpreter.evm 399 if evm.vmConfig.EnablePreimageRecording { 400 evm.StateDB.AddPreimage(interpreter.hasherBuf, data) 401 } 402 stack.push(interpreter.intPool.get().SetBytes(interpreter.hasherBuf[:])) 403 404 interpreter.intPool.put(offset, size) 405 return nil, nil 406 } 407 408 func opAddress(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 409 stack.push(interpreter.intPool.get().SetBytes(contract.Address().Bytes())) 410 return nil, nil 411 } 412 413 func opBalance(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 414 slot := stack.peek() 415 slot.Set(interpreter.evm.StateDB.GetBalance(common.BigToAddress(slot))) 416 return nil, nil 417 } 418 419 func opOrigin(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 420 stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Origin.Bytes())) 421 return nil, nil 422 } 423 424 func opCaller(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 425 stack.push(interpreter.intPool.get().SetBytes(contract.Caller().Bytes())) 426 return nil, nil 427 } 428 429 func opCallValue(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 430 stack.push(interpreter.intPool.get().Set(contract.value)) 431 return nil, nil 432 } 433 434 func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 435 stack.push(interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) 436 return nil, nil 437 } 438 439 func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 440 stack.push(interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) 441 return nil, nil 442 } 443 444 func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 445 var ( 446 memOffset = stack.pop() 447 dataOffset = stack.pop() 448 length = stack.pop() 449 ) 450 memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) 451 452 interpreter.intPool.put(memOffset, dataOffset, length) 453 return nil, nil 454 } 455 456 func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 457 stack.push(interpreter.intPool.get().SetUint64(uint64(len(interpreter.returnData)))) 458 return nil, nil 459 } 460 461 func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 462 var ( 463 memOffset = stack.pop() 464 dataOffset = stack.pop() 465 length = stack.pop() 466 467 end = interpreter.intPool.get().Add(dataOffset, length) 468 ) 469 defer interpreter.intPool.put(memOffset, dataOffset, length, end) 470 471 if !end.IsUint64() || uint64(len(interpreter.returnData)) < end.Uint64() { 472 return nil, errReturnDataOutOfBounds 473 } 474 memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[dataOffset.Uint64():end.Uint64()]) 475 476 return nil, nil 477 } 478 479 func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 480 slot := stack.peek() 481 slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) 482 483 return nil, nil 484 } 485 486 func opCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 487 l := interpreter.intPool.get().SetInt64(int64(len(contract.Code))) 488 stack.push(l) 489 490 return nil, nil 491 } 492 493 func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 494 var ( 495 memOffset = stack.pop() 496 codeOffset = stack.pop() 497 length = stack.pop() 498 ) 499 codeCopy := getDataBig(contract.Code, codeOffset, length) 500 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 501 502 interpreter.intPool.put(memOffset, codeOffset, length) 503 return nil, nil 504 } 505 506 func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 507 var ( 508 addr = common.BigToAddress(stack.pop()) 509 memOffset = stack.pop() 510 codeOffset = stack.pop() 511 length = stack.pop() 512 ) 513 codeCopy := getDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length) 514 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 515 516 interpreter.intPool.put(memOffset, codeOffset, length) 517 return nil, nil 518 } 519 520 // opExtCodeHash returns the code hash of a specified account. 521 // There are several cases when the function is called, while we can relay everything 522 // to `state.GetCodeHash` function to ensure the correctness. 523 // (1) Caller tries to get the code hash of a normal contract account, state 524 // should return the relative code hash and set it as the result. 525 // 526 // (2) Caller tries to get the code hash of a non-existent account, state should 527 // return common.Hash{} and zero will be set as the result. 528 // 529 // (3) Caller tries to get the code hash for an account without contract code, 530 // state should return emptyCodeHash(0xc5d246...) as the result. 531 // 532 // (4) Caller tries to get the code hash of a precompiled account, the result 533 // should be zero or emptyCodeHash. 534 // 535 // It is worth noting that in order to avoid unnecessary create and clean, 536 // all precompile accounts on mainnet have been transferred 1 wei, so the return 537 // here should be emptyCodeHash. 538 // If the precompile account is not transferred any amount on a private or 539 // customized chain, the return value will be zero. 540 // 541 // (5) Caller tries to get the code hash for an account which is marked as suicided 542 // in the current transaction, the code hash of this account should be returned. 543 // 544 // (6) Caller tries to get the code hash for an account which is marked as deleted, 545 // this account should be regarded as a non-existent account and zero should be returned. 546 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 547 slot := stack.peek() 548 address := common.BigToAddress(slot) 549 if interpreter.evm.StateDB.Empty(address) { 550 slot.SetUint64(0) 551 } else { 552 slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) 553 } 554 return nil, nil 555 } 556 557 func opGasprice(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 558 stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice)) 559 return nil, nil 560 } 561 562 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 563 num := stack.pop() 564 565 n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257) 566 if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 { 567 stack.push(interpreter.evm.GetHash(num.Uint64()).Big()) 568 } else { 569 stack.push(interpreter.intPool.getZero()) 570 } 571 interpreter.intPool.put(num, n) 572 return nil, nil 573 } 574 575 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 576 stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Coinbase.Bytes())) 577 return nil, nil 578 } 579 580 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 581 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time))) 582 return nil, nil 583 } 584 585 func opNumber(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 586 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber))) 587 return nil, nil 588 } 589 590 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 591 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty))) 592 return nil, nil 593 } 594 595 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 596 stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit))) 597 return nil, nil 598 } 599 600 func opPop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 601 interpreter.intPool.put(stack.pop()) 602 return nil, nil 603 } 604 605 func opMload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 606 v := stack.peek() 607 offset := v.Int64() 608 v.SetBytes(memory.GetPtr(offset, 32)) 609 return nil, nil 610 } 611 612 func opMstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 613 // pop value of the stack 614 mStart, val := stack.pop(), stack.pop() 615 memory.Set32(mStart.Uint64(), val) 616 617 interpreter.intPool.put(mStart, val) 618 return nil, nil 619 } 620 621 func opMstore8(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 622 off, val := stack.pop().Int64(), stack.pop().Int64() 623 memory.store[off] = byte(val & 0xff) 624 625 return nil, nil 626 } 627 628 func opSload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 629 loc := stack.peek() 630 val := interpreter.evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) 631 loc.SetBytes(val.Bytes()) 632 return nil, nil 633 } 634 635 func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 636 loc := common.BigToHash(stack.pop()) 637 val := stack.pop() 638 interpreter.evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 639 640 interpreter.intPool.put(val) 641 return nil, nil 642 } 643 644 func opJump(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 645 pos := stack.pop() 646 if !contract.validJumpdest(pos) { 647 return nil, errInvalidJump 648 } 649 *pc = pos.Uint64() 650 651 interpreter.intPool.put(pos) 652 return nil, nil 653 } 654 655 func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 656 pos, cond := stack.pop(), stack.pop() 657 if cond.Sign() != 0 { 658 if !contract.validJumpdest(pos) { 659 return nil, errInvalidJump 660 } 661 *pc = pos.Uint64() 662 } else { 663 *pc++ 664 } 665 666 interpreter.intPool.put(pos, cond) 667 return nil, nil 668 } 669 670 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 671 return nil, nil 672 } 673 674 func opPc(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 675 stack.push(interpreter.intPool.get().SetUint64(*pc)) 676 return nil, nil 677 } 678 679 func opMsize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 680 stack.push(interpreter.intPool.get().SetInt64(int64(memory.Len()))) 681 return nil, nil 682 } 683 684 func opGas(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 685 stack.push(interpreter.intPool.get().SetUint64(contract.Gas)) 686 return nil, nil 687 } 688 689 func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 690 var ( 691 value = stack.pop() 692 offset, size = stack.pop(), stack.pop() 693 input = memory.GetCopy(offset.Int64(), size.Int64()) 694 gas = contract.Gas 695 ) 696 if interpreter.evm.chainRules.IsEIP150 { 697 gas -= gas / 64 698 } 699 700 contract.UseGas(gas) 701 res, addr, returnGas, suberr := interpreter.evm.Create(contract, input, gas, value) 702 // Push item on the stack based on the returned error. If the ruleset is 703 // homestead we must check for CodeStoreOutOfGasError (homestead only 704 // rule) and treat as an error, if the ruleset is frontier we must 705 // ignore this error and pretend the operation was successful. 706 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 707 stack.push(interpreter.intPool.getZero()) 708 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 709 stack.push(interpreter.intPool.getZero()) 710 } else { 711 stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) 712 } 713 contract.Gas += returnGas 714 interpreter.intPool.put(value, offset, size) 715 716 if suberr == errExecutionReverted { 717 return res, nil 718 } 719 return nil, nil 720 } 721 722 func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 723 var ( 724 endowment = stack.pop() 725 offset, size = stack.pop(), stack.pop() 726 salt = stack.pop() 727 input = memory.GetCopy(offset.Int64(), size.Int64()) 728 gas = contract.Gas 729 ) 730 731 // Apply EIP150 732 gas -= gas / 64 733 contract.UseGas(gas) 734 res, addr, returnGas, suberr := interpreter.evm.Create2(contract, input, gas, endowment, salt) 735 // Push item on the stack based on the returned error. 736 if suberr != nil { 737 stack.push(interpreter.intPool.getZero()) 738 } else { 739 stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) 740 } 741 contract.Gas += returnGas 742 interpreter.intPool.put(endowment, offset, size, salt) 743 744 if suberr == errExecutionReverted { 745 return res, nil 746 } 747 return nil, nil 748 } 749 750 func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 751 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 752 interpreter.intPool.put(stack.pop()) 753 gas := interpreter.evm.callGasTemp 754 // Pop other call parameters. 755 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 756 toAddr := common.BigToAddress(addr) 757 value = math.U256(value) 758 // Get the arguments from the memory. 759 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 760 761 if value.Sign() != 0 { 762 gas += params.CallStipend 763 } 764 ret, returnGas, err := interpreter.evm.Call(contract, toAddr, args, gas, value) 765 if err != nil { 766 stack.push(interpreter.intPool.getZero()) 767 } else { 768 stack.push(interpreter.intPool.get().SetUint64(1)) 769 } 770 if err == nil || err == errExecutionReverted { 771 ret = common.CopyBytes(ret) 772 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 773 } 774 contract.Gas += returnGas 775 776 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 777 return ret, nil 778 } 779 780 func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 781 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 782 interpreter.intPool.put(stack.pop()) 783 gas := interpreter.evm.callGasTemp 784 // Pop other call parameters. 785 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 786 toAddr := common.BigToAddress(addr) 787 value = math.U256(value) 788 // Get arguments from the memory. 789 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 790 791 if value.Sign() != 0 { 792 gas += params.CallStipend 793 } 794 ret, returnGas, err := interpreter.evm.CallCode(contract, toAddr, args, gas, value) 795 if err != nil { 796 stack.push(interpreter.intPool.getZero()) 797 } else { 798 stack.push(interpreter.intPool.get().SetUint64(1)) 799 } 800 if err == nil || err == errExecutionReverted { 801 ret = common.CopyBytes(ret) 802 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 803 } 804 contract.Gas += returnGas 805 806 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 807 return ret, nil 808 } 809 810 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 811 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 812 interpreter.intPool.put(stack.pop()) 813 gas := interpreter.evm.callGasTemp 814 // Pop other call parameters. 815 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 816 toAddr := common.BigToAddress(addr) 817 // Get arguments from the memory. 818 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 819 820 ret, returnGas, err := interpreter.evm.DelegateCall(contract, toAddr, args, gas) 821 if err != nil { 822 stack.push(interpreter.intPool.getZero()) 823 } else { 824 stack.push(interpreter.intPool.get().SetUint64(1)) 825 } 826 if err == nil || err == errExecutionReverted { 827 ret = common.CopyBytes(ret) 828 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 829 } 830 contract.Gas += returnGas 831 832 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 833 return ret, nil 834 } 835 836 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 837 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 838 interpreter.intPool.put(stack.pop()) 839 gas := interpreter.evm.callGasTemp 840 // Pop other call parameters. 841 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 842 toAddr := common.BigToAddress(addr) 843 // Get arguments from the memory. 844 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 845 846 ret, returnGas, err := interpreter.evm.StaticCall(contract, toAddr, args, gas) 847 if err != nil { 848 stack.push(interpreter.intPool.getZero()) 849 } else { 850 stack.push(interpreter.intPool.get().SetUint64(1)) 851 } 852 if err == nil || err == errExecutionReverted { 853 ret = common.CopyBytes(ret) 854 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 855 } 856 contract.Gas += returnGas 857 858 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 859 return ret, nil 860 } 861 862 func opReturn(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 863 offset, size := stack.pop(), stack.pop() 864 ret := memory.GetPtr(offset.Int64(), size.Int64()) 865 866 interpreter.intPool.put(offset, size) 867 return ret, nil 868 } 869 870 func opRevert(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 871 offset, size := stack.pop(), stack.pop() 872 ret := memory.GetPtr(offset.Int64(), size.Int64()) 873 874 interpreter.intPool.put(offset, size) 875 return ret, nil 876 } 877 878 func opStop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 879 return nil, nil 880 } 881 882 func opSuicide(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 883 balance := interpreter.evm.StateDB.GetBalance(contract.Address()) 884 interpreter.evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 885 886 interpreter.evm.StateDB.Suicide(contract.Address()) 887 if rcfg.UsingOVM && interpreter.evm.chainConfig.IsSDUpdate(interpreter.evm.BlockNumber) { 888 interpreter.evm.StateDB.SubBalance(contract.Address(), balance) 889 } 890 return nil, nil 891 } 892 893 // following functions are used by the instruction jump table 894 895 // make log instruction function 896 func makeLog(size int) executionFunc { 897 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 898 topics := make([]common.Hash, size) 899 mStart, mSize := stack.pop(), stack.pop() 900 for i := 0; i < size; i++ { 901 topics[i] = common.BigToHash(stack.pop()) 902 } 903 904 d := memory.GetCopy(mStart.Int64(), mSize.Int64()) 905 interpreter.evm.StateDB.AddLog(&types.Log{ 906 Address: contract.Address(), 907 Topics: topics, 908 Data: d, 909 // This is a non-consensus field, but assigned here because 910 // core/state doesn't know the current block number. 911 BlockNumber: interpreter.evm.BlockNumber.Uint64(), 912 }) 913 914 interpreter.intPool.put(mStart, mSize) 915 return nil, nil 916 } 917 } 918 919 // opPush1 is a specialized version of pushN 920 func opPush1(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 921 var ( 922 codeLen = uint64(len(contract.Code)) 923 integer = interpreter.intPool.get() 924 ) 925 *pc += 1 926 if *pc < codeLen { 927 stack.push(integer.SetUint64(uint64(contract.Code[*pc]))) 928 } else { 929 stack.push(integer.SetUint64(0)) 930 } 931 return nil, nil 932 } 933 934 // make push instruction function 935 func makePush(size uint64, pushByteSize int) executionFunc { 936 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 937 codeLen := len(contract.Code) 938 939 startMin := codeLen 940 if int(*pc+1) < startMin { 941 startMin = int(*pc + 1) 942 } 943 944 endMin := codeLen 945 if startMin+pushByteSize < endMin { 946 endMin = startMin + pushByteSize 947 } 948 949 integer := interpreter.intPool.get() 950 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 951 952 *pc += size 953 return nil, nil 954 } 955 } 956 957 // make dup instruction function 958 func makeDup(size int64) executionFunc { 959 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 960 stack.dup(interpreter.intPool, int(size)) 961 return nil, nil 962 } 963 } 964 965 // make swap instruction function 966 func makeSwap(size int64) executionFunc { 967 // switch n + 1 otherwise n would be swapped with n 968 size++ 969 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 970 stack.swap(int(size)) 971 return nil, nil 972 } 973 } 974 975 // OVM opcodes 976 func opL1BlockNumber(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 977 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.L1BlockNumber))) 978 return nil, nil 979 }