github.com/pfcoder/quorum@v2.0.3-0.20180501191142-d4a1b0958135+incompatible/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 := getDualState(evm, addr).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(getDualState(evm, addr).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(getDualState(evm, addr).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).Set(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 := getDualState(evm, contract.Address()).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 getDualState(evm, contract.Address()).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 gas := stack.pop().Uint64() 607 // pop gas and value of the stack. 608 addr, value := stack.pop(), stack.pop() 609 value = math.U256(value) 610 // pop input size and offset 611 inOffset, inSize := stack.pop(), stack.pop() 612 // pop return size and offset 613 retOffset, retSize := stack.pop(), stack.pop() 614 615 address := common.BigToAddress(addr) 616 617 // Get the arguments from the memory 618 args := memory.Get(inOffset.Int64(), inSize.Int64()) 619 620 if value.Sign() != 0 { 621 gas += params.CallStipend 622 } 623 ret, returnGas, err := evm.Call(contract, address, args, gas, value) 624 if err != nil { 625 stack.push(new(big.Int)) 626 } else { 627 stack.push(big.NewInt(1)) 628 } 629 if err == nil || err == errExecutionReverted { 630 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 631 } 632 contract.Gas += returnGas 633 634 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 635 return ret, nil 636 } 637 638 func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 639 gas := stack.pop().Uint64() 640 // pop gas and value of the stack. 641 addr, value := stack.pop(), stack.pop() 642 value = math.U256(value) 643 // pop input size and offset 644 inOffset, inSize := stack.pop(), stack.pop() 645 // pop return size and offset 646 retOffset, retSize := stack.pop(), stack.pop() 647 648 address := common.BigToAddress(addr) 649 650 // Get the arguments from the memory 651 args := memory.Get(inOffset.Int64(), inSize.Int64()) 652 653 if value.Sign() != 0 { 654 gas += params.CallStipend 655 } 656 657 ret, returnGas, err := evm.CallCode(contract, address, args, gas, value) 658 if err != nil { 659 stack.push(new(big.Int)) 660 } else { 661 stack.push(big.NewInt(1)) 662 } 663 if err == nil || err == errExecutionReverted { 664 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 665 } 666 contract.Gas += returnGas 667 668 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 669 return ret, nil 670 } 671 672 func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 673 gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 674 675 toAddr := common.BigToAddress(to) 676 args := memory.Get(inOffset.Int64(), inSize.Int64()) 677 678 ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) 679 if err != nil { 680 stack.push(new(big.Int)) 681 } else { 682 stack.push(big.NewInt(1)) 683 } 684 if err == nil || err == errExecutionReverted { 685 memory.Set(outOffset.Uint64(), outSize.Uint64(), ret) 686 } 687 contract.Gas += returnGas 688 689 evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize) 690 return ret, nil 691 } 692 693 func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 694 // pop gas 695 gas := stack.pop().Uint64() 696 // pop address 697 addr := stack.pop() 698 // pop input size and offset 699 inOffset, inSize := stack.pop(), stack.pop() 700 // pop return size and offset 701 retOffset, retSize := stack.pop(), stack.pop() 702 703 address := common.BigToAddress(addr) 704 705 // Get the arguments from the memory 706 args := memory.Get(inOffset.Int64(), inSize.Int64()) 707 708 ret, returnGas, err := evm.StaticCall(contract, address, args, gas) 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, inOffset, inSize, retOffset, retSize) 720 return ret, nil 721 } 722 723 func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 724 offset, size := stack.pop(), stack.pop() 725 ret := memory.GetPtr(offset.Int64(), size.Int64()) 726 727 evm.interpreter.intPool.put(offset, size) 728 return ret, nil 729 } 730 731 func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 732 offset, size := stack.pop(), stack.pop() 733 ret := memory.GetPtr(offset.Int64(), size.Int64()) 734 735 evm.interpreter.intPool.put(offset, size) 736 return ret, nil 737 } 738 739 func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 740 return nil, nil 741 } 742 743 func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 744 db := getDualState(evm, contract.Address()) 745 balance := db.GetBalance(contract.Address()) 746 db.AddBalance(common.BigToAddress(stack.pop()), balance) 747 748 db.Suicide(contract.Address()) 749 return nil, nil 750 } 751 752 // following functions are used by the instruction jump table 753 754 // make log instruction function 755 func makeLog(size int) executionFunc { 756 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 757 topics := make([]common.Hash, size) 758 mStart, mSize := stack.pop(), stack.pop() 759 for i := 0; i < size; i++ { 760 topics[i] = common.BigToHash(stack.pop()) 761 } 762 763 d := memory.Get(mStart.Int64(), mSize.Int64()) 764 evm.StateDB.AddLog(&types.Log{ 765 Address: contract.Address(), 766 Topics: topics, 767 Data: d, 768 // This is a non-consensus field, but assigned here because 769 // core/state doesn't know the current block number. 770 BlockNumber: evm.BlockNumber.Uint64(), 771 }) 772 773 evm.interpreter.intPool.put(mStart, mSize) 774 return nil, nil 775 } 776 } 777 778 // make push instruction function 779 func makePush(size uint64, pushByteSize int) executionFunc { 780 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 781 codeLen := len(contract.Code) 782 783 startMin := codeLen 784 if int(*pc+1) < startMin { 785 startMin = int(*pc + 1) 786 } 787 788 endMin := codeLen 789 if startMin+pushByteSize < endMin { 790 endMin = startMin + pushByteSize 791 } 792 793 integer := evm.interpreter.intPool.get() 794 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 795 796 *pc += size 797 return nil, nil 798 } 799 } 800 801 // make push instruction function 802 func makeDup(size int64) executionFunc { 803 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 804 stack.dup(evm.interpreter.intPool, int(size)) 805 return nil, nil 806 } 807 } 808 809 // make swap instruction function 810 func makeSwap(size int64) executionFunc { 811 // switch n + 1 otherwise n would be swapped with n 812 size += 1 813 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 814 stack.swap(int(size)) 815 return nil, nil 816 } 817 }