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