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