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