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