github.com/karalabe/go-ethereum@v0.8.5/vm/vm.go (about) 1 package vm 2 3 import ( 4 "fmt" 5 "math/big" 6 7 "github.com/ethereum/go-ethereum/crypto" 8 "github.com/ethereum/go-ethereum/ethutil" 9 "github.com/ethereum/go-ethereum/state" 10 ) 11 12 type Vm struct { 13 env Environment 14 15 logTy byte 16 logStr string 17 18 err error 19 20 Dbg Debugger 21 22 BreakPoints []int64 23 Stepping bool 24 Fn string 25 26 Recoverable bool 27 } 28 29 func New(env Environment) *Vm { 30 lt := LogTyPretty 31 if ethutil.Config.Diff { 32 lt = LogTyDiff 33 } 34 35 return &Vm{env: env, logTy: lt, Recoverable: true} 36 } 37 38 func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { 39 self.env.SetDepth(self.env.Depth() + 1) 40 41 context := NewContext(caller, me, code, gas, price) 42 43 vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData) 44 45 if self.Recoverable { 46 // Recover from any require exception 47 defer func() { 48 if r := recover(); r != nil { 49 self.Printf(" %v", r).Endl() 50 51 context.UseGas(context.Gas) 52 53 ret = context.Return(nil) 54 55 err = fmt.Errorf("%v", r) 56 57 } 58 }() 59 } 60 61 if p := Precompiled[string(me.Address())]; p != nil { 62 return self.RunPrecompiled(p, callData, context) 63 } 64 65 var ( 66 op OpCode 67 68 destinations = analyseJumpDests(context.Code) 69 mem = NewMemory() 70 stack = NewStack() 71 pc uint64 = 0 72 step = 0 73 prevStep = 0 74 statedb = self.env.State() 75 76 jump = func(from uint64, to *big.Int) { 77 p := to.Uint64() 78 79 nop := context.GetOp(p) 80 if !destinations.Has(p) { 81 panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) 82 } 83 84 self.Printf(" ~> %v", to) 85 pc = to.Uint64() 86 87 self.Endl() 88 } 89 ) 90 91 // Don't bother with the execution if there's no code. 92 if len(code) == 0 { 93 return context.Return(nil), nil 94 } 95 96 for { 97 prevStep = step 98 // The base for all big integer arithmetic 99 base := new(big.Int) 100 101 step++ 102 // Get the memory location of pc 103 op = context.GetOp(pc) 104 105 self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len()) 106 if self.Dbg != nil { 107 //self.Dbg.Step(self, op, mem, stack, context) 108 } 109 110 newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack) 111 112 self.Printf("(g) %-3v (%v)", gas, context.Gas) 113 114 if !context.UseGas(gas) { 115 self.Endl() 116 117 tmp := new(big.Int).Set(context.Gas) 118 119 context.UseGas(context.Gas) 120 121 return context.Return(nil), OOG(gas, tmp) 122 } 123 124 mem.Resize(newMemSize.Uint64()) 125 126 switch op { 127 // 0x20 range 128 case ADD: 129 x, y := stack.Popn() 130 self.Printf(" %v + %v", y, x) 131 132 base.Add(y, x) 133 134 U256(base) 135 136 self.Printf(" = %v", base) 137 // Pop result back on the stack 138 stack.Push(base) 139 case SUB: 140 x, y := stack.Popn() 141 self.Printf(" %v - %v", y, x) 142 143 base.Sub(y, x) 144 145 U256(base) 146 147 self.Printf(" = %v", base) 148 // Pop result back on the stack 149 stack.Push(base) 150 case MUL: 151 x, y := stack.Popn() 152 self.Printf(" %v * %v", y, x) 153 154 base.Mul(y, x) 155 156 U256(base) 157 158 self.Printf(" = %v", base) 159 // Pop result back on the stack 160 stack.Push(base) 161 case DIV: 162 x, y := stack.Pop(), stack.Pop() 163 self.Printf(" %v / %v", x, y) 164 165 if y.Cmp(ethutil.Big0) != 0 { 166 base.Div(x, y) 167 } 168 169 U256(base) 170 171 self.Printf(" = %v", base) 172 // Pop result back on the stack 173 stack.Push(base) 174 case SDIV: 175 x, y := S256(stack.Pop()), S256(stack.Pop()) 176 177 self.Printf(" %v / %v", x, y) 178 179 if y.Cmp(ethutil.Big0) == 0 { 180 base.Set(ethutil.Big0) 181 } else { 182 n := new(big.Int) 183 if new(big.Int).Mul(x, y).Cmp(ethutil.Big0) < 0 { 184 n.SetInt64(-1) 185 } else { 186 n.SetInt64(1) 187 } 188 189 base.Div(x.Abs(x), y.Abs(y)).Mul(base, n) 190 191 U256(base) 192 } 193 194 self.Printf(" = %v", base) 195 stack.Push(base) 196 case MOD: 197 x, y := stack.Pop(), stack.Pop() 198 199 self.Printf(" %v %% %v", x, y) 200 201 if y.Cmp(ethutil.Big0) == 0 { 202 base.Set(ethutil.Big0) 203 } else { 204 base.Mod(x, y) 205 } 206 207 U256(base) 208 209 self.Printf(" = %v", base) 210 stack.Push(base) 211 case SMOD: 212 x, y := S256(stack.Pop()), S256(stack.Pop()) 213 214 self.Printf(" %v %% %v", x, y) 215 216 if y.Cmp(ethutil.Big0) == 0 { 217 base.Set(ethutil.Big0) 218 } else { 219 n := new(big.Int) 220 if x.Cmp(ethutil.Big0) < 0 { 221 n.SetInt64(-1) 222 } else { 223 n.SetInt64(1) 224 } 225 226 base.Mod(x.Abs(x), y.Abs(y)).Mul(base, n) 227 228 U256(base) 229 } 230 231 self.Printf(" = %v", base) 232 stack.Push(base) 233 234 case EXP: 235 x, y := stack.Popn() 236 237 self.Printf(" %v ** %v", y, x) 238 239 base.Exp(y, x, Pow256) 240 241 U256(base) 242 243 self.Printf(" = %v", base) 244 245 stack.Push(base) 246 case SIGNEXTEND: 247 back := stack.Pop().Uint64() 248 if back < 31 { 249 bit := uint(back*8 + 7) 250 num := stack.Pop() 251 mask := new(big.Int).Lsh(ethutil.Big1, bit) 252 mask.Sub(mask, ethutil.Big1) 253 if ethutil.BitTest(num, int(bit)) { 254 num.Or(num, mask.Not(mask)) 255 } else { 256 num.And(num, mask) 257 } 258 259 num = U256(num) 260 261 self.Printf(" = %v", num) 262 263 stack.Push(num) 264 } 265 case NOT: 266 base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1) 267 268 // Not needed 269 base = U256(base) 270 271 stack.Push(base) 272 case LT: 273 x, y := stack.Popn() 274 self.Printf(" %v < %v", y, x) 275 // x < y 276 if y.Cmp(x) < 0 { 277 stack.Push(ethutil.BigTrue) 278 } else { 279 stack.Push(ethutil.BigFalse) 280 } 281 case GT: 282 x, y := stack.Popn() 283 self.Printf(" %v > %v", y, x) 284 285 // x > y 286 if y.Cmp(x) > 0 { 287 stack.Push(ethutil.BigTrue) 288 } else { 289 stack.Push(ethutil.BigFalse) 290 } 291 292 case SLT: 293 y, x := S256(stack.Pop()), S256(stack.Pop()) 294 self.Printf(" %v < %v", y, x) 295 // x < y 296 if y.Cmp(S256(x)) < 0 { 297 stack.Push(ethutil.BigTrue) 298 } else { 299 stack.Push(ethutil.BigFalse) 300 } 301 case SGT: 302 y, x := S256(stack.Pop()), S256(stack.Pop()) 303 self.Printf(" %v > %v", y, x) 304 305 // x > y 306 if y.Cmp(x) > 0 { 307 stack.Push(ethutil.BigTrue) 308 } else { 309 stack.Push(ethutil.BigFalse) 310 } 311 312 case EQ: 313 x, y := stack.Popn() 314 self.Printf(" %v == %v", y, x) 315 316 // x == y 317 if x.Cmp(y) == 0 { 318 stack.Push(ethutil.BigTrue) 319 } else { 320 stack.Push(ethutil.BigFalse) 321 } 322 case ISZERO: 323 x := stack.Pop() 324 if x.Cmp(ethutil.BigFalse) > 0 { 325 stack.Push(ethutil.BigFalse) 326 } else { 327 stack.Push(ethutil.BigTrue) 328 } 329 330 // 0x10 range 331 case AND: 332 x, y := stack.Popn() 333 self.Printf(" %v & %v", y, x) 334 335 stack.Push(base.And(y, x)) 336 case OR: 337 x, y := stack.Popn() 338 self.Printf(" %v | %v", y, x) 339 340 stack.Push(base.Or(y, x)) 341 case XOR: 342 x, y := stack.Popn() 343 self.Printf(" %v ^ %v", y, x) 344 345 stack.Push(base.Xor(y, x)) 346 case BYTE: 347 val, th := stack.Popn() 348 349 if th.Cmp(big.NewInt(32)) < 0 { 350 byt := big.NewInt(int64(ethutil.LeftPadBytes(val.Bytes(), 32)[th.Int64()])) 351 352 base.Set(byt) 353 } else { 354 base.Set(ethutil.BigFalse) 355 } 356 357 self.Printf(" => 0x%x", base.Bytes()) 358 359 stack.Push(base) 360 case ADDMOD: 361 362 x := stack.Pop() 363 y := stack.Pop() 364 z := stack.Pop() 365 366 add := new(big.Int).Add(x, y) 367 if len(z.Bytes()) > 0 { // NOT 0x0 368 base.Mod(add, z) 369 370 U256(base) 371 } 372 373 self.Printf(" %v + %v %% %v = %v", x, y, z, base) 374 375 stack.Push(base) 376 case MULMOD: 377 378 x := stack.Pop() 379 y := stack.Pop() 380 z := stack.Pop() 381 382 mul := new(big.Int).Mul(x, y) 383 if len(z.Bytes()) > 0 { // NOT 0x0 384 base.Mod(mul, z) 385 386 U256(base) 387 } 388 389 self.Printf(" %v + %v %% %v = %v", x, y, z, base) 390 391 stack.Push(base) 392 393 // 0x20 range 394 case SHA3: 395 size, offset := stack.Popn() 396 data := crypto.Sha3(mem.Get(offset.Int64(), size.Int64())) 397 398 stack.Push(ethutil.BigD(data)) 399 400 self.Printf(" => %x", data) 401 // 0x30 range 402 case ADDRESS: 403 stack.Push(ethutil.BigD(context.Address())) 404 405 self.Printf(" => %x", context.Address()) 406 case BALANCE: 407 408 addr := stack.Pop().Bytes() 409 balance := statedb.GetBalance(addr) 410 411 stack.Push(balance) 412 413 self.Printf(" => %v (%x)", balance, addr) 414 case ORIGIN: 415 origin := self.env.Origin() 416 417 stack.Push(ethutil.BigD(origin)) 418 419 self.Printf(" => %x", origin) 420 case CALLER: 421 caller := context.caller.Address() 422 stack.Push(ethutil.BigD(caller)) 423 424 self.Printf(" => %x", caller) 425 case CALLVALUE: 426 stack.Push(value) 427 428 self.Printf(" => %v", value) 429 case CALLDATALOAD: 430 var ( 431 offset = stack.Pop() 432 data = make([]byte, 32) 433 lenData = big.NewInt(int64(len(callData))) 434 ) 435 436 if lenData.Cmp(offset) >= 0 { 437 length := new(big.Int).Add(offset, ethutil.Big32) 438 length = ethutil.BigMin(length, lenData) 439 440 copy(data, callData[offset.Int64():length.Int64()]) 441 } 442 443 self.Printf(" => 0x%x", data) 444 445 stack.Push(ethutil.BigD(data)) 446 case CALLDATASIZE: 447 l := int64(len(callData)) 448 stack.Push(big.NewInt(l)) 449 450 self.Printf(" => %d", l) 451 case CALLDATACOPY: 452 var ( 453 size = uint64(len(callData)) 454 mOff = stack.Pop().Uint64() 455 cOff = stack.Pop().Uint64() 456 l = stack.Pop().Uint64() 457 ) 458 459 if cOff > size { 460 cOff = 0 461 l = 0 462 } else if cOff+l > size { 463 l = 0 464 } 465 466 code := callData[cOff : cOff+l] 467 468 mem.Set(mOff, l, code) 469 470 self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, callData[cOff:cOff+l]) 471 case CODESIZE, EXTCODESIZE: 472 var code []byte 473 if op == EXTCODESIZE { 474 addr := stack.Pop().Bytes() 475 476 code = statedb.GetCode(addr) 477 } else { 478 code = context.Code 479 } 480 481 l := big.NewInt(int64(len(code))) 482 stack.Push(l) 483 484 self.Printf(" => %d", l) 485 case CODECOPY, EXTCODECOPY: 486 var code []byte 487 if op == EXTCODECOPY { 488 code = statedb.GetCode(stack.Pop().Bytes()) 489 } else { 490 code = context.Code 491 } 492 context := NewContext(nil, nil, code, ethutil.Big0, ethutil.Big0) 493 var ( 494 mOff = stack.Pop().Uint64() 495 cOff = stack.Pop().Uint64() 496 l = stack.Pop().Uint64() 497 ) 498 codeCopy := context.GetCode(cOff, l) 499 500 mem.Set(mOff, l, codeCopy) 501 502 self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy) 503 case GASPRICE: 504 stack.Push(context.Price) 505 506 self.Printf(" => %x", context.Price) 507 508 // 0x40 range 509 case BLOCKHASH: 510 num := stack.Pop() 511 512 n := new(big.Int).Sub(self.env.BlockNumber(), ethutil.Big257) 513 if num.Cmp(n) > 0 && num.Cmp(self.env.BlockNumber()) < 0 { 514 stack.Push(ethutil.BigD(self.env.GetHash(num.Uint64()))) 515 } else { 516 stack.Push(ethutil.Big0) 517 } 518 519 self.Printf(" => 0x%x", stack.Peek().Bytes()) 520 case COINBASE: 521 coinbase := self.env.Coinbase() 522 523 stack.Push(ethutil.BigD(coinbase)) 524 525 self.Printf(" => 0x%x", coinbase) 526 case TIMESTAMP: 527 time := self.env.Time() 528 529 stack.Push(big.NewInt(time)) 530 531 self.Printf(" => 0x%x", time) 532 case NUMBER: 533 number := self.env.BlockNumber() 534 535 stack.Push(U256(number)) 536 537 self.Printf(" => 0x%x", number.Bytes()) 538 case DIFFICULTY: 539 difficulty := self.env.Difficulty() 540 541 stack.Push(difficulty) 542 543 self.Printf(" => 0x%x", difficulty.Bytes()) 544 case GASLIMIT: 545 self.Printf(" => %v", self.env.GasLimit()) 546 547 stack.Push(self.env.GasLimit()) 548 549 // 0x50 range 550 case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: 551 a := uint64(op - PUSH1 + 1) 552 byts := context.GetRangeValue(pc+1, a) 553 // Push value to stack 554 stack.Push(ethutil.BigD(byts)) 555 pc += a 556 557 step += int(op) - int(PUSH1) + 1 558 559 self.Printf(" => 0x%x", byts) 560 case POP: 561 stack.Pop() 562 case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 563 n := int(op - DUP1 + 1) 564 stack.Dupn(n) 565 566 self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes()) 567 case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: 568 n := int(op - SWAP1 + 2) 569 x, y := stack.Swapn(n) 570 571 self.Printf(" => [%d] %x [0] %x", n, x.Bytes(), y.Bytes()) 572 case LOG0, LOG1, LOG2, LOG3, LOG4: 573 n := int(op - LOG0) 574 topics := make([][]byte, n) 575 mSize, mStart := stack.Popn() 576 for i := 0; i < n; i++ { 577 topics[i] = ethutil.LeftPadBytes(stack.Pop().Bytes(), 32) 578 } 579 580 data := mem.Get(mStart.Int64(), mSize.Int64()) 581 log := &Log{context.Address(), topics, data, self.env.BlockNumber().Uint64()} 582 self.env.AddLog(log) 583 584 self.Printf(" => %v", log) 585 case MLOAD: 586 offset := stack.Pop() 587 val := ethutil.BigD(mem.Get(offset.Int64(), 32)) 588 stack.Push(val) 589 590 self.Printf(" => 0x%x", val.Bytes()) 591 case MSTORE: // Store the value at stack top-1 in to memory at location stack top 592 // Pop value of the stack 593 val, mStart := stack.Popn() 594 mem.Set(mStart.Uint64(), 32, ethutil.BigToBytes(val, 256)) 595 596 self.Printf(" => 0x%x", val) 597 case MSTORE8: 598 off := stack.Pop() 599 val := stack.Pop() 600 601 mem.store[off.Int64()] = byte(val.Int64() & 0xff) 602 603 self.Printf(" => [%v] 0x%x", off, val) 604 case SLOAD: 605 loc := stack.Pop() 606 val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes())) 607 stack.Push(val) 608 609 self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) 610 case SSTORE: 611 val, loc := stack.Popn() 612 statedb.SetState(context.Address(), loc.Bytes(), val) 613 614 self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) 615 case JUMP: 616 jump(pc, stack.Pop()) 617 618 continue 619 case JUMPI: 620 cond, pos := stack.Popn() 621 622 if cond.Cmp(ethutil.BigTrue) >= 0 { 623 jump(pc, pos) 624 625 continue 626 } 627 628 self.Printf(" ~> false") 629 630 case JUMPDEST: 631 case PC: 632 stack.Push(big.NewInt(int64(pc))) 633 case MSIZE: 634 stack.Push(big.NewInt(int64(mem.Len()))) 635 case GAS: 636 stack.Push(context.Gas) 637 638 self.Printf(" => %x", context.Gas) 639 // 0x60 range 640 case CREATE: 641 642 var ( 643 value = stack.Pop() 644 size, offset = stack.Popn() 645 input = mem.Get(offset.Int64(), size.Int64()) 646 gas = new(big.Int).Set(context.Gas) 647 addr []byte 648 ) 649 self.Endl() 650 651 context.UseGas(context.Gas) 652 ret, suberr, ref := self.env.Create(context, nil, input, gas, price, value) 653 if suberr != nil { 654 stack.Push(ethutil.BigFalse) 655 656 self.Printf(" (*) 0x0 %v", suberr) 657 } else { 658 659 // gas < len(ret) * CreateDataGas == NO_CODE 660 dataGas := big.NewInt(int64(len(ret))) 661 dataGas.Mul(dataGas, GasCreateByte) 662 if context.UseGas(dataGas) { 663 ref.SetCode(ret) 664 } 665 addr = ref.Address() 666 667 stack.Push(ethutil.BigD(addr)) 668 669 } 670 671 // Debug hook 672 if self.Dbg != nil { 673 self.Dbg.SetCode(context.Code) 674 } 675 case CALL, CALLCODE: 676 gas := stack.Pop() 677 // Pop gas and value of the stack. 678 value, addr := stack.Popn() 679 value = U256(value) 680 // Pop input size and offset 681 inSize, inOffset := stack.Popn() 682 // Pop return size and offset 683 retSize, retOffset := stack.Popn() 684 685 address := ethutil.Address(addr.Bytes()) 686 self.Printf(" => %x", address).Endl() 687 688 // Get the arguments from the memory 689 args := mem.Get(inOffset.Int64(), inSize.Int64()) 690 691 var ( 692 ret []byte 693 err error 694 ) 695 if op == CALLCODE { 696 ret, err = self.env.CallCode(context, address, args, gas, price, value) 697 } else { 698 ret, err = self.env.Call(context, address, args, gas, price, value) 699 } 700 701 if err != nil { 702 stack.Push(ethutil.BigFalse) 703 704 vmlogger.Debugln(err) 705 } else { 706 stack.Push(ethutil.BigTrue) 707 708 mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) 709 } 710 self.Printf("resume %x (%v)", context.Address(), context.Gas) 711 712 // Debug hook 713 if self.Dbg != nil { 714 self.Dbg.SetCode(context.Code) 715 } 716 717 case RETURN: 718 size, offset := stack.Popn() 719 ret := mem.Get(offset.Int64(), size.Int64()) 720 721 self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl() 722 723 return context.Return(ret), nil 724 case SUICIDE: 725 receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes()) 726 balance := statedb.GetBalance(context.Address()) 727 728 self.Printf(" => (%x) %v", receiver.Address()[:4], balance) 729 730 receiver.AddAmount(balance) 731 statedb.Delete(context.Address()) 732 733 fallthrough 734 case STOP: // Stop the context 735 self.Endl() 736 737 return context.Return(nil), nil 738 default: 739 vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) 740 741 panic(fmt.Errorf("Invalid opcode %x", op)) 742 } 743 744 pc++ 745 746 self.Endl() 747 748 if self.Dbg != nil { 749 for _, instrNo := range self.Dbg.BreakPoints() { 750 if pc == uint64(instrNo) { 751 self.Stepping = true 752 753 if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) { 754 return nil, nil 755 } 756 } else if self.Stepping { 757 if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) { 758 return nil, nil 759 } 760 } 761 } 762 } 763 764 } 765 } 766 767 func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) { 768 gas := new(big.Int) 769 addStepGasUsage := func(amount *big.Int) { 770 if amount.Cmp(ethutil.Big0) >= 0 { 771 gas.Add(gas, amount) 772 } 773 } 774 775 addStepGasUsage(GasStep) 776 777 var newMemSize *big.Int = ethutil.Big0 778 var additionalGas *big.Int = new(big.Int) 779 // Stack Check, memory resize & gas phase 780 switch op { 781 // Stack checks only 782 case ISZERO, CALLDATALOAD, POP, JUMP, NOT: // 1 783 stack.require(1) 784 case JUMPI, ADD, SUB, DIV, SDIV, MOD, SMOD, LT, GT, SLT, SGT, EQ, AND, OR, XOR, BYTE, SIGNEXTEND: // 2 785 stack.require(2) 786 case ADDMOD, MULMOD: // 3 787 stack.require(3) 788 case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: 789 n := int(op - SWAP1 + 2) 790 stack.require(n) 791 case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 792 n := int(op - DUP1 + 1) 793 stack.require(n) 794 case LOG0, LOG1, LOG2, LOG3, LOG4: 795 n := int(op - LOG0) 796 stack.require(n + 2) 797 798 gas.Set(GasLog) 799 addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog)) 800 801 mSize, mStart := stack.Peekn() 802 addStepGasUsage(mSize) 803 804 newMemSize = calcMemSize(mStart, mSize) 805 case EXP: 806 stack.require(2) 807 808 gas.Set(big.NewInt(int64(len(stack.data[stack.Len()-2].Bytes()) + 1))) 809 // Gas only 810 case STOP: 811 gas.Set(ethutil.Big0) 812 case SUICIDE: 813 stack.require(1) 814 815 gas.Set(ethutil.Big0) 816 case SLOAD: 817 stack.require(1) 818 819 gas.Set(GasSLoad) 820 // Memory resize & Gas 821 case SSTORE: 822 stack.require(2) 823 824 var mult *big.Int 825 y, x := stack.Peekn() 826 val := statedb.GetState(context.Address(), x.Bytes()) 827 if len(val) == 0 && len(y.Bytes()) > 0 { 828 // 0 => non 0 829 mult = ethutil.Big3 830 } else if len(val) > 0 && len(y.Bytes()) == 0 { 831 statedb.Refund(caller.Address(), GasSStoreRefund) 832 833 mult = ethutil.Big0 834 } else { 835 // non 0 => non 0 (or 0 => 0) 836 mult = ethutil.Big1 837 } 838 gas.Set(new(big.Int).Mul(mult, GasSStore)) 839 case BALANCE: 840 stack.require(1) 841 gas.Set(GasBalance) 842 case MSTORE: 843 stack.require(2) 844 newMemSize = calcMemSize(stack.Peek(), u256(32)) 845 case MLOAD: 846 stack.require(1) 847 848 newMemSize = calcMemSize(stack.Peek(), u256(32)) 849 case MSTORE8: 850 stack.require(2) 851 newMemSize = calcMemSize(stack.Peek(), u256(1)) 852 case RETURN: 853 stack.require(2) 854 855 newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) 856 case SHA3: 857 stack.require(2) 858 gas.Set(GasSha) 859 newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) 860 additionalGas.Set(stack.data[stack.Len()-2]) 861 case CALLDATACOPY: 862 stack.require(2) 863 864 newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) 865 additionalGas.Set(stack.data[stack.Len()-3]) 866 case CODECOPY: 867 stack.require(3) 868 869 newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3]) 870 additionalGas.Set(stack.data[stack.Len()-3]) 871 case EXTCODECOPY: 872 stack.require(4) 873 874 newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4]) 875 additionalGas.Set(stack.data[stack.Len()-4]) 876 case CALL, CALLCODE: 877 stack.require(7) 878 gas.Set(GasCall) 879 addStepGasUsage(stack.data[stack.Len()-1]) 880 881 x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7]) 882 y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5]) 883 884 newMemSize = ethutil.BigMax(x, y) 885 case CREATE: 886 stack.require(3) 887 gas.Set(GasCreate) 888 889 newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3]) 890 } 891 892 switch op { 893 case CALLDATACOPY, CODECOPY, EXTCODECOPY: 894 additionalGas.Add(additionalGas, u256(31)) 895 additionalGas.Div(additionalGas, u256(32)) 896 addStepGasUsage(additionalGas) 897 case SHA3: 898 additionalGas.Add(additionalGas, u256(31)) 899 additionalGas.Div(additionalGas, u256(32)) 900 additionalGas.Mul(additionalGas, GasSha3Byte) 901 addStepGasUsage(additionalGas) 902 } 903 904 if newMemSize.Cmp(ethutil.Big0) > 0 { 905 newMemSize.Add(newMemSize, u256(31)) 906 newMemSize.Div(newMemSize, u256(32)) 907 newMemSize.Mul(newMemSize, u256(32)) 908 909 if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 { 910 memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len()))) 911 memGasUsage.Mul(GasMemory, memGasUsage) 912 memGasUsage.Div(memGasUsage, u256(32)) 913 914 addStepGasUsage(memGasUsage) 915 } 916 917 } 918 919 return newMemSize, gas 920 } 921 922 func (self *Vm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) { 923 gas := p.Gas(len(callData)) 924 if context.UseGas(gas) { 925 ret = p.Call(callData) 926 self.Printf("NATIVE_FUNC => %x", ret) 927 self.Endl() 928 929 return context.Return(ret), nil 930 } else { 931 self.Printf("NATIVE_FUNC => failed").Endl() 932 933 tmp := new(big.Int).Set(context.Gas) 934 935 panic(OOG(gas, tmp).Error()) 936 } 937 } 938 939 func (self *Vm) Printf(format string, v ...interface{}) VirtualMachine { 940 if self.logTy == LogTyPretty { 941 self.logStr += fmt.Sprintf(format, v...) 942 } 943 944 return self 945 } 946 947 func (self *Vm) Endl() VirtualMachine { 948 if self.logTy == LogTyPretty { 949 vmlogger.Debugln(self.logStr) 950 self.logStr = "" 951 } 952 953 return self 954 } 955 956 func (self *Vm) Env() Environment { 957 return self.env 958 }