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