github.com/devfans/go-ethereum@v1.5.10-0.20170326212234-7419d0c38291/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 "fmt" 21 "math/big" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/common/math" 25 "github.com/ethereum/go-ethereum/core/types" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/params" 28 ) 29 30 var bigZero = new(big.Int) 31 32 func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 33 x, y := stack.pop(), stack.pop() 34 stack.push(math.U256(x.Add(x, y))) 35 36 evm.interpreter.intPool.put(y) 37 38 return nil, nil 39 } 40 41 func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 42 x, y := stack.pop(), stack.pop() 43 stack.push(math.U256(x.Sub(x, y))) 44 45 evm.interpreter.intPool.put(y) 46 47 return nil, nil 48 } 49 50 func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 51 x, y := stack.pop(), stack.pop() 52 stack.push(math.U256(x.Mul(x, y))) 53 54 evm.interpreter.intPool.put(y) 55 56 return nil, nil 57 } 58 59 func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 60 x, y := stack.pop(), stack.pop() 61 if y.Sign() != 0 { 62 stack.push(math.U256(x.Div(x, y))) 63 } else { 64 stack.push(new(big.Int)) 65 } 66 67 evm.interpreter.intPool.put(y) 68 69 return nil, nil 70 } 71 72 func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 73 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 74 if y.Sign() == 0 { 75 stack.push(new(big.Int)) 76 return nil, nil 77 } else { 78 n := new(big.Int) 79 if evm.interpreter.intPool.get().Mul(x, y).Sign() < 0 { 80 n.SetInt64(-1) 81 } else { 82 n.SetInt64(1) 83 } 84 85 res := x.Div(x.Abs(x), y.Abs(y)) 86 res.Mul(res, n) 87 88 stack.push(math.U256(res)) 89 } 90 evm.interpreter.intPool.put(y) 91 return nil, nil 92 } 93 94 func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 95 x, y := stack.pop(), stack.pop() 96 if y.Sign() == 0 { 97 stack.push(new(big.Int)) 98 } else { 99 stack.push(math.U256(x.Mod(x, y))) 100 } 101 evm.interpreter.intPool.put(y) 102 return nil, nil 103 } 104 105 func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 106 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 107 108 if y.Sign() == 0 { 109 stack.push(new(big.Int)) 110 } else { 111 n := new(big.Int) 112 if x.Sign() < 0 { 113 n.SetInt64(-1) 114 } else { 115 n.SetInt64(1) 116 } 117 118 res := x.Mod(x.Abs(x), y.Abs(y)) 119 res.Mul(res, n) 120 121 stack.push(math.U256(res)) 122 } 123 evm.interpreter.intPool.put(y) 124 return nil, nil 125 } 126 127 func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 128 base, exponent := stack.pop(), stack.pop() 129 stack.push(math.Exp(base, exponent)) 130 131 evm.interpreter.intPool.put(base, exponent) 132 133 return nil, nil 134 } 135 136 func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 137 back := stack.pop() 138 if back.Cmp(big.NewInt(31)) < 0 { 139 bit := uint(back.Uint64()*8 + 7) 140 num := stack.pop() 141 mask := back.Lsh(common.Big1, bit) 142 mask.Sub(mask, common.Big1) 143 if num.Bit(int(bit)) > 0 { 144 num.Or(num, mask.Not(mask)) 145 } else { 146 num.And(num, mask) 147 } 148 149 stack.push(math.U256(num)) 150 } 151 152 evm.interpreter.intPool.put(back) 153 return nil, nil 154 } 155 156 func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 157 x := stack.pop() 158 stack.push(math.U256(x.Not(x))) 159 return nil, nil 160 } 161 162 func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 163 x, y := stack.pop(), stack.pop() 164 if x.Cmp(y) < 0 { 165 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 166 } else { 167 stack.push(new(big.Int)) 168 } 169 170 evm.interpreter.intPool.put(x, y) 171 return nil, nil 172 } 173 174 func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 175 x, y := stack.pop(), stack.pop() 176 if x.Cmp(y) > 0 { 177 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 178 } else { 179 stack.push(new(big.Int)) 180 } 181 182 evm.interpreter.intPool.put(x, y) 183 return nil, nil 184 } 185 186 func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 187 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 188 if x.Cmp(math.S256(y)) < 0 { 189 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 190 } else { 191 stack.push(new(big.Int)) 192 } 193 194 evm.interpreter.intPool.put(x, y) 195 return nil, nil 196 } 197 198 func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 199 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 200 if x.Cmp(y) > 0 { 201 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 202 } else { 203 stack.push(new(big.Int)) 204 } 205 206 evm.interpreter.intPool.put(x, y) 207 return nil, nil 208 } 209 210 func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 211 x, y := stack.pop(), stack.pop() 212 if x.Cmp(y) == 0 { 213 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 214 } else { 215 stack.push(new(big.Int)) 216 } 217 218 evm.interpreter.intPool.put(x, y) 219 return nil, nil 220 } 221 222 func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 223 x := stack.pop() 224 if x.Sign() > 0 { 225 stack.push(new(big.Int)) 226 } else { 227 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 228 } 229 230 evm.interpreter.intPool.put(x) 231 return nil, nil 232 } 233 234 func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 235 x, y := stack.pop(), stack.pop() 236 stack.push(x.And(x, y)) 237 238 evm.interpreter.intPool.put(y) 239 return nil, nil 240 } 241 func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 242 x, y := stack.pop(), stack.pop() 243 stack.push(x.Or(x, y)) 244 245 evm.interpreter.intPool.put(y) 246 return nil, nil 247 } 248 func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 249 x, y := stack.pop(), stack.pop() 250 stack.push(x.Xor(x, y)) 251 252 evm.interpreter.intPool.put(y) 253 return nil, nil 254 } 255 256 func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 257 th, val := stack.pop(), stack.pop() 258 if th.Cmp(big.NewInt(32)) < 0 { 259 byte := evm.interpreter.intPool.get().SetInt64(int64(math.PaddedBigBytes(val, 32)[th.Int64()])) 260 stack.push(byte) 261 } else { 262 stack.push(new(big.Int)) 263 } 264 265 evm.interpreter.intPool.put(th, val) 266 return nil, nil 267 } 268 func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 269 x, y, z := stack.pop(), stack.pop(), stack.pop() 270 if z.Cmp(bigZero) > 0 { 271 add := x.Add(x, y) 272 add.Mod(add, z) 273 stack.push(math.U256(add)) 274 } else { 275 stack.push(new(big.Int)) 276 } 277 278 evm.interpreter.intPool.put(y, z) 279 return nil, nil 280 } 281 func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 282 x, y, z := stack.pop(), stack.pop(), stack.pop() 283 if z.Cmp(bigZero) > 0 { 284 mul := x.Mul(x, y) 285 mul.Mod(mul, z) 286 stack.push(math.U256(mul)) 287 } else { 288 stack.push(new(big.Int)) 289 } 290 291 evm.interpreter.intPool.put(y, z) 292 return nil, nil 293 } 294 295 func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 296 offset, size := stack.pop(), stack.pop() 297 data := memory.Get(offset.Int64(), size.Int64()) 298 hash := crypto.Keccak256(data) 299 300 if evm.vmConfig.EnablePreimageRecording { 301 evm.StateDB.AddPreimage(common.BytesToHash(hash), data) 302 } 303 304 stack.push(new(big.Int).SetBytes(hash)) 305 306 evm.interpreter.intPool.put(offset, size) 307 return nil, nil 308 } 309 310 func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 311 stack.push(contract.Address().Big()) 312 return nil, nil 313 } 314 315 func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 316 addr := common.BigToAddress(stack.pop()) 317 balance := evm.StateDB.GetBalance(addr) 318 319 stack.push(new(big.Int).Set(balance)) 320 return nil, nil 321 } 322 323 func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 324 stack.push(evm.Origin.Big()) 325 return nil, nil 326 } 327 328 func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 329 stack.push(contract.Caller().Big()) 330 return nil, nil 331 } 332 333 func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 334 stack.push(evm.interpreter.intPool.get().Set(contract.value)) 335 return nil, nil 336 } 337 338 func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 339 stack.push(new(big.Int).SetBytes(getData(contract.Input, stack.pop(), common.Big32))) 340 return nil, nil 341 } 342 343 func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 344 stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) 345 return nil, nil 346 } 347 348 func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 349 var ( 350 mOff = stack.pop() 351 cOff = stack.pop() 352 l = stack.pop() 353 ) 354 memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l)) 355 356 evm.interpreter.intPool.put(mOff, cOff, l) 357 return nil, nil 358 } 359 360 func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 361 a := stack.pop() 362 363 addr := common.BigToAddress(a) 364 a.SetInt64(int64(evm.StateDB.GetCodeSize(addr))) 365 stack.push(a) 366 367 return nil, nil 368 } 369 370 func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 371 l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) 372 stack.push(l) 373 return nil, nil 374 } 375 376 func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 377 var ( 378 mOff = stack.pop() 379 cOff = stack.pop() 380 l = stack.pop() 381 ) 382 codeCopy := getData(contract.Code, cOff, l) 383 384 memory.Set(mOff.Uint64(), l.Uint64(), codeCopy) 385 386 evm.interpreter.intPool.put(mOff, cOff, l) 387 return nil, nil 388 } 389 390 func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 391 var ( 392 addr = common.BigToAddress(stack.pop()) 393 mOff = stack.pop() 394 cOff = stack.pop() 395 l = stack.pop() 396 ) 397 codeCopy := getData(evm.StateDB.GetCode(addr), cOff, l) 398 399 memory.Set(mOff.Uint64(), l.Uint64(), codeCopy) 400 401 evm.interpreter.intPool.put(mOff, cOff, l) 402 403 return nil, nil 404 } 405 406 func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 407 stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice)) 408 return nil, nil 409 } 410 411 func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 412 num := stack.pop() 413 414 n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257) 415 if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 { 416 stack.push(evm.GetHash(num.Uint64()).Big()) 417 } else { 418 stack.push(new(big.Int)) 419 } 420 421 evm.interpreter.intPool.put(num, n) 422 return nil, nil 423 } 424 425 func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 426 stack.push(evm.Coinbase.Big()) 427 return nil, nil 428 } 429 430 func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 431 stack.push(math.U256(new(big.Int).Set(evm.Time))) 432 return nil, nil 433 } 434 435 func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 436 stack.push(math.U256(new(big.Int).Set(evm.BlockNumber))) 437 return nil, nil 438 } 439 440 func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 441 stack.push(math.U256(new(big.Int).Set(evm.Difficulty))) 442 return nil, nil 443 } 444 445 func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 446 stack.push(math.U256(new(big.Int).Set(evm.GasLimit))) 447 return nil, nil 448 } 449 450 func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 451 evm.interpreter.intPool.put(stack.pop()) 452 return nil, nil 453 } 454 455 func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 456 offset := stack.pop() 457 val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32)) 458 stack.push(val) 459 460 evm.interpreter.intPool.put(offset) 461 return nil, nil 462 } 463 464 func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 465 // pop value of the stack 466 mStart, val := stack.pop(), stack.pop() 467 memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32)) 468 469 evm.interpreter.intPool.put(mStart, val) 470 return nil, nil 471 } 472 473 func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 474 off, val := stack.pop().Int64(), stack.pop().Int64() 475 memory.store[off] = byte(val & 0xff) 476 477 return nil, nil 478 } 479 480 func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 481 loc := common.BigToHash(stack.pop()) 482 val := evm.StateDB.GetState(contract.Address(), loc).Big() 483 stack.push(val) 484 return nil, nil 485 } 486 487 func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 488 loc := common.BigToHash(stack.pop()) 489 val := stack.pop() 490 evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 491 492 evm.interpreter.intPool.put(val) 493 return nil, nil 494 } 495 496 func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 497 pos := stack.pop() 498 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 499 nop := contract.GetOp(pos.Uint64()) 500 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 501 } 502 *pc = pos.Uint64() 503 504 evm.interpreter.intPool.put(pos) 505 return nil, nil 506 } 507 func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 508 pos, cond := stack.pop(), stack.pop() 509 if cond.Sign() != 0 { 510 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 511 nop := contract.GetOp(pos.Uint64()) 512 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 513 } 514 *pc = pos.Uint64() 515 } else { 516 *pc++ 517 } 518 519 evm.interpreter.intPool.put(pos, cond) 520 return nil, nil 521 } 522 func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 523 return nil, nil 524 } 525 526 func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 527 stack.push(evm.interpreter.intPool.get().SetUint64(*pc)) 528 return nil, nil 529 } 530 531 func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 532 stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) 533 return nil, nil 534 } 535 536 func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 537 stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas)) 538 return nil, nil 539 } 540 541 func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 542 var ( 543 value = stack.pop() 544 offset, size = stack.pop(), stack.pop() 545 input = memory.Get(offset.Int64(), size.Int64()) 546 gas = contract.Gas 547 ) 548 if evm.ChainConfig().IsEIP150(evm.BlockNumber) { 549 gas -= gas / 64 550 } 551 552 contract.UseGas(gas) 553 _, addr, returnGas, suberr := evm.Create(contract, input, gas, value) 554 // Push item on the stack based on the returned error. If the ruleset is 555 // homestead we must check for CodeStoreOutOfGasError (homestead only 556 // rule) and treat as an error, if the ruleset is frontier we must 557 // ignore this error and pretend the operation was successful. 558 if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas { 559 stack.push(new(big.Int)) 560 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 561 stack.push(new(big.Int)) 562 } else { 563 stack.push(addr.Big()) 564 } 565 contract.Gas += returnGas 566 567 evm.interpreter.intPool.put(value, offset, size) 568 569 return nil, nil 570 } 571 572 func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 573 gas := stack.pop().Uint64() 574 // pop gas and value of the stack. 575 addr, value := stack.pop(), stack.pop() 576 value = math.U256(value) 577 // pop input size and offset 578 inOffset, inSize := stack.pop(), stack.pop() 579 // pop return size and offset 580 retOffset, retSize := stack.pop(), stack.pop() 581 582 address := common.BigToAddress(addr) 583 584 // Get the arguments from the memory 585 args := memory.Get(inOffset.Int64(), inSize.Int64()) 586 587 if value.Sign() != 0 { 588 gas += params.CallStipend 589 } 590 591 ret, returnGas, err := evm.Call(contract, address, args, gas, value) 592 if err != nil { 593 stack.push(new(big.Int)) 594 } else { 595 stack.push(big.NewInt(1)) 596 597 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 598 } 599 contract.Gas += returnGas 600 601 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 602 return nil, nil 603 } 604 605 func opCallCode(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 624 ret, returnGas, err := evm.CallCode(contract, address, args, gas, value) 625 if err != nil { 626 stack.push(new(big.Int)) 627 628 } else { 629 stack.push(big.NewInt(1)) 630 631 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 632 } 633 contract.Gas += returnGas 634 635 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 636 return nil, nil 637 } 638 639 func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 640 // if not homestead return an error. DELEGATECALL is not supported 641 // during pre-homestead. 642 if !evm.ChainConfig().IsHomestead(evm.BlockNumber) { 643 return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL) 644 } 645 646 gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 647 648 toAddr := common.BigToAddress(to) 649 args := memory.Get(inOffset.Int64(), inSize.Int64()) 650 651 ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) 652 if err != nil { 653 stack.push(new(big.Int)) 654 } else { 655 stack.push(big.NewInt(1)) 656 memory.Set(outOffset.Uint64(), outSize.Uint64(), ret) 657 } 658 contract.Gas += returnGas 659 660 evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize) 661 return nil, nil 662 } 663 664 func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 665 offset, size := stack.pop(), stack.pop() 666 ret := memory.GetPtr(offset.Int64(), size.Int64()) 667 668 evm.interpreter.intPool.put(offset, size) 669 return ret, nil 670 } 671 672 func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 673 return nil, nil 674 } 675 676 func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 677 balance := evm.StateDB.GetBalance(contract.Address()) 678 evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 679 680 evm.StateDB.Suicide(contract.Address()) 681 682 return nil, nil 683 } 684 685 // following functions are used by the instruction jump table 686 687 // make log instruction function 688 func makeLog(size int) executionFunc { 689 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 690 topics := make([]common.Hash, size) 691 mStart, mSize := stack.pop(), stack.pop() 692 for i := 0; i < size; i++ { 693 topics[i] = common.BigToHash(stack.pop()) 694 } 695 696 d := memory.Get(mStart.Int64(), mSize.Int64()) 697 evm.StateDB.AddLog(&types.Log{ 698 Address: contract.Address(), 699 Topics: topics, 700 Data: d, 701 // This is a non-consensus field, but assigned here because 702 // core/state doesn't know the current block number. 703 BlockNumber: evm.BlockNumber.Uint64(), 704 }) 705 706 evm.interpreter.intPool.put(mStart, mSize) 707 return nil, nil 708 } 709 } 710 711 // make push instruction function 712 func makePush(size uint64, bsize *big.Int) executionFunc { 713 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 714 byts := getData(contract.Code, evm.interpreter.intPool.get().SetUint64(*pc+1), bsize) 715 stack.push(new(big.Int).SetBytes(byts)) 716 *pc += size 717 return nil, nil 718 } 719 } 720 721 // make push instruction function 722 func makeDup(size int64) executionFunc { 723 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 724 stack.dup(int(size)) 725 return nil, nil 726 } 727 } 728 729 // make swap instruction function 730 func makeSwap(size int64) executionFunc { 731 // switch n + 1 otherwise n would be swapped with n 732 size += 1 733 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 734 stack.swap(int(size)) 735 return nil, nil 736 } 737 }