gitlab.com/flarenetwork/coreth@v0.1.1/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 32 "github.com/ethereum/go-ethereum/common" 33 "github.com/holiman/uint256" 34 "gitlab.com/flarenetwork/coreth/core/types" 35 "gitlab.com/flarenetwork/coreth/params" 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 opSha3(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 opBalanceMultiCoin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 279 addr, cid := scope.Stack.pop(), scope.Stack.pop() 280 res, err := uint256.FromBig(interpreter.evm.StateDB.GetBalanceMultiCoin( 281 common.BigToAddress(addr.ToBig()), common.BigToHash(cid.ToBig()))) 282 if err { 283 return nil, errors.New("balance overflow") 284 } 285 scope.Stack.push(res) 286 return nil, nil 287 } 288 289 func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 290 scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes())) 291 return nil, nil 292 } 293 func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 294 scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes())) 295 return nil, nil 296 } 297 298 func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 299 v, _ := uint256.FromBig(scope.Contract.value) 300 scope.Stack.push(v) 301 return nil, nil 302 } 303 304 func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 305 x := scope.Stack.peek() 306 if offset, overflow := x.Uint64WithOverflow(); !overflow { 307 data := getData(scope.Contract.Input, offset, 32) 308 x.SetBytes(data) 309 } else { 310 x.Clear() 311 } 312 return nil, nil 313 } 314 315 func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 316 scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input)))) 317 return nil, nil 318 } 319 320 func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 321 var ( 322 memOffset = scope.Stack.pop() 323 dataOffset = scope.Stack.pop() 324 length = scope.Stack.pop() 325 ) 326 dataOffset64, overflow := dataOffset.Uint64WithOverflow() 327 if overflow { 328 dataOffset64 = 0xffffffffffffffff 329 } 330 // These values are checked for overflow during gas cost calculation 331 memOffset64 := memOffset.Uint64() 332 length64 := length.Uint64() 333 scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64)) 334 335 return nil, nil 336 } 337 338 func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 339 scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData)))) 340 return nil, nil 341 } 342 343 func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 344 var ( 345 memOffset = scope.Stack.pop() 346 dataOffset = scope.Stack.pop() 347 length = scope.Stack.pop() 348 ) 349 350 offset64, overflow := dataOffset.Uint64WithOverflow() 351 if overflow { 352 return nil, ErrReturnDataOutOfBounds 353 } 354 // we can reuse dataOffset now (aliasing it for clarity) 355 var end = dataOffset 356 end.Add(&dataOffset, &length) 357 end64, overflow := end.Uint64WithOverflow() 358 if overflow || uint64(len(interpreter.returnData)) < end64 { 359 return nil, ErrReturnDataOutOfBounds 360 } 361 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64]) 362 return nil, nil 363 } 364 365 func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 366 slot := scope.Stack.peek() 367 slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) 368 return nil, nil 369 } 370 371 func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 372 l := new(uint256.Int) 373 l.SetUint64(uint64(len(scope.Contract.Code))) 374 scope.Stack.push(l) 375 return nil, nil 376 } 377 378 func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 379 var ( 380 memOffset = scope.Stack.pop() 381 codeOffset = scope.Stack.pop() 382 length = scope.Stack.pop() 383 ) 384 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 385 if overflow { 386 uint64CodeOffset = 0xffffffffffffffff 387 } 388 codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64()) 389 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 390 391 return nil, nil 392 } 393 394 func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 395 var ( 396 stack = scope.Stack 397 a = stack.pop() 398 memOffset = stack.pop() 399 codeOffset = stack.pop() 400 length = stack.pop() 401 ) 402 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 403 if overflow { 404 uint64CodeOffset = 0xffffffffffffffff 405 } 406 addr := common.Address(a.Bytes20()) 407 codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) 408 scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 409 410 return nil, nil 411 } 412 413 // opExtCodeHash returns the code hash of a specified account. 414 // There are several cases when the function is called, while we can relay everything 415 // to `state.GetCodeHash` function to ensure the correctness. 416 // (1) Caller tries to get the code hash of a normal contract account, state 417 // should return the relative code hash and set it as the result. 418 // 419 // (2) Caller tries to get the code hash of a non-existent account, state should 420 // return common.Hash{} and zero will be set as the result. 421 // 422 // (3) Caller tries to get the code hash for an account without contract code, 423 // state should return emptyCodeHash(0xc5d246...) as the result. 424 // 425 // (4) Caller tries to get the code hash of a precompiled account, the result 426 // should be zero or emptyCodeHash. 427 // 428 // It is worth noting that in order to avoid unnecessary create and clean, 429 // all precompile accounts on mainnet have been transferred 1 wei, so the return 430 // here should be emptyCodeHash. 431 // If the precompile account is not transferred any amount on a private or 432 // customized chain, the return value will be zero. 433 // 434 // (5) Caller tries to get the code hash for an account which is marked as suicided 435 // in the current transaction, the code hash of this account should be returned. 436 // 437 // (6) Caller tries to get the code hash for an account which is marked as deleted, 438 // this account should be regarded as a non-existent account and zero should be returned. 439 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 440 slot := scope.Stack.peek() 441 address := common.Address(slot.Bytes20()) 442 if interpreter.evm.StateDB.Empty(address) { 443 slot.Clear() 444 } else { 445 slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) 446 } 447 return nil, nil 448 } 449 450 func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 451 v, _ := uint256.FromBig(interpreter.evm.GasPrice) 452 scope.Stack.push(v) 453 return nil, nil 454 } 455 456 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 457 num := scope.Stack.peek() 458 num64, overflow := num.Uint64WithOverflow() 459 if overflow { 460 num.Clear() 461 return nil, nil 462 } 463 var upper, lower uint64 464 upper = interpreter.evm.Context.BlockNumber.Uint64() 465 if upper < 257 { 466 lower = 0 467 } else { 468 lower = upper - 256 469 } 470 if num64 >= lower && num64 < upper { 471 num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) 472 } else { 473 num.Clear() 474 } 475 return nil, nil 476 } 477 478 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 479 scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) 480 return nil, nil 481 } 482 483 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 484 v, _ := uint256.FromBig(interpreter.evm.Context.Time) 485 scope.Stack.push(v) 486 return nil, nil 487 } 488 489 func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 490 v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber) 491 scope.Stack.push(v) 492 return nil, nil 493 } 494 495 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 496 v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty) 497 scope.Stack.push(v) 498 return nil, nil 499 } 500 501 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 502 scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit)) 503 return nil, nil 504 } 505 506 func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 507 scope.Stack.pop() 508 return nil, nil 509 } 510 511 func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 512 v := scope.Stack.peek() 513 offset := int64(v.Uint64()) 514 v.SetBytes(scope.Memory.GetPtr(offset, 32)) 515 return nil, nil 516 } 517 518 func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 519 // pop value of the stack 520 mStart, val := scope.Stack.pop(), scope.Stack.pop() 521 scope.Memory.Set32(mStart.Uint64(), &val) 522 return nil, nil 523 } 524 525 func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 526 off, val := scope.Stack.pop(), scope.Stack.pop() 527 scope.Memory.store[off.Uint64()] = byte(val.Uint64()) 528 return nil, nil 529 } 530 531 func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 532 loc := scope.Stack.peek() 533 hash := common.Hash(loc.Bytes32()) 534 val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash) 535 loc.SetBytes(val.Bytes()) 536 return nil, nil 537 } 538 539 func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 540 loc := scope.Stack.pop() 541 val := scope.Stack.pop() 542 interpreter.evm.StateDB.SetState(scope.Contract.Address(), 543 loc.Bytes32(), val.Bytes32()) 544 return nil, nil 545 } 546 547 func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 548 pos := scope.Stack.pop() 549 if !scope.Contract.validJumpdest(&pos) { 550 return nil, ErrInvalidJump 551 } 552 *pc = pos.Uint64() 553 return nil, nil 554 } 555 556 func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 557 pos, cond := scope.Stack.pop(), scope.Stack.pop() 558 if !cond.IsZero() { 559 if !scope.Contract.validJumpdest(&pos) { 560 return nil, ErrInvalidJump 561 } 562 *pc = pos.Uint64() 563 } else { 564 *pc++ 565 } 566 return nil, nil 567 } 568 569 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 570 return nil, nil 571 } 572 573 func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 574 scope.Stack.push(new(uint256.Int).SetUint64(*pc)) 575 return nil, nil 576 } 577 578 func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 579 scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len()))) 580 return nil, nil 581 } 582 583 func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 584 scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas)) 585 return nil, nil 586 } 587 588 func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 589 var ( 590 value = scope.Stack.pop() 591 offset, size = scope.Stack.pop(), scope.Stack.pop() 592 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 593 gas = scope.Contract.Gas 594 ) 595 if interpreter.evm.chainRules.IsEIP150 { 596 gas -= gas / 64 597 } 598 // reuse size int for stackvalue 599 stackvalue := size 600 601 scope.Contract.UseGas(gas) 602 //TODO: use uint256.Int instead of converting with toBig() 603 var bigVal = big0 604 if !value.IsZero() { 605 bigVal = value.ToBig() 606 } 607 608 res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal) 609 // Push item on the stack based on the returned error. If the ruleset is 610 // homestead we must check for CodeStoreOutOfGasError (homestead only 611 // rule) and treat as an error, if the ruleset is frontier we must 612 // ignore this error and pretend the operation was successful. 613 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 614 stackvalue.Clear() 615 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 616 stackvalue.Clear() 617 } else { 618 stackvalue.SetBytes(addr.Bytes()) 619 } 620 scope.Stack.push(&stackvalue) 621 scope.Contract.Gas += returnGas 622 623 if suberr == ErrExecutionReverted { 624 return res, nil 625 } 626 return nil, nil 627 } 628 629 func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 630 var ( 631 endowment = scope.Stack.pop() 632 offset, size = scope.Stack.pop(), scope.Stack.pop() 633 salt = scope.Stack.pop() 634 input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 635 gas = scope.Contract.Gas 636 ) 637 638 // Apply EIP150 639 gas -= gas / 64 640 scope.Contract.UseGas(gas) 641 // reuse size int for stackvalue 642 stackvalue := size 643 //TODO: use uint256.Int instead of converting with toBig() 644 bigEndowment := big0 645 if !endowment.IsZero() { 646 bigEndowment = endowment.ToBig() 647 } 648 res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, 649 bigEndowment, &salt) 650 // Push item on the stack based on the returned error. 651 if suberr != nil { 652 stackvalue.Clear() 653 } else { 654 stackvalue.SetBytes(addr.Bytes()) 655 } 656 scope.Stack.push(&stackvalue) 657 scope.Contract.Gas += returnGas 658 659 if suberr == ErrExecutionReverted { 660 return res, nil 661 } 662 return nil, nil 663 } 664 665 func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 666 stack := scope.Stack 667 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 668 // We can use this as a temporary value 669 temp := stack.pop() 670 gas := interpreter.evm.callGasTemp 671 // Pop other call parameters. 672 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 673 toAddr := common.Address(addr.Bytes20()) 674 // Get the arguments from the memory. 675 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 676 677 var bigVal = big0 678 //TODO: use uint256.Int instead of converting with toBig() 679 // By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls), 680 // but it would make more sense to extend the usage of uint256.Int 681 if !value.IsZero() { 682 gas += params.CallStipend 683 bigVal = value.ToBig() 684 } 685 686 ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal) 687 688 if err != nil { 689 temp.Clear() 690 } else { 691 temp.SetOne() 692 } 693 stack.push(&temp) 694 if err == nil || err == ErrExecutionReverted { 695 ret = common.CopyBytes(ret) 696 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 697 } 698 scope.Contract.Gas += returnGas 699 700 return ret, nil 701 } 702 703 func opCallExpert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 704 stack := scope.Stack 705 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 706 // We can use this as a temporary value 707 temp := stack.pop() 708 gas := interpreter.evm.callGasTemp 709 // Pop other call parameters. 710 addr, value, cid, value2, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 711 toAddr := common.Address(addr.Bytes20()) 712 coinID := common.BigToHash(cid.ToBig()) 713 // Get the arguments from the memory. 714 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 715 716 var bigVal = big0 717 //TODO: use uint256.Int instead of converting with toBig() 718 // By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls), 719 // but it would make more sense to extend the usage of uint256.Int 720 if !value.IsZero() { 721 gas += params.CallStipend 722 bigVal = value.ToBig() 723 } 724 725 var bigVal2 = big0 726 //TODO: use uint256.Int instead of converting with toBig() 727 // By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls), 728 // but it would make more sense to extend the usage of uint256.Int 729 if !value2.IsZero() { 730 bigVal2 = value2.ToBig() 731 } 732 733 ret, returnGas, err := interpreter.evm.CallExpert(scope.Contract, toAddr, args, gas, bigVal, &coinID, bigVal2) 734 735 if err != nil { 736 temp.Clear() 737 } else { 738 temp.SetOne() 739 } 740 stack.push(&temp) 741 if err == nil || err == ErrExecutionReverted { 742 ret = common.CopyBytes(ret) 743 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 744 } 745 scope.Contract.Gas += returnGas 746 747 return ret, nil 748 } 749 func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 750 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 751 stack := scope.Stack 752 // We use it as a temporary value 753 temp := stack.pop() 754 gas := interpreter.evm.callGasTemp 755 // Pop other call parameters. 756 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 757 toAddr := common.Address(addr.Bytes20()) 758 // Get arguments from the memory. 759 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 760 761 //TODO: use uint256.Int instead of converting with toBig() 762 var bigVal = big0 763 if !value.IsZero() { 764 gas += params.CallStipend 765 bigVal = value.ToBig() 766 } 767 768 ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal) 769 if err != nil { 770 temp.Clear() 771 } else { 772 temp.SetOne() 773 } 774 stack.push(&temp) 775 if err == nil || err == ErrExecutionReverted { 776 ret = common.CopyBytes(ret) 777 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 778 } 779 scope.Contract.Gas += returnGas 780 781 return ret, nil 782 } 783 784 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 785 stack := scope.Stack 786 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 787 // We use it as a temporary value 788 temp := stack.pop() 789 gas := interpreter.evm.callGasTemp 790 // Pop other call parameters. 791 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 792 toAddr := common.Address(addr.Bytes20()) 793 // Get arguments from the memory. 794 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 795 796 ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) 797 if err != nil { 798 temp.Clear() 799 } else { 800 temp.SetOne() 801 } 802 stack.push(&temp) 803 if err == nil || err == ErrExecutionReverted { 804 ret = common.CopyBytes(ret) 805 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 806 } 807 scope.Contract.Gas += returnGas 808 809 return ret, nil 810 } 811 812 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 813 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 814 stack := scope.Stack 815 // We use it as a temporary value 816 temp := stack.pop() 817 gas := interpreter.evm.callGasTemp 818 // Pop other call parameters. 819 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 820 toAddr := common.Address(addr.Bytes20()) 821 // Get arguments from the memory. 822 args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 823 824 ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) 825 if err != nil { 826 temp.Clear() 827 } else { 828 temp.SetOne() 829 } 830 stack.push(&temp) 831 if err == nil || err == ErrExecutionReverted { 832 ret = common.CopyBytes(ret) 833 scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 834 } 835 scope.Contract.Gas += returnGas 836 837 return ret, nil 838 } 839 840 func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 841 offset, size := scope.Stack.pop(), scope.Stack.pop() 842 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 843 844 return ret, nil 845 } 846 847 func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 848 offset, size := scope.Stack.pop(), scope.Stack.pop() 849 ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 850 851 return ret, nil 852 } 853 854 func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 855 return nil, nil 856 } 857 858 func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 859 beneficiary := scope.Stack.pop() 860 balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) 861 interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) 862 interpreter.evm.StateDB.Suicide(scope.Contract.Address()) 863 return nil, nil 864 } 865 866 // following functions are used by the instruction jump table 867 868 // make log instruction function 869 func makeLog(size int) executionFunc { 870 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 871 topics := make([]common.Hash, size) 872 stack := scope.Stack 873 mStart, mSize := stack.pop(), stack.pop() 874 for i := 0; i < size; i++ { 875 addr := stack.pop() 876 topics[i] = addr.Bytes32() 877 } 878 879 d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) 880 interpreter.evm.StateDB.AddLog(&types.Log{ 881 Address: scope.Contract.Address(), 882 Topics: topics, 883 Data: d, 884 // This is a non-consensus field, but assigned here because 885 // core/state doesn't know the current block number. 886 BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(), 887 }) 888 889 return nil, nil 890 } 891 } 892 893 // opPush1 is a specialized version of pushN 894 func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 895 var ( 896 codeLen = uint64(len(scope.Contract.Code)) 897 integer = new(uint256.Int) 898 ) 899 *pc += 1 900 if *pc < codeLen { 901 scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) 902 } else { 903 scope.Stack.push(integer.Clear()) 904 } 905 return nil, nil 906 } 907 908 // make push instruction function 909 func makePush(size uint64, pushByteSize int) executionFunc { 910 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 911 codeLen := len(scope.Contract.Code) 912 913 startMin := codeLen 914 if int(*pc+1) < startMin { 915 startMin = int(*pc + 1) 916 } 917 918 endMin := codeLen 919 if startMin+pushByteSize < endMin { 920 endMin = startMin + pushByteSize 921 } 922 923 integer := new(uint256.Int) 924 scope.Stack.push(integer.SetBytes(common.RightPadBytes( 925 scope.Contract.Code[startMin:endMin], pushByteSize))) 926 927 *pc += size 928 return nil, nil 929 } 930 } 931 932 // make dup instruction function 933 func makeDup(size int64) executionFunc { 934 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 935 scope.Stack.dup(int(size)) 936 return nil, nil 937 } 938 } 939 940 // make swap instruction function 941 func makeSwap(size int64) executionFunc { 942 // switch n + 1 otherwise n would be swapped with n 943 size++ 944 return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { 945 scope.Stack.swap(int(size)) 946 return nil, nil 947 } 948 }