github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/core/vm/vm.go (about) 1 // Copyright 2014 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 implements the Ethereum Virtual Machine. 18 package vm 19 20 import ( 21 "fmt" 22 "math/big" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/state" 26 "github.com/ethereum/go-ethereum/crypto" 27 "github.com/ethereum/go-ethereum/logger" 28 "github.com/ethereum/go-ethereum/logger/glog" 29 "github.com/ethereum/go-ethereum/params" 30 ) 31 32 // Vm implements VirtualMachine 33 type Vm struct { 34 env Environment 35 } 36 37 // New returns a new Virtual Machine 38 func New(env Environment) *Vm { 39 return &Vm{env: env} 40 } 41 42 // Run loops and evaluates the contract's code with the given input data 43 func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) { 44 self.env.SetDepth(self.env.Depth() + 1) 45 defer self.env.SetDepth(self.env.Depth() - 1) 46 47 // User defer pattern to check for an error and, based on the error being nil or not, use all gas and return. 48 defer func() { 49 if err != nil { 50 // In case of a VM exception (known exceptions) all gas consumed (panics NOT included). 51 context.UseGas(context.Gas) 52 53 ret = context.Return(nil) 54 } 55 }() 56 57 if context.CodeAddr != nil { 58 if p := Precompiled[context.CodeAddr.Str()]; p != nil { 59 return self.RunPrecompiled(p, input, context) 60 } 61 } 62 63 var ( 64 codehash = crypto.Sha3Hash(context.Code) // codehash is used when doing jump dest caching 65 program *Program 66 ) 67 if EnableJit { 68 // Fetch program status. 69 // * If ready run using JIT 70 // * If unknown, compile in a seperate goroutine 71 // * If forced wait for compilation and run once done 72 if status := GetProgramStatus(codehash); status == progReady { 73 return RunProgram(GetProgram(codehash), self.env, context, input) 74 } else if status == progUnknown { 75 if ForceJit { 76 // Create and compile program 77 program = NewProgram(context.Code) 78 perr := CompileProgram(program) 79 if perr == nil { 80 return RunProgram(program, self.env, context, input) 81 } 82 glog.V(logger.Info).Infoln("error compiling program", err) 83 } else { 84 // create and compile the program. Compilation 85 // is done in a seperate goroutine 86 program = NewProgram(context.Code) 87 go func() { 88 err := CompileProgram(program) 89 if err != nil { 90 glog.V(logger.Info).Infoln("error compiling program", err) 91 return 92 } 93 }() 94 } 95 } 96 } 97 98 var ( 99 caller = context.caller 100 code = context.Code 101 value = context.value 102 price = context.Price 103 104 op OpCode // current opcode 105 mem = NewMemory() // bound memory 106 stack = newstack() // local stack 107 statedb = self.env.State() // current state 108 // For optimisation reason we're using uint64 as the program counter. 109 // It's theoretically possible to go above 2^64. The YP defines the PC to be uint256. Pratically much less so feasible. 110 pc = uint64(0) // program counter 111 112 // jump evaluates and checks whether the given jump destination is a valid one 113 // if valid move the `pc` otherwise return an error. 114 jump = func(from uint64, to *big.Int) error { 115 if !context.jumpdests.has(codehash, code, to) { 116 nop := context.GetOp(to.Uint64()) 117 return fmt.Errorf("invalid jump destination (%v) %v", nop, to) 118 } 119 120 pc = to.Uint64() 121 122 return nil 123 } 124 125 newMemSize *big.Int 126 cost *big.Int 127 ) 128 129 // User defer pattern to check for an error and, based on the error being nil or not, use all gas and return. 130 defer func() { 131 if err != nil { 132 self.log(pc, op, context.Gas, cost, mem, stack, context, err) 133 } 134 }() 135 136 // Don't bother with the execution if there's no code. 137 if len(code) == 0 { 138 return context.Return(nil), nil 139 } 140 141 for { 142 // Overhead of the atomic read might not be worth it 143 /* TODO this still causes a few issues in the tests 144 if program != nil && progStatus(atomic.LoadInt32(&program.status)) == progReady { 145 // move execution 146 glog.V(logger.Info).Infoln("Moved execution to JIT") 147 return runProgram(program, pc, mem, stack, self.env, context, input) 148 } 149 */ 150 // The base for all big integer arithmetic 151 base := new(big.Int) 152 153 // Get the memory location of pc 154 op = context.GetOp(pc) 155 156 // calculate the new memory size and gas price for the current executing opcode 157 newMemSize, cost, err = calculateGasAndSize(self.env, context, caller, op, statedb, mem, stack) 158 if err != nil { 159 return nil, err 160 } 161 162 // Use the calculated gas. When insufficient gas is present, use all gas and return an 163 // Out Of Gas error 164 if !context.UseGas(cost) { 165 return nil, OutOfGasError 166 } 167 168 // Resize the memory calculated previously 169 mem.Resize(newMemSize.Uint64()) 170 // Add a log message 171 self.log(pc, op, context.Gas, cost, mem, stack, context, nil) 172 173 switch op { 174 case ADD: 175 x, y := stack.pop(), stack.pop() 176 177 base.Add(x, y) 178 179 U256(base) 180 181 // pop result back on the stack 182 stack.push(base) 183 case SUB: 184 x, y := stack.pop(), stack.pop() 185 186 base.Sub(x, y) 187 188 U256(base) 189 190 // pop result back on the stack 191 stack.push(base) 192 case MUL: 193 x, y := stack.pop(), stack.pop() 194 195 base.Mul(x, y) 196 197 U256(base) 198 199 // pop result back on the stack 200 stack.push(base) 201 case DIV: 202 x, y := stack.pop(), stack.pop() 203 204 if y.Cmp(common.Big0) != 0 { 205 base.Div(x, y) 206 } 207 208 U256(base) 209 210 // pop result back on the stack 211 stack.push(base) 212 case SDIV: 213 x, y := S256(stack.pop()), S256(stack.pop()) 214 215 if y.Cmp(common.Big0) == 0 { 216 base.Set(common.Big0) 217 } else { 218 n := new(big.Int) 219 if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 { 220 n.SetInt64(-1) 221 } else { 222 n.SetInt64(1) 223 } 224 225 base.Div(x.Abs(x), y.Abs(y)).Mul(base, n) 226 227 U256(base) 228 } 229 230 stack.push(base) 231 case MOD: 232 x, y := stack.pop(), stack.pop() 233 234 if y.Cmp(common.Big0) == 0 { 235 base.Set(common.Big0) 236 } else { 237 base.Mod(x, y) 238 } 239 240 U256(base) 241 242 stack.push(base) 243 case SMOD: 244 x, y := S256(stack.pop()), S256(stack.pop()) 245 246 if y.Cmp(common.Big0) == 0 { 247 base.Set(common.Big0) 248 } else { 249 n := new(big.Int) 250 if x.Cmp(common.Big0) < 0 { 251 n.SetInt64(-1) 252 } else { 253 n.SetInt64(1) 254 } 255 256 base.Mod(x.Abs(x), y.Abs(y)).Mul(base, n) 257 258 U256(base) 259 } 260 261 stack.push(base) 262 263 case EXP: 264 x, y := stack.pop(), stack.pop() 265 266 base.Exp(x, y, Pow256) 267 268 U256(base) 269 270 stack.push(base) 271 case SIGNEXTEND: 272 back := stack.pop() 273 if back.Cmp(big.NewInt(31)) < 0 { 274 bit := uint(back.Uint64()*8 + 7) 275 num := stack.pop() 276 mask := new(big.Int).Lsh(common.Big1, bit) 277 mask.Sub(mask, common.Big1) 278 if common.BitTest(num, int(bit)) { 279 num.Or(num, mask.Not(mask)) 280 } else { 281 num.And(num, mask) 282 } 283 284 num = U256(num) 285 286 stack.push(num) 287 } 288 case NOT: 289 stack.push(U256(new(big.Int).Not(stack.pop()))) 290 case LT: 291 x, y := stack.pop(), stack.pop() 292 293 // x < y 294 if x.Cmp(y) < 0 { 295 stack.push(common.BigTrue) 296 } else { 297 stack.push(common.BigFalse) 298 } 299 case GT: 300 x, y := stack.pop(), stack.pop() 301 302 // x > y 303 if x.Cmp(y) > 0 { 304 stack.push(common.BigTrue) 305 } else { 306 stack.push(common.BigFalse) 307 } 308 309 case SLT: 310 x, y := S256(stack.pop()), S256(stack.pop()) 311 312 // x < y 313 if x.Cmp(S256(y)) < 0 { 314 stack.push(common.BigTrue) 315 } else { 316 stack.push(common.BigFalse) 317 } 318 case SGT: 319 x, y := S256(stack.pop()), S256(stack.pop()) 320 321 // x > y 322 if x.Cmp(y) > 0 { 323 stack.push(common.BigTrue) 324 } else { 325 stack.push(common.BigFalse) 326 } 327 328 case EQ: 329 x, y := stack.pop(), stack.pop() 330 331 // x == y 332 if x.Cmp(y) == 0 { 333 stack.push(common.BigTrue) 334 } else { 335 stack.push(common.BigFalse) 336 } 337 case ISZERO: 338 x := stack.pop() 339 if x.Cmp(common.BigFalse) > 0 { 340 stack.push(common.BigFalse) 341 } else { 342 stack.push(common.BigTrue) 343 } 344 345 case AND: 346 x, y := stack.pop(), stack.pop() 347 348 stack.push(base.And(x, y)) 349 case OR: 350 x, y := stack.pop(), stack.pop() 351 352 stack.push(base.Or(x, y)) 353 case XOR: 354 x, y := stack.pop(), stack.pop() 355 356 stack.push(base.Xor(x, y)) 357 case BYTE: 358 th, val := stack.pop(), stack.pop() 359 360 if th.Cmp(big.NewInt(32)) < 0 { 361 byt := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()])) 362 363 base.Set(byt) 364 } else { 365 base.Set(common.BigFalse) 366 } 367 368 stack.push(base) 369 case ADDMOD: 370 x := stack.pop() 371 y := stack.pop() 372 z := stack.pop() 373 374 if z.Cmp(Zero) > 0 { 375 add := new(big.Int).Add(x, y) 376 base.Mod(add, z) 377 378 base = U256(base) 379 } 380 381 stack.push(base) 382 case MULMOD: 383 x := stack.pop() 384 y := stack.pop() 385 z := stack.pop() 386 387 if z.Cmp(Zero) > 0 { 388 mul := new(big.Int).Mul(x, y) 389 base.Mod(mul, z) 390 391 U256(base) 392 } 393 394 stack.push(base) 395 396 case SHA3: 397 offset, size := stack.pop(), stack.pop() 398 data := crypto.Sha3(mem.Get(offset.Int64(), size.Int64())) 399 400 stack.push(common.BigD(data)) 401 402 case ADDRESS: 403 stack.push(common.Bytes2Big(context.Address().Bytes())) 404 405 case BALANCE: 406 addr := common.BigToAddress(stack.pop()) 407 balance := statedb.GetBalance(addr) 408 409 stack.push(new(big.Int).Set(balance)) 410 411 case ORIGIN: 412 origin := self.env.Origin() 413 414 stack.push(origin.Big()) 415 416 case CALLER: 417 caller := context.caller.Address() 418 stack.push(common.Bytes2Big(caller.Bytes())) 419 420 case CALLVALUE: 421 stack.push(new(big.Int).Set(value)) 422 423 case CALLDATALOAD: 424 data := getData(input, stack.pop(), common.Big32) 425 426 stack.push(common.Bytes2Big(data)) 427 case CALLDATASIZE: 428 l := int64(len(input)) 429 stack.push(big.NewInt(l)) 430 431 case CALLDATACOPY: 432 var ( 433 mOff = stack.pop() 434 cOff = stack.pop() 435 l = stack.pop() 436 ) 437 data := getData(input, cOff, l) 438 439 mem.Set(mOff.Uint64(), l.Uint64(), data) 440 441 case CODESIZE, EXTCODESIZE: 442 var code []byte 443 if op == EXTCODESIZE { 444 addr := common.BigToAddress(stack.pop()) 445 446 code = statedb.GetCode(addr) 447 } else { 448 code = context.Code 449 } 450 451 l := big.NewInt(int64(len(code))) 452 stack.push(l) 453 454 case CODECOPY, EXTCODECOPY: 455 var code []byte 456 if op == EXTCODECOPY { 457 addr := common.BigToAddress(stack.pop()) 458 code = statedb.GetCode(addr) 459 } else { 460 code = context.Code 461 } 462 463 var ( 464 mOff = stack.pop() 465 cOff = stack.pop() 466 l = stack.pop() 467 ) 468 469 codeCopy := getData(code, cOff, l) 470 471 mem.Set(mOff.Uint64(), l.Uint64(), codeCopy) 472 473 case GASPRICE: 474 stack.push(new(big.Int).Set(context.Price)) 475 476 case BLOCKHASH: 477 num := stack.pop() 478 479 n := new(big.Int).Sub(self.env.BlockNumber(), common.Big257) 480 if num.Cmp(n) > 0 && num.Cmp(self.env.BlockNumber()) < 0 { 481 stack.push(self.env.GetHash(num.Uint64()).Big()) 482 } else { 483 stack.push(common.Big0) 484 } 485 486 case COINBASE: 487 coinbase := self.env.Coinbase() 488 489 stack.push(coinbase.Big()) 490 491 case TIMESTAMP: 492 time := self.env.Time() 493 494 stack.push(new(big.Int).Set(time)) 495 496 case NUMBER: 497 number := self.env.BlockNumber() 498 499 stack.push(U256(number)) 500 501 case DIFFICULTY: 502 difficulty := self.env.Difficulty() 503 504 stack.push(new(big.Int).Set(difficulty)) 505 506 case GASLIMIT: 507 508 stack.push(new(big.Int).Set(self.env.GasLimit())) 509 510 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: 511 size := uint64(op - PUSH1 + 1) 512 byts := getData(code, new(big.Int).SetUint64(pc+1), new(big.Int).SetUint64(size)) 513 // push value to stack 514 stack.push(common.Bytes2Big(byts)) 515 pc += size 516 517 case POP: 518 stack.pop() 519 case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 520 n := int(op - DUP1 + 1) 521 stack.dup(n) 522 523 case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: 524 n := int(op - SWAP1 + 2) 525 stack.swap(n) 526 527 case LOG0, LOG1, LOG2, LOG3, LOG4: 528 n := int(op - LOG0) 529 topics := make([]common.Hash, n) 530 mStart, mSize := stack.pop(), stack.pop() 531 for i := 0; i < n; i++ { 532 topics[i] = common.BigToHash(stack.pop()) 533 } 534 535 data := mem.Get(mStart.Int64(), mSize.Int64()) 536 log := state.NewLog(context.Address(), topics, data, self.env.BlockNumber().Uint64()) 537 self.env.AddLog(log) 538 539 case MLOAD: 540 offset := stack.pop() 541 val := common.BigD(mem.Get(offset.Int64(), 32)) 542 stack.push(val) 543 544 case MSTORE: 545 // pop value of the stack 546 mStart, val := stack.pop(), stack.pop() 547 mem.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256)) 548 549 case MSTORE8: 550 off, val := stack.pop().Int64(), stack.pop().Int64() 551 552 mem.store[off] = byte(val & 0xff) 553 554 case SLOAD: 555 loc := common.BigToHash(stack.pop()) 556 val := statedb.GetState(context.Address(), loc).Big() 557 stack.push(val) 558 559 case SSTORE: 560 loc := common.BigToHash(stack.pop()) 561 val := stack.pop() 562 563 statedb.SetState(context.Address(), loc, common.BigToHash(val)) 564 565 case JUMP: 566 if err := jump(pc, stack.pop()); err != nil { 567 return nil, err 568 } 569 570 continue 571 case JUMPI: 572 pos, cond := stack.pop(), stack.pop() 573 574 if cond.Cmp(common.BigTrue) >= 0 { 575 if err := jump(pc, pos); err != nil { 576 return nil, err 577 } 578 579 continue 580 } 581 582 case JUMPDEST: 583 case PC: 584 stack.push(new(big.Int).SetUint64(pc)) 585 case MSIZE: 586 stack.push(big.NewInt(int64(mem.Len()))) 587 case GAS: 588 stack.push(new(big.Int).Set(context.Gas)) 589 case CREATE: 590 591 var ( 592 value = stack.pop() 593 offset, size = stack.pop(), stack.pop() 594 input = mem.Get(offset.Int64(), size.Int64()) 595 gas = new(big.Int).Set(context.Gas) 596 addr common.Address 597 ) 598 599 context.UseGas(context.Gas) 600 ret, suberr, ref := self.env.Create(context, input, gas, price, value) 601 if suberr != nil { 602 stack.push(common.BigFalse) 603 604 } else { 605 // gas < len(ret) * CreateDataGas == NO_CODE 606 dataGas := big.NewInt(int64(len(ret))) 607 dataGas.Mul(dataGas, params.CreateDataGas) 608 if context.UseGas(dataGas) { 609 ref.SetCode(ret) 610 } 611 addr = ref.Address() 612 613 stack.push(addr.Big()) 614 615 } 616 617 case CALL, CALLCODE: 618 gas := stack.pop() 619 // pop gas and value of the stack. 620 addr, value := stack.pop(), stack.pop() 621 value = U256(value) 622 // pop input size and offset 623 inOffset, inSize := stack.pop(), stack.pop() 624 // pop return size and offset 625 retOffset, retSize := stack.pop(), stack.pop() 626 627 address := common.BigToAddress(addr) 628 629 // Get the arguments from the memory 630 args := mem.Get(inOffset.Int64(), inSize.Int64()) 631 632 if len(value.Bytes()) > 0 { 633 gas.Add(gas, params.CallStipend) 634 } 635 636 var ( 637 ret []byte 638 err error 639 ) 640 if op == CALLCODE { 641 ret, err = self.env.CallCode(context, address, args, gas, price, value) 642 } else { 643 ret, err = self.env.Call(context, address, args, gas, price, value) 644 } 645 646 if err != nil { 647 stack.push(common.BigFalse) 648 649 } else { 650 stack.push(common.BigTrue) 651 652 mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) 653 } 654 655 case RETURN: 656 offset, size := stack.pop(), stack.pop() 657 ret := mem.GetPtr(offset.Int64(), size.Int64()) 658 659 return context.Return(ret), nil 660 case SUICIDE: 661 receiver := statedb.GetOrNewStateObject(common.BigToAddress(stack.pop())) 662 balance := statedb.GetBalance(context.Address()) 663 664 receiver.AddBalance(balance) 665 666 statedb.Delete(context.Address()) 667 668 fallthrough 669 case STOP: // Stop the context 670 671 return context.Return(nil), nil 672 default: 673 674 return nil, fmt.Errorf("Invalid opcode %x", op) 675 } 676 677 pc++ 678 679 } 680 } 681 682 // calculateGasAndSize calculates the required given the opcode and stack items calculates the new memorysize for 683 // the operation. This does not reduce gas or resizes the memory. 684 func calculateGasAndSize(env Environment, context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *stack) (*big.Int, *big.Int, error) { 685 var ( 686 gas = new(big.Int) 687 newMemSize *big.Int = new(big.Int) 688 ) 689 err := baseCheck(op, stack, gas) 690 if err != nil { 691 return nil, nil, err 692 } 693 694 // stack Check, memory resize & gas phase 695 switch op { 696 case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16: 697 n := int(op - SWAP1 + 2) 698 err := stack.require(n) 699 if err != nil { 700 return nil, nil, err 701 } 702 gas.Set(GasFastestStep) 703 case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 704 n := int(op - DUP1 + 1) 705 err := stack.require(n) 706 if err != nil { 707 return nil, nil, err 708 } 709 gas.Set(GasFastestStep) 710 case LOG0, LOG1, LOG2, LOG3, LOG4: 711 n := int(op - LOG0) 712 err := stack.require(n + 2) 713 if err != nil { 714 return nil, nil, err 715 } 716 717 mSize, mStart := stack.data[stack.len()-2], stack.data[stack.len()-1] 718 719 gas.Add(gas, params.LogGas) 720 gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(n)), params.LogTopicGas)) 721 gas.Add(gas, new(big.Int).Mul(mSize, params.LogDataGas)) 722 723 newMemSize = calcMemSize(mStart, mSize) 724 case EXP: 725 gas.Add(gas, new(big.Int).Mul(big.NewInt(int64(len(stack.data[stack.len()-2].Bytes()))), params.ExpByteGas)) 726 case SSTORE: 727 err := stack.require(2) 728 if err != nil { 729 return nil, nil, err 730 } 731 732 var g *big.Int 733 y, x := stack.data[stack.len()-2], stack.data[stack.len()-1] 734 val := statedb.GetState(context.Address(), common.BigToHash(x)) 735 736 // This checks for 3 scenario's and calculates gas accordingly 737 // 1. From a zero-value address to a non-zero value (NEW VALUE) 738 // 2. From a non-zero value address to a zero-value address (DELETE) 739 // 3. From a nen-zero to a non-zero (CHANGE) 740 if common.EmptyHash(val) && !common.EmptyHash(common.BigToHash(y)) { 741 // 0 => non 0 742 g = params.SstoreSetGas 743 } else if !common.EmptyHash(val) && common.EmptyHash(common.BigToHash(y)) { 744 statedb.Refund(params.SstoreRefundGas) 745 746 g = params.SstoreClearGas 747 } else { 748 // non 0 => non 0 (or 0 => 0) 749 g = params.SstoreClearGas 750 } 751 gas.Set(g) 752 case SUICIDE: 753 if !statedb.IsDeleted(context.Address()) { 754 statedb.Refund(params.SuicideRefundGas) 755 } 756 case MLOAD: 757 newMemSize = calcMemSize(stack.peek(), u256(32)) 758 case MSTORE8: 759 newMemSize = calcMemSize(stack.peek(), u256(1)) 760 case MSTORE: 761 newMemSize = calcMemSize(stack.peek(), u256(32)) 762 case RETURN: 763 newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-2]) 764 case SHA3: 765 newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-2]) 766 767 words := toWordSize(stack.data[stack.len()-2]) 768 gas.Add(gas, words.Mul(words, params.Sha3WordGas)) 769 case CALLDATACOPY: 770 newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3]) 771 772 words := toWordSize(stack.data[stack.len()-3]) 773 gas.Add(gas, words.Mul(words, params.CopyGas)) 774 case CODECOPY: 775 newMemSize = calcMemSize(stack.peek(), stack.data[stack.len()-3]) 776 777 words := toWordSize(stack.data[stack.len()-3]) 778 gas.Add(gas, words.Mul(words, params.CopyGas)) 779 case EXTCODECOPY: 780 newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-4]) 781 782 words := toWordSize(stack.data[stack.len()-4]) 783 gas.Add(gas, words.Mul(words, params.CopyGas)) 784 785 case CREATE: 786 newMemSize = calcMemSize(stack.data[stack.len()-2], stack.data[stack.len()-3]) 787 case CALL, CALLCODE: 788 gas.Add(gas, stack.data[stack.len()-1]) 789 790 if op == CALL { 791 if env.State().GetStateObject(common.BigToAddress(stack.data[stack.len()-2])) == nil { 792 gas.Add(gas, params.CallNewAccountGas) 793 } 794 } 795 796 if len(stack.data[stack.len()-3].Bytes()) > 0 { 797 gas.Add(gas, params.CallValueTransferGas) 798 } 799 800 x := calcMemSize(stack.data[stack.len()-6], stack.data[stack.len()-7]) 801 y := calcMemSize(stack.data[stack.len()-4], stack.data[stack.len()-5]) 802 803 newMemSize = common.BigMax(x, y) 804 } 805 806 if newMemSize.Cmp(common.Big0) > 0 { 807 newMemSizeWords := toWordSize(newMemSize) 808 newMemSize.Mul(newMemSizeWords, u256(32)) 809 810 if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 { 811 oldSize := toWordSize(big.NewInt(int64(mem.Len()))) 812 pow := new(big.Int).Exp(oldSize, common.Big2, Zero) 813 linCoef := new(big.Int).Mul(oldSize, params.MemoryGas) 814 quadCoef := new(big.Int).Div(pow, params.QuadCoeffDiv) 815 oldTotalFee := new(big.Int).Add(linCoef, quadCoef) 816 817 pow.Exp(newMemSizeWords, common.Big2, Zero) 818 linCoef = new(big.Int).Mul(newMemSizeWords, params.MemoryGas) 819 quadCoef = new(big.Int).Div(pow, params.QuadCoeffDiv) 820 newTotalFee := new(big.Int).Add(linCoef, quadCoef) 821 822 fee := new(big.Int).Sub(newTotalFee, oldTotalFee) 823 gas.Add(gas, fee) 824 } 825 } 826 827 return newMemSize, gas, nil 828 } 829 830 // RunPrecompile runs and evaluate the output of a precompiled contract defined in contracts.go 831 func (self *Vm) RunPrecompiled(p *PrecompiledAccount, input []byte, context *Context) (ret []byte, err error) { 832 gas := p.Gas(len(input)) 833 if context.UseGas(gas) { 834 ret = p.Call(input) 835 836 return context.Return(ret), nil 837 } else { 838 return nil, OutOfGasError 839 } 840 } 841 842 // log emits a log event to the environment for each opcode encountered. This is not to be confused with the 843 // LOG* opcode. 844 func (self *Vm) log(pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *stack, context *Context, err error) { 845 if Debug { 846 mem := make([]byte, len(memory.Data())) 847 copy(mem, memory.Data()) 848 stck := make([]*big.Int, len(stack.Data())) 849 copy(stck, stack.Data()) 850 851 object := context.self.(*state.StateObject) 852 storage := make(map[common.Hash][]byte) 853 object.EachStorage(func(k, v []byte) { 854 storage[common.BytesToHash(k)] = v 855 }) 856 857 self.env.AddStructLog(StructLog{pc, op, new(big.Int).Set(gas), cost, mem, stck, storage, err}) 858 } 859 } 860 861 // Environment returns the current workable state of the VM 862 func (self *Vm) Env() Environment { 863 return self.env 864 }