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