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