github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/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/kisexp/xdchain/common" 21 "github.com/kisexp/xdchain/core/types" 22 "github.com/kisexp/xdchain/params" 23 "github.com/holiman/uint256" 24 "golang.org/x/crypto/sha3" 25 ) 26 27 func opAdd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 28 x, y := callContext.stack.pop(), callContext.stack.peek() 29 y.Add(&x, y) 30 return nil, nil 31 } 32 33 func opSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 34 x, y := callContext.stack.pop(), callContext.stack.peek() 35 y.Sub(&x, y) 36 return nil, nil 37 } 38 39 func opMul(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 40 x, y := callContext.stack.pop(), callContext.stack.peek() 41 y.Mul(&x, y) 42 return nil, nil 43 } 44 45 func opDiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 46 x, y := callContext.stack.pop(), callContext.stack.peek() 47 y.Div(&x, y) 48 return nil, nil 49 } 50 51 func opSdiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 52 x, y := callContext.stack.pop(), callContext.stack.peek() 53 y.SDiv(&x, y) 54 return nil, nil 55 } 56 57 func opMod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 58 x, y := callContext.stack.pop(), callContext.stack.peek() 59 y.Mod(&x, y) 60 return nil, nil 61 } 62 63 func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 64 x, y := callContext.stack.pop(), callContext.stack.peek() 65 y.SMod(&x, y) 66 return nil, nil 67 } 68 69 func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 70 base, exponent := callContext.stack.pop(), callContext.stack.peek() 71 exponent.Exp(&base, exponent) 72 return nil, nil 73 } 74 75 func opSignExtend(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 76 back, num := callContext.stack.pop(), callContext.stack.peek() 77 num.ExtendSign(num, &back) 78 return nil, nil 79 } 80 81 func opNot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 82 x := callContext.stack.peek() 83 x.Not(x) 84 return nil, nil 85 } 86 87 func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 88 x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 98 x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 108 x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 118 x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 128 x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 138 x := callContext.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, callContext *callCtx) ([]byte, error) { 148 x, y := callContext.stack.pop(), callContext.stack.peek() 149 y.And(&x, y) 150 return nil, nil 151 } 152 153 func opOr(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 154 x, y := callContext.stack.pop(), callContext.stack.peek() 155 y.Or(&x, y) 156 return nil, nil 157 } 158 159 func opXor(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 160 x, y := callContext.stack.pop(), callContext.stack.peek() 161 y.Xor(&x, y) 162 return nil, nil 163 } 164 165 func opByte(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 166 th, val := callContext.stack.pop(), callContext.stack.peek() 167 val.Byte(&th) 168 return nil, nil 169 } 170 171 func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 172 x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 182 x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.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, callContext *callCtx) ([]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 := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]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 := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) { 219 shift, value := callContext.stack.pop(), callContext.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 opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 235 offset, size := callContext.stack.pop(), callContext.stack.peek() 236 data := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 237 238 if interpreter.hasher == nil { 239 interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) 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.vmConfig.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, callContext *callCtx) ([]byte, error) { 255 callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Address().Bytes())) 256 return nil, nil 257 } 258 259 func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 260 slot := callContext.stack.peek() 261 addr := common.Address(slot.Bytes20()) 262 // Quorum: get public/private state db based on addr 263 balance := getDualState(interpreter.evm, addr).GetBalance(addr) 264 slot.SetFromBig(balance) 265 return nil, nil 266 } 267 268 func opOrigin(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 269 callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes())) 270 return nil, nil 271 } 272 func opCaller(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 273 callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Caller().Bytes())) 274 return nil, nil 275 } 276 277 func opCallValue(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 278 v, _ := uint256.FromBig(callContext.contract.value) 279 callContext.stack.push(v) 280 return nil, nil 281 } 282 283 func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 284 x := callContext.stack.peek() 285 if offset, overflow := x.Uint64WithOverflow(); !overflow { 286 data := getData(callContext.contract.Input, offset, 32) 287 x.SetBytes(data) 288 } else { 289 x.Clear() 290 } 291 return nil, nil 292 } 293 294 func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 295 callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(callContext.contract.Input)))) 296 return nil, nil 297 } 298 299 func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 300 var ( 301 memOffset = callContext.stack.pop() 302 dataOffset = callContext.stack.pop() 303 length = callContext.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 callContext.memory.Set(memOffset64, length64, getData(callContext.contract.Input, dataOffset64, length64)) 313 314 return nil, nil 315 } 316 317 func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 318 callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData)))) 319 return nil, nil 320 } 321 322 func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 323 var ( 324 memOffset = callContext.stack.pop() 325 dataOffset = callContext.stack.pop() 326 length = callContext.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 callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64]) 341 return nil, nil 342 } 343 344 func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 345 slot := callContext.stack.peek() 346 addr := slot.Bytes20() 347 // Quorum: get public/private state db based on addr 348 slot.SetUint64(uint64(getDualState(interpreter.evm, addr).GetCodeSize(addr))) 349 return nil, nil 350 } 351 352 func opCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 353 l := new(uint256.Int) 354 l.SetUint64(uint64(len(callContext.contract.Code))) 355 callContext.stack.push(l) 356 return nil, nil 357 } 358 359 func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 360 var ( 361 memOffset = callContext.stack.pop() 362 codeOffset = callContext.stack.pop() 363 length = callContext.stack.pop() 364 ) 365 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 366 if overflow { 367 uint64CodeOffset = 0xffffffffffffffff 368 } 369 codeCopy := getData(callContext.contract.Code, uint64CodeOffset, length.Uint64()) 370 callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 371 372 return nil, nil 373 } 374 375 func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 376 var ( 377 stack = callContext.stack 378 a = stack.pop() 379 memOffset = stack.pop() 380 codeOffset = stack.pop() 381 length = stack.pop() 382 ) 383 uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() 384 if overflow { 385 uint64CodeOffset = 0xffffffffffffffff 386 } 387 addr := common.Address(a.Bytes20()) 388 codeCopy := getData(getDualState(interpreter.evm, addr).GetCode(addr), uint64CodeOffset, length.Uint64()) 389 // Quorum: get public/private state db based on addr 390 callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 391 392 return nil, nil 393 } 394 395 // opExtCodeHash returns the code hash of a specified account. 396 // There are several cases when the function is called, while we can relay everything 397 // to `state.GetCodeHash` function to ensure the correctness. 398 // (1) Caller tries to get the code hash of a normal contract account, state 399 // should return the relative code hash and set it as the result. 400 // 401 // (2) Caller tries to get the code hash of a non-existent account, state should 402 // return common.Hash{} and zero will be set as the result. 403 // 404 // (3) Caller tries to get the code hash for an account without contract code, 405 // state should return emptyCodeHash(0xc5d246...) as the result. 406 // 407 // (4) Caller tries to get the code hash of a precompiled account, the result 408 // should be zero or emptyCodeHash. 409 // 410 // It is worth noting that in order to avoid unnecessary create and clean, 411 // all precompile accounts on mainnet have been transferred 1 wei, so the return 412 // here should be emptyCodeHash. 413 // If the precompile account is not transferred any amount on a private or 414 // customized chain, the return value will be zero. 415 // 416 // (5) Caller tries to get the code hash for an account which is marked as suicided 417 // in the current transaction, the code hash of this account should be returned. 418 // 419 // (6) Caller tries to get the code hash for an account which is marked as deleted, 420 // this account should be regarded as a non-existent account and zero should be returned. 421 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 422 slot := callContext.stack.peek() 423 address := common.Address(slot.Bytes20()) 424 stateDB := getDualState(interpreter.evm, address) 425 if stateDB.Empty(address) { 426 slot.Clear() 427 } else { 428 slot.SetBytes(stateDB.GetCodeHash(address).Bytes()) 429 } 430 return nil, nil 431 } 432 433 func opGasprice(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 434 v, _ := uint256.FromBig(interpreter.evm.GasPrice) 435 callContext.stack.push(v) 436 return nil, nil 437 } 438 439 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 440 num := callContext.stack.peek() 441 num64, overflow := num.Uint64WithOverflow() 442 if overflow { 443 num.Clear() 444 return nil, nil 445 } 446 var upper, lower uint64 447 upper = interpreter.evm.Context.BlockNumber.Uint64() 448 if upper < 257 { 449 lower = 0 450 } else { 451 lower = upper - 256 452 } 453 if num64 >= lower && num64 < upper { 454 num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) 455 } else { 456 num.Clear() 457 } 458 return nil, nil 459 } 460 461 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 462 callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) 463 return nil, nil 464 } 465 466 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 467 v, _ := uint256.FromBig(interpreter.evm.Context.Time) 468 callContext.stack.push(v) 469 return nil, nil 470 } 471 472 func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 473 v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber) 474 callContext.stack.push(v) 475 return nil, nil 476 } 477 478 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 479 v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty) 480 callContext.stack.push(v) 481 return nil, nil 482 } 483 484 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 485 callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit)) 486 return nil, nil 487 } 488 489 func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 490 callContext.stack.pop() 491 return nil, nil 492 } 493 494 func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 495 v := callContext.stack.peek() 496 offset := int64(v.Uint64()) 497 v.SetBytes(callContext.memory.GetPtr(offset, 32)) 498 return nil, nil 499 } 500 501 func opMstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 502 // pop value of the stack 503 mStart, val := callContext.stack.pop(), callContext.stack.pop() 504 callContext.memory.Set32(mStart.Uint64(), &val) 505 return nil, nil 506 } 507 508 func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 509 off, val := callContext.stack.pop(), callContext.stack.pop() 510 callContext.memory.store[off.Uint64()] = byte(val.Uint64()) 511 return nil, nil 512 } 513 514 func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 515 loc := callContext.stack.peek() 516 hash := common.Hash(loc.Bytes32()) 517 // Quorum: get public/private state db based on addr 518 val := getDualState(interpreter.evm, callContext.contract.Address()).GetState(callContext.contract.Address(), hash) 519 loc.SetBytes(val.Bytes()) 520 return nil, nil 521 } 522 523 func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 524 loc := callContext.stack.pop() 525 val := callContext.stack.pop() 526 // Quorum: get public/private state db based on addr 527 getDualState(interpreter.evm, callContext.contract.Address()).SetState(callContext.contract.Address(), 528 loc.Bytes32(), val.Bytes32()) 529 return nil, nil 530 } 531 532 func opJump(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 533 pos := callContext.stack.pop() 534 if !callContext.contract.validJumpdest(&pos) { 535 return nil, ErrInvalidJump 536 } 537 *pc = pos.Uint64() 538 return nil, nil 539 } 540 541 func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 542 pos, cond := callContext.stack.pop(), callContext.stack.pop() 543 if !cond.IsZero() { 544 if !callContext.contract.validJumpdest(&pos) { 545 return nil, ErrInvalidJump 546 } 547 *pc = pos.Uint64() 548 } else { 549 *pc++ 550 } 551 return nil, nil 552 } 553 554 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 555 return nil, nil 556 } 557 558 func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 559 return nil, ErrInvalidSubroutineEntry 560 } 561 562 func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 563 if len(callContext.rstack.data) >= 1023 { 564 return nil, ErrReturnStackExceeded 565 } 566 pos := callContext.stack.pop() 567 if !pos.IsUint64() { 568 return nil, ErrInvalidJump 569 } 570 posU64 := pos.Uint64() 571 if !callContext.contract.validJumpSubdest(posU64) { 572 return nil, ErrInvalidJump 573 } 574 callContext.rstack.push(uint32(*pc)) 575 *pc = posU64 + 1 576 return nil, nil 577 } 578 579 func opReturnSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 580 if len(callContext.rstack.data) == 0 { 581 return nil, ErrInvalidRetsub 582 } 583 // Other than the check that the return stack is not empty, there is no 584 // need to validate the pc from 'returns', since we only ever push valid 585 //values onto it via jumpsub. 586 *pc = uint64(callContext.rstack.pop()) + 1 587 return nil, nil 588 } 589 590 func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 591 callContext.stack.push(new(uint256.Int).SetUint64(*pc)) 592 return nil, nil 593 } 594 595 func opMsize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 596 callContext.stack.push(new(uint256.Int).SetUint64(uint64(callContext.memory.Len()))) 597 return nil, nil 598 } 599 600 func opGas(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 601 callContext.stack.push(new(uint256.Int).SetUint64(callContext.contract.Gas)) 602 return nil, nil 603 } 604 605 func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 606 var ( 607 value = callContext.stack.pop() 608 offset, size = callContext.stack.pop(), callContext.stack.pop() 609 input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 610 gas = callContext.contract.Gas 611 ) 612 if interpreter.evm.chainRules.IsEIP150 { 613 gas -= gas / 64 614 } 615 // reuse size int for stackvalue 616 stackvalue := size 617 618 callContext.contract.UseGas(gas) 619 //TODO: use uint256.Int instead of converting with toBig() 620 var bigVal = big0 621 if !value.IsZero() { 622 bigVal = value.ToBig() 623 } 624 625 res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, bigVal) 626 // Push item on the stack based on the returned error. If the ruleset is 627 // homestead we must check for CodeStoreOutOfGasError (homestead only 628 // rule) and treat as an error, if the ruleset is frontier we must 629 // ignore this error and pretend the operation was successful. 630 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 631 stackvalue.Clear() 632 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 633 stackvalue.Clear() 634 } else { 635 stackvalue.SetBytes(addr.Bytes()) 636 } 637 callContext.stack.push(&stackvalue) 638 callContext.contract.Gas += returnGas 639 640 if suberr == ErrExecutionReverted { 641 return res, nil 642 } 643 return nil, nil 644 } 645 646 func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 647 var ( 648 endowment = callContext.stack.pop() 649 offset, size = callContext.stack.pop(), callContext.stack.pop() 650 salt = callContext.stack.pop() 651 input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) 652 gas = callContext.contract.Gas 653 ) 654 655 // Apply EIP150 656 gas -= gas / 64 657 callContext.contract.UseGas(gas) 658 // reuse size int for stackvalue 659 stackvalue := size 660 //TODO: use uint256.Int instead of converting with toBig() 661 bigEndowment := big0 662 if !endowment.IsZero() { 663 bigEndowment = endowment.ToBig() 664 } 665 res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas, 666 bigEndowment, &salt) 667 // Push item on the stack based on the returned error. 668 if suberr != nil { 669 stackvalue.Clear() 670 } else { 671 stackvalue.SetBytes(addr.Bytes()) 672 } 673 callContext.stack.push(&stackvalue) 674 callContext.contract.Gas += returnGas 675 676 if suberr == ErrExecutionReverted { 677 return res, nil 678 } 679 return nil, nil 680 } 681 682 func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 683 stack := callContext.stack 684 // Pop gas. The actual gas in interpreter.evm.callGasTemp. 685 // We can use this as a temporary value 686 temp := stack.pop() 687 gas := interpreter.evm.callGasTemp 688 // Pop other call parameters. 689 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 690 toAddr := common.Address(addr.Bytes20()) 691 // Get the arguments from the memory. 692 args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 693 694 var bigVal = big0 695 //TODO: use uint256.Int instead of converting with toBig() 696 // By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls), 697 // but it would make more sense to extend the usage of uint256.Int 698 if !value.IsZero() { 699 gas += params.CallStipend 700 bigVal = value.ToBig() 701 } 702 703 ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, bigVal) 704 705 if err != nil { 706 temp.Clear() 707 } else { 708 temp.SetOne() 709 } 710 stack.push(&temp) 711 if err == nil || err == ErrExecutionReverted { 712 callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 713 } 714 callContext.contract.Gas += returnGas 715 716 return ret, nil 717 } 718 719 func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 720 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 721 stack := callContext.stack 722 // We use it as a temporary value 723 temp := stack.pop() 724 gas := interpreter.evm.callGasTemp 725 // Pop other call parameters. 726 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 727 toAddr := common.Address(addr.Bytes20()) 728 // Get arguments from the memory. 729 args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 730 731 //TODO: use uint256.Int instead of converting with toBig() 732 var bigVal = big0 733 if !value.IsZero() { 734 gas += params.CallStipend 735 bigVal = value.ToBig() 736 } 737 738 ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, bigVal) 739 if err != nil { 740 temp.Clear() 741 } else { 742 temp.SetOne() 743 } 744 stack.push(&temp) 745 if err == nil || err == ErrExecutionReverted { 746 callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 747 } 748 callContext.contract.Gas += returnGas 749 750 return ret, nil 751 } 752 753 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 754 stack := callContext.stack 755 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 756 // We use it as a temporary value 757 temp := stack.pop() 758 gas := interpreter.evm.callGasTemp 759 // Pop other call parameters. 760 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 761 toAddr := common.Address(addr.Bytes20()) 762 // Get arguments from the memory. 763 args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 764 765 ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas) 766 if err != nil { 767 temp.Clear() 768 } else { 769 temp.SetOne() 770 } 771 stack.push(&temp) 772 if err == nil || err == ErrExecutionReverted { 773 callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 774 } 775 callContext.contract.Gas += returnGas 776 777 return ret, nil 778 } 779 780 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 781 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 782 stack := callContext.stack 783 // We use it as a temporary value 784 temp := stack.pop() 785 gas := interpreter.evm.callGasTemp 786 // Pop other call parameters. 787 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 788 toAddr := common.Address(addr.Bytes20()) 789 // Get arguments from the memory. 790 args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) 791 792 ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas) 793 if err != nil { 794 temp.Clear() 795 } else { 796 temp.SetOne() 797 } 798 stack.push(&temp) 799 if err == nil || err == ErrExecutionReverted { 800 callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 801 } 802 callContext.contract.Gas += returnGas 803 804 return ret, nil 805 } 806 807 func opReturn(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 808 offset, size := callContext.stack.pop(), callContext.stack.pop() 809 ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 810 811 return ret, nil 812 } 813 814 func opRevert(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 815 offset, size := callContext.stack.pop(), callContext.stack.pop() 816 ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) 817 818 return ret, nil 819 } 820 821 func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 822 return nil, nil 823 } 824 825 func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 826 beneficiary := callContext.stack.pop() 827 // Quorum: get public/private state db based on addr 828 db := getDualState(interpreter.evm, callContext.contract.Address()) 829 balance := db.GetBalance(callContext.contract.Address()) 830 db.AddBalance(beneficiary.Bytes20(), balance) 831 db.Suicide(callContext.contract.Address()) 832 return nil, nil 833 } 834 835 // following functions are used by the instruction jump table 836 837 // make log instruction function 838 func makeLog(size int) executionFunc { 839 return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 840 topics := make([]common.Hash, size) 841 stack := callContext.stack 842 mStart, mSize := stack.pop(), stack.pop() 843 for i := 0; i < size; i++ { 844 addr := stack.pop() 845 topics[i] = addr.Bytes32() 846 } 847 848 d := callContext.memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) 849 interpreter.evm.StateDB.AddLog(&types.Log{ 850 Address: callContext.contract.Address(), 851 Topics: topics, 852 Data: d, 853 // This is a non-consensus field, but assigned here because 854 // core/state doesn't know the current block number. 855 BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(), 856 }) 857 858 return nil, nil 859 } 860 } 861 862 // opPush1 is a specialized version of pushN 863 func opPush1(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 864 var ( 865 codeLen = uint64(len(callContext.contract.Code)) 866 integer = new(uint256.Int) 867 ) 868 *pc += 1 869 if *pc < codeLen { 870 callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc]))) 871 } else { 872 callContext.stack.push(integer.Clear()) 873 } 874 return nil, nil 875 } 876 877 // make push instruction function 878 func makePush(size uint64, pushByteSize int) executionFunc { 879 return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 880 codeLen := len(callContext.contract.Code) 881 882 startMin := codeLen 883 if int(*pc+1) < startMin { 884 startMin = int(*pc + 1) 885 } 886 887 endMin := codeLen 888 if startMin+pushByteSize < endMin { 889 endMin = startMin + pushByteSize 890 } 891 892 integer := new(uint256.Int) 893 callContext.stack.push(integer.SetBytes(common.RightPadBytes( 894 callContext.contract.Code[startMin:endMin], pushByteSize))) 895 896 *pc += size 897 return nil, nil 898 } 899 } 900 901 // make dup instruction function 902 func makeDup(size int64) executionFunc { 903 return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 904 callContext.stack.dup(int(size)) 905 return nil, nil 906 } 907 } 908 909 // make swap instruction function 910 func makeSwap(size int64) executionFunc { 911 // switch n + 1 otherwise n would be swapped with n 912 size++ 913 return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { 914 callContext.stack.swap(int(size)) 915 return nil, nil 916 } 917 }