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