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