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