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