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  }