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