github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/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 codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64()) 363 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 364 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 var upper, lower uint64 438 upper = interpreter.evm.Context.BlockNumber.Uint64() 439 if upper < 257 { 440 lower = 0 441 } else { 442 lower = upper - 256 443 } 444 if num64 >= lower && num64 < upper { 445 num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) 446 } else { 447 num.Clear() 448 } 449 return nil, nil 450 } 451 452 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 453 scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) 454 return nil, nil 455 } 456 457 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 458 scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.Time)) 459 return nil, nil 460 } 461 462 func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 463 v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber) 464 scope.Stack.push(v) 465 return nil, nil 466 } 467 468 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 469 v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty) 470 scope.Stack.push(v) 471 return nil, nil 472 } 473 474 func opRandom(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 475 v := new(uint256.Int).SetBytes(interpreter.evm.Context.Random.Bytes()) 476 scope.Stack.push(v) 477 return nil, nil 478 } 479 480 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 481 scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit)) 482 return nil, nil 483 } 484 485 func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 486 scope.Stack.pop() 487 return nil, nil 488 } 489 490 func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 491 v := scope.Stack.peek() 492 offset := int64(v.Uint64()) 493 v.SetBytes(scope.Memory.GetPtr(offset, 32)) 494 return nil, nil 495 } 496 497 func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 498 // pop value of the stack 499 mStart, val := scope.Stack.pop(), scope.Stack.pop() 500 scope.Memory.Set32(mStart.Uint64(), &val) 501 return nil, nil 502 } 503 504 func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 505 off, val := scope.Stack.pop(), scope.Stack.pop() 506 scope.Memory.store[off.Uint64()] = byte(val.Uint64()) 507 return nil, nil 508 } 509 510 func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 511 loc := scope.Stack.peek() 512 hash := common.Hash(loc.Bytes32()) 513 val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash) 514 loc.SetBytes(val.Bytes()) 515 return nil, nil 516 } 517 518 func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 519 if interpreter.readOnly { 520 return nil, ErrWriteProtection 521 } 522 loc := scope.Stack.pop() 523 val := scope.Stack.pop() 524 interpreter.evm.StateDB.SetState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) 525 return nil, nil 526 } 527 528 func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 529 if interpreter.evm.abort.Load() { 530 return nil, errStopToken 531 } 532 pos := scope.Stack.pop() 533 if !scope.Contract.validJumpdest(&pos) { 534 return nil, ErrInvalidJump 535 } 536 *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop 537 return nil, nil 538 } 539 540 func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 541 if interpreter.evm.abort.Load() { 542 return nil, errStopToken 543 } 544 pos, cond := scope.Stack.pop(), scope.Stack.pop() 545 if !cond.IsZero() { 546 if !scope.Contract.validJumpdest(&pos) { 547 return nil, ErrInvalidJump 548 } 549 *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop 550 } 551 return nil, nil 552 } 553 554 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 555 return nil, nil 556 } 557 558 func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 559 scope.Stack.push(new(uint256.Int).SetUint64(*pc)) 560 return nil, nil 561 } 562 563 func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 564 scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len()))) 565 return nil, nil 566 } 567 568 func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 569 scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas)) 570 return nil, nil 571 } 572 573 func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 574 if interpreter.readOnly { 575 return nil, ErrWriteProtection 576 } 577 var ( 578 value = scope.Stack.pop() 579 offset, size = scope.Stack.pop(), scope.Stack.pop() 580 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 581 gas = scope.Contract.Gas 582 ) 583 if interpreter.evm.chainRules.IsEIP150 { 584 gas -= gas / 64 585 } 586 // reuse size int for stackvalue 587 stackvalue := size 588 589 scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation) 590 591 res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value) 592 // Push item on the stack based on the returned error. If the ruleset is 593 // homestead we must check for CodeStoreOutOfGasError (homestead only 594 // rule) and treat as an error, if the ruleset is frontier we must 595 // ignore this error and pretend the operation was successful. 596 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 597 stackvalue.Clear() 598 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 599 stackvalue.Clear() 600 } else { 601 stackvalue.SetBytes(addr.Bytes()) 602 } 603 scope.Stack.push(&stackvalue) 604 605 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 606 607 if suberr == ErrExecutionReverted { 608 interpreter.returnData = res // set REVERT data to return data buffer 609 return res, nil 610 } 611 interpreter.returnData = nil // clear dirty return data buffer 612 return nil, nil 613 } 614 615 func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 616 if interpreter.readOnly { 617 return nil, ErrWriteProtection 618 } 619 var ( 620 endowment = scope.Stack.pop() 621 offset, size = scope.Stack.pop(), scope.Stack.pop() 622 salt = scope.Stack.pop() 623 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 624 gas = scope.Contract.Gas 625 ) 626 // Apply EIP150 627 gas -= gas / 64 628 scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation2) 629 // reuse size int for stackvalue 630 stackvalue := size 631 res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, 632 &endowment, &salt) 633 // Push item on the stack based on the returned error. 634 if suberr != nil { 635 stackvalue.Clear() 636 } else { 637 stackvalue.SetBytes(addr.Bytes()) 638 } 639 scope.Stack.push(&stackvalue) 640 641 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 642 643 if suberr == ErrExecutionReverted { 644 interpreter.returnData = res // set REVERT data to return data buffer 645 return res, nil 646 } 647 interpreter.returnData = nil // clear dirty return data buffer 648 return nil, nil 649 } 650 651 func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 652 stack := scope.Stack 653 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 654 // We can use this as a temporary value 655 temp := stack.pop() 656 gas := interpreter.evm.callGasTemp 657 // Pop other call parameters. 658 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 659 toAddr := common.Address(addr.Bytes20()) 660 // Get the arguments from the memory. 661 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 662 663 if interpreter.readOnly && !value.IsZero() { 664 return nil, ErrWriteProtection 665 } 666 if !value.IsZero() { 667 gas += params.CallStipend 668 } 669 ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value) 670 671 if err != nil { 672 temp.Clear() 673 } else { 674 temp.SetOne() 675 } 676 stack.push(&temp) 677 if err == nil || err == ErrExecutionReverted { 678 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 679 } 680 681 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 682 683 interpreter.returnData = ret 684 return ret, nil 685 } 686 687 func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 688 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 689 stack := scope.Stack 690 // We use it as a temporary value 691 temp := stack.pop() 692 gas := interpreter.evm.callGasTemp 693 // Pop other call parameters. 694 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 695 toAddr := common.Address(addr.Bytes20()) 696 // Get arguments from the memory. 697 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 698 699 if !value.IsZero() { 700 gas += params.CallStipend 701 } 702 703 ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, &value) 704 if err != nil { 705 temp.Clear() 706 } else { 707 temp.SetOne() 708 } 709 stack.push(&temp) 710 if err == nil || err == ErrExecutionReverted { 711 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 712 } 713 714 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 715 716 interpreter.returnData = ret 717 return ret, nil 718 } 719 720 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 721 stack := scope.Stack 722 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 723 // We use it as a temporary value 724 temp := stack.pop() 725 gas := interpreter.evm.callGasTemp 726 // Pop other call parameters. 727 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 728 toAddr := common.Address(addr.Bytes20()) 729 // Get arguments from the memory. 730 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 731 732 ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) 733 if err != nil { 734 temp.Clear() 735 } else { 736 temp.SetOne() 737 } 738 stack.push(&temp) 739 if err == nil || err == ErrExecutionReverted { 740 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 741 } 742 743 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 744 745 interpreter.returnData = ret 746 return ret, nil 747 } 748 749 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 750 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 751 stack := scope.Stack 752 // We use it as a temporary value 753 temp := stack.pop() 754 gas := interpreter.evm.callGasTemp 755 // Pop other call parameters. 756 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 757 toAddr := common.Address(addr.Bytes20()) 758 // Get arguments from the memory. 759 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 760 761 ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) 762 if err != nil { 763 temp.Clear() 764 } else { 765 temp.SetOne() 766 } 767 stack.push(&temp) 768 if err == nil || err == ErrExecutionReverted { 769 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 770 } 771 772 scope.Contract.RefundGas(returnGas, interpreter.evm.Config.Tracer, tracing.GasChangeCallLeftOverRefunded) 773 774 interpreter.returnData = ret 775 return ret, nil 776 } 777 778 func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 779 offset, size := scope.Stack.pop(), scope.Stack.pop() 780 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 781 782 return ret, errStopToken 783 } 784 785 func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 786 offset, size := scope.Stack.pop(), scope.Stack.pop() 787 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 788 789 interpreter.returnData = ret 790 return ret, ErrExecutionReverted 791 } 792 793 func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 794 return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])} 795 } 796 797 func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 798 return nil, errStopToken 799 } 800 801 func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 802 if interpreter.readOnly { 803 return nil, ErrWriteProtection 804 } 805 beneficiary := scope.Stack.pop() 806 balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) 807 interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) 808 interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address()) 809 if tracer := interpreter.evm.Config.Tracer; tracer != nil { 810 if tracer.OnEnter != nil { 811 tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) 812 } 813 if tracer.OnExit != nil { 814 tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false) 815 } 816 } 817 return nil, errStopToken 818 } 819 820 func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 821 if interpreter.readOnly { 822 return nil, ErrWriteProtection 823 } 824 beneficiary := scope.Stack.pop() 825 balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) 826 interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct) 827 interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) 828 interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address()) 829 if tracer := interpreter.evm.Config.Tracer; tracer != nil { 830 if tracer.OnEnter != nil { 831 tracer.OnEnter(interpreter.evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) 832 } 833 if tracer.OnExit != nil { 834 tracer.OnExit(interpreter.evm.depth, []byte{}, 0, nil, false) 835 } 836 } 837 return nil, errStopToken 838 } 839 840 // following functions are used by the instruction jump table 841 842 // make log instruction function 843 func makeLog(size int) executionFunc { 844 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 845 if interpreter.readOnly { 846 return nil, ErrWriteProtection 847 } 848 topics := make([]common.Hash, size) 849 stack := scope.Stack 850 mStart, mSize := stack.pop(), stack.pop() 851 for i := 0; i < size; i++ { 852 addr := stack.pop() 853 topics[i] = addr.Bytes32() 854 } 855 856 d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) 857 interpreter.evm.StateDB.AddLog(&types.Log{ 858 Address: scope.Contract.Address(), 859 Topics: topics, 860 Data: d, 861 // This is a non-consensus field, but assigned here because 862 // core/state doesn't know the current block number. 863 BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(), 864 }) 865 866 return nil, nil 867 } 868 } 869 870 // opPush1 is a specialized version of pushN 871 func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 872 var ( 873 codeLen = uint64(len(scope.Contract.Code)) 874 integer = new(uint256.Int) 875 ) 876 *pc += 1 877 if *pc < codeLen { 878 scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) 879 } else { 880 scope.Stack.push(integer.Clear()) 881 } 882 return nil, nil 883 } 884 885 // make push instruction function 886 func makePush(size uint64, pushByteSize int) executionFunc { 887 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 888 var ( 889 codeLen = len(scope.Contract.Code) 890 start = min(codeLen, int(*pc+1)) 891 end = min(codeLen, start+pushByteSize) 892 ) 893 scope.Stack.push(new(uint256.Int).SetBytes( 894 common.RightPadBytes( 895 scope.Contract.Code[start:end], 896 pushByteSize, 897 )), 898 ) 899 *pc += size 900 return nil, nil 901 } 902 } 903 904 // make dup instruction function 905 func makeDup(size int64) executionFunc { 906 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 907 scope.Stack.dup(int(size)) 908 return nil, nil 909 } 910 } 911 912 // make swap instruction function 913 func makeSwap(size int64) executionFunc { 914 // switch n + 1 otherwise n would be swapped with n 915 size++ 916 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 917 scope.Stack.swap(int(size)) 918 return nil, nil 919 } 920 }