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