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