github.com/needkane/go-ethereum@v1.7.4-0.20180131070256-c212876ea2b7/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 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 func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 306 offset, size := stack.pop(), stack.pop() 307 data := memory.Get(offset.Int64(), size.Int64()) 308 hash := crypto.Keccak256(data) 309 310 if evm.vmConfig.EnablePreimageRecording { 311 evm.StateDB.AddPreimage(common.BytesToHash(hash), data) 312 } 313 314 stack.push(new(big.Int).SetBytes(hash)) 315 316 evm.interpreter.intPool.put(offset, size) 317 return nil, nil 318 } 319 320 func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 321 stack.push(contract.Address().Big()) 322 return nil, nil 323 } 324 325 func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 326 addr := common.BigToAddress(stack.pop()) 327 balance := evm.StateDB.GetBalance(addr) 328 329 stack.push(new(big.Int).Set(balance)) 330 return nil, nil 331 } 332 333 func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 334 stack.push(evm.Origin.Big()) 335 return nil, nil 336 } 337 338 func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 339 stack.push(contract.Caller().Big()) 340 return nil, nil 341 } 342 343 func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 344 stack.push(evm.interpreter.intPool.get().Set(contract.value)) 345 return nil, nil 346 } 347 348 func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 349 stack.push(new(big.Int).SetBytes(getDataBig(contract.Input, stack.pop(), big32))) 350 return nil, nil 351 } 352 353 func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 354 stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) 355 return nil, nil 356 } 357 358 func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 359 var ( 360 memOffset = stack.pop() 361 dataOffset = stack.pop() 362 length = stack.pop() 363 ) 364 memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) 365 366 evm.interpreter.intPool.put(memOffset, dataOffset, length) 367 return nil, nil 368 } 369 370 func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 371 stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) 372 return nil, nil 373 } 374 375 func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 376 var ( 377 memOffset = stack.pop() 378 dataOffset = stack.pop() 379 length = stack.pop() 380 ) 381 defer evm.interpreter.intPool.put(memOffset, dataOffset, length) 382 383 end := new(big.Int).Add(dataOffset, length) 384 if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() { 385 return nil, errReturnDataOutOfBounds 386 } 387 memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) 388 389 return nil, nil 390 } 391 392 func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 393 a := stack.pop() 394 395 addr := common.BigToAddress(a) 396 a.SetInt64(int64(evm.StateDB.GetCodeSize(addr))) 397 stack.push(a) 398 399 return nil, nil 400 } 401 402 func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 403 l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) 404 stack.push(l) 405 return nil, nil 406 } 407 408 func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 409 var ( 410 memOffset = stack.pop() 411 codeOffset = stack.pop() 412 length = stack.pop() 413 ) 414 codeCopy := getDataBig(contract.Code, codeOffset, length) 415 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 416 417 evm.interpreter.intPool.put(memOffset, codeOffset, length) 418 return nil, nil 419 } 420 421 func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 422 var ( 423 addr = common.BigToAddress(stack.pop()) 424 memOffset = stack.pop() 425 codeOffset = stack.pop() 426 length = stack.pop() 427 ) 428 codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length) 429 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 430 431 evm.interpreter.intPool.put(memOffset, codeOffset, length) 432 return nil, nil 433 } 434 435 func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 436 stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice)) 437 return nil, nil 438 } 439 440 func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 441 num := stack.pop() 442 443 n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257) 444 if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 { 445 stack.push(evm.GetHash(num.Uint64()).Big()) 446 } else { 447 stack.push(new(big.Int)) 448 } 449 450 evm.interpreter.intPool.put(num, n) 451 return nil, nil 452 } 453 454 func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 455 stack.push(evm.Coinbase.Big()) 456 return nil, nil 457 } 458 459 func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 460 stack.push(math.U256(new(big.Int).Set(evm.Time))) 461 return nil, nil 462 } 463 464 func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 465 stack.push(math.U256(new(big.Int).Set(evm.BlockNumber))) 466 return nil, nil 467 } 468 469 func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 470 stack.push(math.U256(new(big.Int).Set(evm.Difficulty))) 471 return nil, nil 472 } 473 474 func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 475 stack.push(math.U256(new(big.Int).SetUint64(evm.GasLimit))) 476 return nil, nil 477 } 478 479 func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 480 evm.interpreter.intPool.put(stack.pop()) 481 return nil, nil 482 } 483 484 func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 485 offset := stack.pop() 486 val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32)) 487 stack.push(val) 488 489 evm.interpreter.intPool.put(offset) 490 return nil, nil 491 } 492 493 func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 494 // pop value of the stack 495 mStart, val := stack.pop(), stack.pop() 496 memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32)) 497 498 evm.interpreter.intPool.put(mStart, val) 499 return nil, nil 500 } 501 502 func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 503 off, val := stack.pop().Int64(), stack.pop().Int64() 504 memory.store[off] = byte(val & 0xff) 505 506 return nil, nil 507 } 508 509 func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 510 loc := common.BigToHash(stack.pop()) 511 val := evm.StateDB.GetState(contract.Address(), loc).Big() 512 stack.push(val) 513 return nil, nil 514 } 515 516 func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 517 loc := common.BigToHash(stack.pop()) 518 val := stack.pop() 519 evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 520 521 evm.interpreter.intPool.put(val) 522 return nil, nil 523 } 524 525 func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 526 pos := stack.pop() 527 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 528 nop := contract.GetOp(pos.Uint64()) 529 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 530 } 531 *pc = pos.Uint64() 532 533 evm.interpreter.intPool.put(pos) 534 return nil, nil 535 } 536 537 func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 538 pos, cond := stack.pop(), stack.pop() 539 if cond.Sign() != 0 { 540 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 541 nop := contract.GetOp(pos.Uint64()) 542 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 543 } 544 *pc = pos.Uint64() 545 } else { 546 *pc++ 547 } 548 549 evm.interpreter.intPool.put(pos, cond) 550 return nil, nil 551 } 552 553 func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 554 return nil, nil 555 } 556 557 func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 558 stack.push(evm.interpreter.intPool.get().SetUint64(*pc)) 559 return nil, nil 560 } 561 562 func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 563 stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) 564 return nil, nil 565 } 566 567 func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 568 stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas)) 569 return nil, nil 570 } 571 572 func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 573 var ( 574 value = stack.pop() 575 offset, size = stack.pop(), stack.pop() 576 input = memory.Get(offset.Int64(), size.Int64()) 577 gas = contract.Gas 578 ) 579 if evm.ChainConfig().IsEIP150(evm.BlockNumber) { 580 gas -= gas / 64 581 } 582 583 contract.UseGas(gas) 584 res, addr, returnGas, suberr := evm.Create(contract, input, gas, value) 585 // Push item on the stack based on the returned error. If the ruleset is 586 // homestead we must check for CodeStoreOutOfGasError (homestead only 587 // rule) and treat as an error, if the ruleset is frontier we must 588 // ignore this error and pretend the operation was successful. 589 if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas { 590 stack.push(new(big.Int)) 591 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 592 stack.push(new(big.Int)) 593 } else { 594 stack.push(addr.Big()) 595 } 596 contract.Gas += returnGas 597 evm.interpreter.intPool.put(value, offset, size) 598 599 if suberr == errExecutionReverted { 600 return res, nil 601 } 602 return nil, nil 603 } 604 605 func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 606 // Pop gas. The actual gas in in evm.callGasTemp. 607 evm.interpreter.intPool.put(stack.pop()) 608 gas := evm.callGasTemp 609 // Pop other call parameters. 610 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 611 toAddr := common.BigToAddress(addr) 612 value = math.U256(value) 613 // Get the arguments from the memory. 614 args := memory.Get(inOffset.Int64(), inSize.Int64()) 615 616 if value.Sign() != 0 { 617 gas += params.CallStipend 618 } 619 ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value) 620 if err != nil { 621 stack.push(new(big.Int)) 622 } else { 623 stack.push(big.NewInt(1)) 624 } 625 if err == nil || err == errExecutionReverted { 626 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 627 } 628 contract.Gas += returnGas 629 630 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 631 return ret, nil 632 } 633 634 func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 635 // Pop gas. The actual gas is in evm.callGasTemp. 636 evm.interpreter.intPool.put(stack.pop()) 637 gas := evm.callGasTemp 638 // Pop other call parameters. 639 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 640 toAddr := common.BigToAddress(addr) 641 value = math.U256(value) 642 // Get arguments from the memory. 643 args := memory.Get(inOffset.Int64(), inSize.Int64()) 644 645 if value.Sign() != 0 { 646 gas += params.CallStipend 647 } 648 ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value) 649 if err != nil { 650 stack.push(new(big.Int)) 651 } else { 652 stack.push(big.NewInt(1)) 653 } 654 if err == nil || err == errExecutionReverted { 655 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 656 } 657 contract.Gas += returnGas 658 659 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 660 return ret, nil 661 } 662 663 func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 664 // Pop gas. The actual gas is in evm.callGasTemp. 665 evm.interpreter.intPool.put(stack.pop()) 666 gas := evm.callGasTemp 667 // Pop other call parameters. 668 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 669 toAddr := common.BigToAddress(addr) 670 // Get arguments from the memory. 671 args := memory.Get(inOffset.Int64(), inSize.Int64()) 672 673 ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) 674 if err != nil { 675 stack.push(new(big.Int)) 676 } else { 677 stack.push(big.NewInt(1)) 678 } 679 if err == nil || err == errExecutionReverted { 680 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 681 } 682 contract.Gas += returnGas 683 684 evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 685 return ret, nil 686 } 687 688 func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 689 // Pop gas. The actual gas is in evm.callGasTemp. 690 evm.interpreter.intPool.put(stack.pop()) 691 gas := evm.callGasTemp 692 // Pop other call parameters. 693 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 694 toAddr := common.BigToAddress(addr) 695 // Get arguments from the memory. 696 args := memory.Get(inOffset.Int64(), inSize.Int64()) 697 698 ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas) 699 if err != nil { 700 stack.push(new(big.Int)) 701 } else { 702 stack.push(big.NewInt(1)) 703 } 704 if err == nil || err == errExecutionReverted { 705 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 706 } 707 contract.Gas += returnGas 708 709 evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 710 return ret, nil 711 } 712 713 func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 714 offset, size := stack.pop(), stack.pop() 715 ret := memory.GetPtr(offset.Int64(), size.Int64()) 716 717 evm.interpreter.intPool.put(offset, size) 718 return ret, nil 719 } 720 721 func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 722 offset, size := stack.pop(), stack.pop() 723 ret := memory.GetPtr(offset.Int64(), size.Int64()) 724 725 evm.interpreter.intPool.put(offset, size) 726 return ret, nil 727 } 728 729 func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 730 return nil, nil 731 } 732 733 func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 734 balance := evm.StateDB.GetBalance(contract.Address()) 735 evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 736 737 evm.StateDB.Suicide(contract.Address()) 738 return nil, nil 739 } 740 741 // following functions are used by the instruction jump table 742 743 // make log instruction function 744 func makeLog(size int) executionFunc { 745 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 746 topics := make([]common.Hash, size) 747 mStart, mSize := stack.pop(), stack.pop() 748 for i := 0; i < size; i++ { 749 topics[i] = common.BigToHash(stack.pop()) 750 } 751 752 d := memory.Get(mStart.Int64(), mSize.Int64()) 753 evm.StateDB.AddLog(&types.Log{ 754 Address: contract.Address(), 755 Topics: topics, 756 Data: d, 757 // This is a non-consensus field, but assigned here because 758 // core/state doesn't know the current block number. 759 BlockNumber: evm.BlockNumber.Uint64(), 760 }) 761 762 evm.interpreter.intPool.put(mStart, mSize) 763 return nil, nil 764 } 765 } 766 767 // make push instruction function 768 func makePush(size uint64, pushByteSize int) executionFunc { 769 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 770 codeLen := len(contract.Code) 771 772 startMin := codeLen 773 if int(*pc+1) < startMin { 774 startMin = int(*pc + 1) 775 } 776 777 endMin := codeLen 778 if startMin+pushByteSize < endMin { 779 endMin = startMin + pushByteSize 780 } 781 782 integer := evm.interpreter.intPool.get() 783 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 784 785 *pc += size 786 return nil, nil 787 } 788 } 789 790 // make push instruction function 791 func makeDup(size int64) executionFunc { 792 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 793 stack.dup(evm.interpreter.intPool, int(size)) 794 return nil, nil 795 } 796 } 797 798 // make swap instruction function 799 func makeSwap(size int64) executionFunc { 800 // switch n + 1 otherwise n would be swapped with n 801 size += 1 802 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 803 stack.swap(int(size)) 804 return nil, nil 805 } 806 }