github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/vm/instructions.go (about) 1 package vm 2 3 import ( 4 "math/big" 5 6 "github.com/neatlab/neatio/chain/core/types" 7 "github.com/neatlab/neatio/params" 8 "github.com/neatlab/neatio/utilities/common" 9 "github.com/neatlab/neatio/utilities/common/math" 10 "golang.org/x/crypto/sha3" 11 ) 12 13 var ( 14 bigZero = new(big.Int) 15 tt255 = math.BigPow(2, 255) 16 ) 17 18 func opAdd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 19 x, y := stack.pop(), stack.peek() 20 math.U256(y.Add(x, y)) 21 22 interpreter.intPool.put(x) 23 return nil, nil 24 } 25 26 func opSub(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 27 x, y := stack.pop(), stack.peek() 28 math.U256(y.Sub(x, y)) 29 30 interpreter.intPool.put(x) 31 return nil, nil 32 } 33 34 func opMul(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 35 x, y := stack.pop(), stack.pop() 36 stack.push(math.U256(x.Mul(x, y))) 37 38 interpreter.intPool.put(y) 39 40 return nil, nil 41 } 42 43 func opDiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 44 x, y := stack.pop(), stack.peek() 45 if y.Sign() != 0 { 46 math.U256(y.Div(x, y)) 47 } else { 48 y.SetUint64(0) 49 } 50 interpreter.intPool.put(x) 51 return nil, nil 52 } 53 54 func opSdiv(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 55 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 56 res := interpreter.intPool.getZero() 57 58 if y.Sign() == 0 || x.Sign() == 0 { 59 stack.push(res) 60 } else { 61 if x.Sign() != y.Sign() { 62 res.Div(x.Abs(x), y.Abs(y)) 63 res.Neg(res) 64 } else { 65 res.Div(x.Abs(x), y.Abs(y)) 66 } 67 stack.push(math.U256(res)) 68 } 69 interpreter.intPool.put(x, y) 70 return nil, nil 71 } 72 73 func opMod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 74 x, y := stack.pop(), stack.pop() 75 if y.Sign() == 0 { 76 stack.push(x.SetUint64(0)) 77 } else { 78 stack.push(math.U256(x.Mod(x, y))) 79 } 80 interpreter.intPool.put(y) 81 return nil, nil 82 } 83 84 func opSmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 85 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 86 res := interpreter.intPool.getZero() 87 88 if y.Sign() == 0 { 89 stack.push(res) 90 } else { 91 if x.Sign() < 0 { 92 res.Mod(x.Abs(x), y.Abs(y)) 93 res.Neg(res) 94 } else { 95 res.Mod(x.Abs(x), y.Abs(y)) 96 } 97 stack.push(math.U256(res)) 98 } 99 interpreter.intPool.put(x, y) 100 return nil, nil 101 } 102 103 func opExp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 104 base, exponent := stack.pop(), stack.pop() 105 106 cmpToOne := exponent.Cmp(big1) 107 if cmpToOne < 0 { 108 109 stack.push(base.SetUint64(1)) 110 } else if base.Sign() == 0 { 111 112 stack.push(base.SetUint64(0)) 113 } else if cmpToOne == 0 { 114 115 stack.push(base) 116 } else { 117 stack.push(math.Exp(base, exponent)) 118 interpreter.intPool.put(base) 119 } 120 interpreter.intPool.put(exponent) 121 return nil, nil 122 } 123 124 func opSignExtend(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 125 back := stack.pop() 126 if back.Cmp(big.NewInt(31)) < 0 { 127 bit := uint(back.Uint64()*8 + 7) 128 num := stack.pop() 129 mask := back.Lsh(common.Big1, bit) 130 mask.Sub(mask, common.Big1) 131 if num.Bit(int(bit)) > 0 { 132 num.Or(num, mask.Not(mask)) 133 } else { 134 num.And(num, mask) 135 } 136 137 stack.push(math.U256(num)) 138 } 139 140 interpreter.intPool.put(back) 141 return nil, nil 142 } 143 144 func opNot(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 145 x := stack.peek() 146 math.U256(x.Not(x)) 147 return nil, nil 148 } 149 150 func opLt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 151 x, y := stack.pop(), stack.peek() 152 if x.Cmp(y) < 0 { 153 y.SetUint64(1) 154 } else { 155 y.SetUint64(0) 156 } 157 interpreter.intPool.put(x) 158 return nil, nil 159 } 160 161 func opGt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 162 x, y := stack.pop(), stack.peek() 163 if x.Cmp(y) > 0 { 164 y.SetUint64(1) 165 } else { 166 y.SetUint64(0) 167 } 168 interpreter.intPool.put(x) 169 return nil, nil 170 } 171 172 func opSlt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 173 x, y := stack.pop(), stack.peek() 174 175 xSign := x.Cmp(tt255) 176 ySign := y.Cmp(tt255) 177 178 switch { 179 case xSign >= 0 && ySign < 0: 180 y.SetUint64(1) 181 182 case xSign < 0 && ySign >= 0: 183 y.SetUint64(0) 184 185 default: 186 if x.Cmp(y) < 0 { 187 y.SetUint64(1) 188 } else { 189 y.SetUint64(0) 190 } 191 } 192 interpreter.intPool.put(x) 193 return nil, nil 194 } 195 196 func opSgt(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 197 x, y := stack.pop(), stack.peek() 198 199 xSign := x.Cmp(tt255) 200 ySign := y.Cmp(tt255) 201 202 switch { 203 case xSign >= 0 && ySign < 0: 204 y.SetUint64(0) 205 206 case xSign < 0 && ySign >= 0: 207 y.SetUint64(1) 208 209 default: 210 if x.Cmp(y) > 0 { 211 y.SetUint64(1) 212 } else { 213 y.SetUint64(0) 214 } 215 } 216 interpreter.intPool.put(x) 217 return nil, nil 218 } 219 220 func opEq(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 221 x, y := stack.pop(), stack.peek() 222 if x.Cmp(y) == 0 { 223 y.SetUint64(1) 224 } else { 225 y.SetUint64(0) 226 } 227 interpreter.intPool.put(x) 228 return nil, nil 229 } 230 231 func opIszero(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 232 x := stack.peek() 233 if x.Sign() > 0 { 234 x.SetUint64(0) 235 } else { 236 x.SetUint64(1) 237 } 238 return nil, nil 239 } 240 241 func opAnd(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 242 x, y := stack.pop(), stack.pop() 243 stack.push(x.And(x, y)) 244 245 interpreter.intPool.put(y) 246 return nil, nil 247 } 248 249 func opOr(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 250 x, y := stack.pop(), stack.peek() 251 y.Or(x, y) 252 253 interpreter.intPool.put(x) 254 return nil, nil 255 } 256 257 func opXor(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 258 x, y := stack.pop(), stack.peek() 259 y.Xor(x, y) 260 261 interpreter.intPool.put(x) 262 return nil, nil 263 } 264 265 func opByte(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 266 th, val := stack.pop(), stack.peek() 267 if th.Cmp(common.Big32) < 0 { 268 b := math.Byte(val, 32, int(th.Int64())) 269 val.SetUint64(uint64(b)) 270 } else { 271 val.SetUint64(0) 272 } 273 interpreter.intPool.put(th) 274 return nil, nil 275 } 276 277 func opAddmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 278 x, y, z := stack.pop(), stack.pop(), stack.pop() 279 if z.Cmp(bigZero) > 0 { 280 x.Add(x, y) 281 x.Mod(x, z) 282 stack.push(math.U256(x)) 283 } else { 284 stack.push(x.SetUint64(0)) 285 } 286 interpreter.intPool.put(y, z) 287 return nil, nil 288 } 289 290 func opMulmod(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 291 x, y, z := stack.pop(), stack.pop(), stack.pop() 292 if z.Cmp(bigZero) > 0 { 293 x.Mul(x, y) 294 x.Mod(x, z) 295 stack.push(math.U256(x)) 296 } else { 297 stack.push(x.SetUint64(0)) 298 } 299 interpreter.intPool.put(y, z) 300 return nil, nil 301 } 302 303 func opSHL(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 304 305 shift, value := math.U256(stack.pop()), math.U256(stack.peek()) 306 defer interpreter.intPool.put(shift) 307 308 if shift.Cmp(common.Big256) >= 0 { 309 value.SetUint64(0) 310 return nil, nil 311 } 312 n := uint(shift.Uint64()) 313 math.U256(value.Lsh(value, n)) 314 315 return nil, nil 316 } 317 318 func opSHR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 319 320 shift, value := math.U256(stack.pop()), math.U256(stack.peek()) 321 defer interpreter.intPool.put(shift) 322 323 if shift.Cmp(common.Big256) >= 0 { 324 value.SetUint64(0) 325 return nil, nil 326 } 327 n := uint(shift.Uint64()) 328 math.U256(value.Rsh(value, n)) 329 330 return nil, nil 331 } 332 333 func opSAR(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 334 335 shift, value := math.U256(stack.pop()), math.S256(stack.pop()) 336 defer interpreter.intPool.put(shift) 337 338 if shift.Cmp(common.Big256) >= 0 { 339 if value.Sign() >= 0 { 340 value.SetUint64(0) 341 } else { 342 value.SetInt64(-1) 343 } 344 stack.push(math.U256(value)) 345 return nil, nil 346 } 347 n := uint(shift.Uint64()) 348 value.Rsh(value, n) 349 stack.push(math.U256(value)) 350 351 return nil, nil 352 } 353 354 func opSha3(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 355 offset, size := stack.pop(), stack.pop() 356 data := memory.GetPtr(offset.Int64(), size.Int64()) 357 358 if interpreter.hasher == nil { 359 interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState) 360 } else { 361 interpreter.hasher.Reset() 362 } 363 interpreter.hasher.Write(data) 364 interpreter.hasher.Read(interpreter.hasherBuf[:]) 365 366 evm := interpreter.evm 367 if evm.vmConfig.EnablePreimageRecording { 368 evm.StateDB.AddPreimage(interpreter.hasherBuf, data) 369 } 370 stack.push(interpreter.intPool.get().SetBytes(interpreter.hasherBuf[:])) 371 372 interpreter.intPool.put(offset, size) 373 return nil, nil 374 } 375 376 func opAddress(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 377 stack.push(interpreter.intPool.get().SetBytes(contract.Address().Bytes())) 378 return nil, nil 379 } 380 381 func opBalance(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 382 slot := stack.peek() 383 slot.Set(interpreter.evm.StateDB.GetBalance(common.BigToAddress(slot))) 384 return nil, nil 385 } 386 387 func opOrigin(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 388 stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Origin.Bytes())) 389 return nil, nil 390 } 391 392 func opCaller(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 393 stack.push(interpreter.intPool.get().SetBytes(contract.Caller().Bytes())) 394 return nil, nil 395 } 396 397 func opCallValue(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 398 stack.push(interpreter.intPool.get().Set(contract.value)) 399 return nil, nil 400 } 401 402 func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 403 stack.push(interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) 404 return nil, nil 405 } 406 407 func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 408 stack.push(interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) 409 return nil, nil 410 } 411 412 func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 413 var ( 414 memOffset = stack.pop() 415 dataOffset = stack.pop() 416 length = stack.pop() 417 ) 418 memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) 419 420 interpreter.intPool.put(memOffset, dataOffset, length) 421 return nil, nil 422 } 423 424 func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 425 stack.push(interpreter.intPool.get().SetUint64(uint64(len(interpreter.returnData)))) 426 return nil, nil 427 } 428 429 func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 430 var ( 431 memOffset = stack.pop() 432 dataOffset = stack.pop() 433 length = stack.pop() 434 435 end = interpreter.intPool.get().Add(dataOffset, length) 436 ) 437 defer interpreter.intPool.put(memOffset, dataOffset, length, end) 438 439 if !end.IsUint64() || uint64(len(interpreter.returnData)) < end.Uint64() { 440 return nil, ErrReturnDataOutOfBounds 441 } 442 memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[dataOffset.Uint64():end.Uint64()]) 443 444 return nil, nil 445 } 446 447 func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 448 slot := stack.peek() 449 slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) 450 451 return nil, nil 452 } 453 454 func opCodeSize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 455 l := interpreter.intPool.get().SetInt64(int64(len(contract.Code))) 456 stack.push(l) 457 458 return nil, nil 459 } 460 461 func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 462 var ( 463 memOffset = stack.pop() 464 codeOffset = stack.pop() 465 length = stack.pop() 466 ) 467 codeCopy := getDataBig(contract.Code, codeOffset, length) 468 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 469 470 interpreter.intPool.put(memOffset, codeOffset, length) 471 return nil, nil 472 } 473 474 func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 475 var ( 476 addr = common.BigToAddress(stack.pop()) 477 memOffset = stack.pop() 478 codeOffset = stack.pop() 479 length = stack.pop() 480 ) 481 codeCopy := getDataBig(interpreter.evm.StateDB.GetCode(addr), codeOffset, length) 482 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 483 484 interpreter.intPool.put(memOffset, codeOffset, length) 485 return nil, nil 486 } 487 488 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 489 slot := stack.peek() 490 address := common.BigToAddress(slot) 491 if interpreter.evm.StateDB.Empty(address) { 492 slot.SetUint64(0) 493 } else { 494 slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) 495 } 496 return nil, nil 497 } 498 499 func opGasprice(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 500 stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice)) 501 return nil, nil 502 } 503 504 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 505 num := stack.pop() 506 507 n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257) 508 if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 { 509 stack.push(interpreter.evm.GetHash(num.Uint64()).Big()) 510 } else { 511 stack.push(interpreter.intPool.getZero()) 512 } 513 interpreter.intPool.put(num, n) 514 return nil, nil 515 } 516 517 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 518 stack.push(interpreter.intPool.get().SetBytes(interpreter.evm.Coinbase.Bytes())) 519 return nil, nil 520 } 521 522 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 523 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time))) 524 return nil, nil 525 } 526 527 func opNumber(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 528 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber))) 529 return nil, nil 530 } 531 532 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 533 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty))) 534 return nil, nil 535 } 536 537 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 538 stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit))) 539 return nil, nil 540 } 541 542 func opPop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 543 interpreter.intPool.put(stack.pop()) 544 return nil, nil 545 } 546 547 func opMload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 548 v := stack.peek() 549 offset := v.Int64() 550 v.SetBytes(memory.GetPtr(offset, 32)) 551 return nil, nil 552 } 553 554 func opMstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 555 556 mStart, val := stack.pop(), stack.pop() 557 memory.Set32(mStart.Uint64(), val) 558 559 interpreter.intPool.put(mStart, val) 560 return nil, nil 561 } 562 563 func opMstore8(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 564 off, val := stack.pop().Int64(), stack.pop().Int64() 565 memory.store[off] = byte(val & 0xff) 566 567 return nil, nil 568 } 569 570 func opSload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 571 loc := stack.peek() 572 val := interpreter.evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) 573 loc.SetBytes(val.Bytes()) 574 return nil, nil 575 } 576 577 func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 578 loc := common.BigToHash(stack.pop()) 579 val := stack.pop() 580 interpreter.evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 581 582 interpreter.intPool.put(val) 583 return nil, nil 584 } 585 586 func opJump(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 587 pos := stack.pop() 588 if !contract.validJumpdest(pos) { 589 return nil, ErrInvalidJump 590 } 591 *pc = pos.Uint64() 592 593 interpreter.intPool.put(pos) 594 return nil, nil 595 } 596 597 func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 598 pos, cond := stack.pop(), stack.pop() 599 if cond.Sign() != 0 { 600 if !contract.validJumpdest(pos) { 601 return nil, ErrInvalidJump 602 } 603 *pc = pos.Uint64() 604 } else { 605 *pc++ 606 } 607 608 interpreter.intPool.put(pos, cond) 609 return nil, nil 610 } 611 612 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 613 return nil, nil 614 } 615 616 func opPc(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 617 stack.push(interpreter.intPool.get().SetUint64(*pc)) 618 return nil, nil 619 } 620 621 func opMsize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 622 stack.push(interpreter.intPool.get().SetInt64(int64(memory.Len()))) 623 return nil, nil 624 } 625 626 func opGas(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 627 stack.push(interpreter.intPool.get().SetUint64(contract.Gas)) 628 return nil, nil 629 } 630 631 func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 632 var ( 633 value = stack.pop() 634 offset, size = stack.pop(), stack.pop() 635 input = memory.GetCopy(offset.Int64(), size.Int64()) 636 gas = contract.Gas 637 ) 638 if interpreter.evm.chainRules.IsEIP150 { 639 gas -= gas / 64 640 } 641 642 contract.UseGas(gas) 643 res, addr, returnGas, suberr := interpreter.evm.Create(contract, input, gas, value) 644 645 if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas { 646 stack.push(interpreter.intPool.getZero()) 647 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 648 stack.push(interpreter.intPool.getZero()) 649 } else { 650 stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) 651 } 652 contract.Gas += returnGas 653 interpreter.intPool.put(value, offset, size) 654 655 if suberr == ErrExecutionReverted { 656 return res, nil 657 } 658 return nil, nil 659 } 660 661 func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 662 var ( 663 endowment = stack.pop() 664 offset, size = stack.pop(), stack.pop() 665 salt = stack.pop() 666 input = memory.GetCopy(offset.Int64(), size.Int64()) 667 gas = contract.Gas 668 ) 669 670 gas -= gas / 64 671 contract.UseGas(gas) 672 res, addr, returnGas, suberr := interpreter.evm.Create2(contract, input, gas, endowment, salt) 673 674 if suberr != nil { 675 stack.push(interpreter.intPool.getZero()) 676 } else { 677 stack.push(interpreter.intPool.get().SetBytes(addr.Bytes())) 678 } 679 contract.Gas += returnGas 680 interpreter.intPool.put(endowment, offset, size, salt) 681 682 if suberr == ErrExecutionReverted { 683 return res, nil 684 } 685 return nil, nil 686 } 687 688 func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 689 690 interpreter.intPool.put(stack.pop()) 691 gas := interpreter.evm.callGasTemp 692 693 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 694 toAddr := common.BigToAddress(addr) 695 value = math.U256(value) 696 697 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 698 699 if value.Sign() != 0 { 700 gas += params.CallStipend 701 } 702 ret, returnGas, err := interpreter.evm.Call(contract, toAddr, args, gas, value) 703 if err != nil { 704 stack.push(interpreter.intPool.getZero()) 705 } else { 706 stack.push(interpreter.intPool.get().SetUint64(1)) 707 } 708 if err == nil || err == ErrExecutionReverted { 709 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 710 } 711 contract.Gas += returnGas 712 713 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 714 return ret, nil 715 } 716 717 func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 718 719 interpreter.intPool.put(stack.pop()) 720 gas := interpreter.evm.callGasTemp 721 722 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 723 toAddr := common.BigToAddress(addr) 724 value = math.U256(value) 725 726 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 727 728 if value.Sign() != 0 { 729 gas += params.CallStipend 730 } 731 ret, returnGas, err := interpreter.evm.CallCode(contract, toAddr, args, gas, value) 732 if err != nil { 733 stack.push(interpreter.intPool.getZero()) 734 } else { 735 stack.push(interpreter.intPool.get().SetUint64(1)) 736 } 737 if err == nil || err == ErrExecutionReverted { 738 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 739 } 740 contract.Gas += returnGas 741 742 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 743 return ret, nil 744 } 745 746 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 747 748 interpreter.intPool.put(stack.pop()) 749 gas := interpreter.evm.callGasTemp 750 751 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 752 toAddr := common.BigToAddress(addr) 753 754 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 755 756 ret, returnGas, err := interpreter.evm.DelegateCall(contract, toAddr, args, gas) 757 if err != nil { 758 stack.push(interpreter.intPool.getZero()) 759 } else { 760 stack.push(interpreter.intPool.get().SetUint64(1)) 761 } 762 if err == nil || err == ErrExecutionReverted { 763 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 764 } 765 contract.Gas += returnGas 766 767 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 768 return ret, nil 769 } 770 771 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 772 773 interpreter.intPool.put(stack.pop()) 774 gas := interpreter.evm.callGasTemp 775 776 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 777 toAddr := common.BigToAddress(addr) 778 779 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 780 781 ret, returnGas, err := interpreter.evm.StaticCall(contract, toAddr, args, gas) 782 if err != nil { 783 stack.push(interpreter.intPool.getZero()) 784 } else { 785 stack.push(interpreter.intPool.get().SetUint64(1)) 786 } 787 if err == nil || err == ErrExecutionReverted { 788 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 789 } 790 contract.Gas += returnGas 791 792 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 793 return ret, nil 794 } 795 796 func opReturn(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 797 offset, size := stack.pop(), stack.pop() 798 ret := memory.GetPtr(offset.Int64(), size.Int64()) 799 800 interpreter.intPool.put(offset, size) 801 return ret, nil 802 } 803 804 func opRevert(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 805 offset, size := stack.pop(), stack.pop() 806 ret := memory.GetPtr(offset.Int64(), size.Int64()) 807 808 interpreter.intPool.put(offset, size) 809 return ret, nil 810 } 811 812 func opStop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 813 return nil, nil 814 } 815 816 func opSuicide(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 817 balance := interpreter.evm.StateDB.GetBalance(contract.Address()) 818 interpreter.evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 819 820 interpreter.evm.StateDB.Suicide(contract.Address()) 821 return nil, nil 822 } 823 824 func makeLog(size int) executionFunc { 825 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 826 topics := make([]common.Hash, size) 827 mStart, mSize := stack.pop(), stack.pop() 828 for i := 0; i < size; i++ { 829 topics[i] = common.BigToHash(stack.pop()) 830 } 831 832 d := memory.GetCopy(mStart.Int64(), mSize.Int64()) 833 interpreter.evm.StateDB.AddLog(&types.Log{ 834 Address: contract.Address(), 835 Topics: topics, 836 Data: d, 837 838 BlockNumber: interpreter.evm.BlockNumber.Uint64(), 839 }) 840 841 interpreter.intPool.put(mStart, mSize) 842 return nil, nil 843 } 844 } 845 846 func opPush1(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 847 var ( 848 codeLen = uint64(len(contract.Code)) 849 integer = interpreter.intPool.get() 850 ) 851 *pc += 1 852 if *pc < codeLen { 853 stack.push(integer.SetUint64(uint64(contract.Code[*pc]))) 854 } else { 855 stack.push(integer.SetUint64(0)) 856 } 857 return nil, nil 858 } 859 860 func makePush(size uint64, pushByteSize int) executionFunc { 861 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 862 codeLen := len(contract.Code) 863 864 startMin := codeLen 865 if int(*pc+1) < startMin { 866 startMin = int(*pc + 1) 867 } 868 869 endMin := codeLen 870 if startMin+pushByteSize < endMin { 871 endMin = startMin + pushByteSize 872 } 873 874 integer := interpreter.intPool.get() 875 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 876 877 *pc += size 878 return nil, nil 879 } 880 } 881 882 func makeDup(size int64) executionFunc { 883 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 884 stack.dup(interpreter.intPool, int(size)) 885 return nil, nil 886 } 887 } 888 889 func makeSwap(size int64) executionFunc { 890 891 size++ 892 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 893 stack.swap(int(size)) 894 return nil, nil 895 } 896 }