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