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