github.com/anthdm/go-ethereum@v1.8.4-0.20180412101906-60516c83b011/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  	"errors"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/math"
    26  	"github.com/ethereum/go-ethereum/core/types"
    27  	"github.com/ethereum/go-ethereum/crypto"
    28  	"github.com/ethereum/go-ethereum/params"
    29  )
    30  
    31  var (
    32  	bigZero                  = new(big.Int)
    33  	tt255                    = math.BigPow(2, 255)
    34  	tt256                    = math.BigPow(2, 256)
    35  	errWriteProtection       = errors.New("evm: write protection")
    36  	errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
    37  	errExecutionReverted     = errors.New("evm: execution reverted")
    38  	errMaxCodeSizeExceeded   = errors.New("evm: max code size exceeded")
    39  )
    40  
    41  func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    42  	x, y := stack.pop(), stack.peek()
    43  	math.U256(y.Add(x, y))
    44  
    45  	evm.interpreter.intPool.put(x)
    46  	return nil, nil
    47  }
    48  
    49  func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    50  	x, y := stack.pop(), stack.peek()
    51  	math.U256(y.Sub(x, y))
    52  
    53  	evm.interpreter.intPool.put(x)
    54  	return nil, nil
    55  }
    56  
    57  func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    58  	x, y := stack.pop(), stack.pop()
    59  	stack.push(math.U256(x.Mul(x, y)))
    60  
    61  	evm.interpreter.intPool.put(y)
    62  
    63  	return nil, nil
    64  }
    65  
    66  func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    67  	x, y := stack.pop(), stack.peek()
    68  	if y.Sign() != 0 {
    69  		math.U256(y.Div(x, y))
    70  	} else {
    71  		y.SetUint64(0)
    72  	}
    73  	evm.interpreter.intPool.put(x)
    74  	return nil, nil
    75  }
    76  
    77  func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    78  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
    79  	res := evm.interpreter.intPool.getZero()
    80  
    81  	if y.Sign() == 0 || x.Sign() == 0 {
    82  		stack.push(res)
    83  	} else {
    84  		if x.Sign() != y.Sign() {
    85  			res.Div(x.Abs(x), y.Abs(y))
    86  			res.Neg(res)
    87  		} else {
    88  			res.Div(x.Abs(x), y.Abs(y))
    89  		}
    90  		stack.push(math.U256(res))
    91  	}
    92  	evm.interpreter.intPool.put(x, 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(x.SetUint64(0))
   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  	res := evm.interpreter.intPool.getZero()
   110  
   111  	if y.Sign() == 0 {
   112  		stack.push(res)
   113  	} else {
   114  		if x.Sign() < 0 {
   115  			res.Mod(x.Abs(x), y.Abs(y))
   116  			res.Neg(res)
   117  		} else {
   118  			res.Mod(x.Abs(x), y.Abs(y))
   119  		}
   120  		stack.push(math.U256(res))
   121  	}
   122  	evm.interpreter.intPool.put(x, y)
   123  	return nil, nil
   124  }
   125  
   126  func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   127  	base, exponent := stack.pop(), stack.pop()
   128  	stack.push(math.Exp(base, exponent))
   129  
   130  	evm.interpreter.intPool.put(base, exponent)
   131  
   132  	return nil, nil
   133  }
   134  
   135  func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   136  	back := stack.pop()
   137  	if back.Cmp(big.NewInt(31)) < 0 {
   138  		bit := uint(back.Uint64()*8 + 7)
   139  		num := stack.pop()
   140  		mask := back.Lsh(common.Big1, bit)
   141  		mask.Sub(mask, common.Big1)
   142  		if num.Bit(int(bit)) > 0 {
   143  			num.Or(num, mask.Not(mask))
   144  		} else {
   145  			num.And(num, mask)
   146  		}
   147  
   148  		stack.push(math.U256(num))
   149  	}
   150  
   151  	evm.interpreter.intPool.put(back)
   152  	return nil, nil
   153  }
   154  
   155  func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   156  	x := stack.peek()
   157  	math.U256(x.Not(x))
   158  	return nil, nil
   159  }
   160  
   161  func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   162  	x, y := stack.pop(), stack.peek()
   163  	if x.Cmp(y) < 0 {
   164  		y.SetUint64(1)
   165  	} else {
   166  		y.SetUint64(0)
   167  	}
   168  	evm.interpreter.intPool.put(x)
   169  	return nil, nil
   170  }
   171  
   172  func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   173  	x, y := stack.pop(), stack.peek()
   174  	if x.Cmp(y) > 0 {
   175  		y.SetUint64(1)
   176  	} else {
   177  		y.SetUint64(0)
   178  	}
   179  	evm.interpreter.intPool.put(x)
   180  	return nil, nil
   181  }
   182  
   183  func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   184  	x, y := stack.pop(), stack.peek()
   185  
   186  	xSign := x.Cmp(tt255)
   187  	ySign := y.Cmp(tt255)
   188  
   189  	switch {
   190  	case xSign >= 0 && ySign < 0:
   191  		y.SetUint64(1)
   192  
   193  	case xSign < 0 && ySign >= 0:
   194  		y.SetUint64(0)
   195  
   196  	default:
   197  		if x.Cmp(y) < 0 {
   198  			y.SetUint64(1)
   199  		} else {
   200  			y.SetUint64(0)
   201  		}
   202  	}
   203  	evm.interpreter.intPool.put(x)
   204  	return nil, nil
   205  }
   206  
   207  func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   208  	x, y := stack.pop(), stack.peek()
   209  
   210  	xSign := x.Cmp(tt255)
   211  	ySign := y.Cmp(tt255)
   212  
   213  	switch {
   214  	case xSign >= 0 && ySign < 0:
   215  		y.SetUint64(0)
   216  
   217  	case xSign < 0 && ySign >= 0:
   218  		y.SetUint64(1)
   219  
   220  	default:
   221  		if x.Cmp(y) > 0 {
   222  			y.SetUint64(1)
   223  		} else {
   224  			y.SetUint64(0)
   225  		}
   226  	}
   227  	evm.interpreter.intPool.put(x)
   228  	return nil, nil
   229  }
   230  
   231  func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   232  	x, y := stack.pop(), stack.peek()
   233  	if x.Cmp(y) == 0 {
   234  		y.SetUint64(1)
   235  	} else {
   236  		y.SetUint64(0)
   237  	}
   238  	evm.interpreter.intPool.put(x)
   239  	return nil, nil
   240  }
   241  
   242  func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   243  	x := stack.peek()
   244  	if x.Sign() > 0 {
   245  		x.SetUint64(0)
   246  	} else {
   247  		x.SetUint64(1)
   248  	}
   249  	return nil, nil
   250  }
   251  
   252  func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   253  	x, y := stack.pop(), stack.pop()
   254  	stack.push(x.And(x, y))
   255  
   256  	evm.interpreter.intPool.put(y)
   257  	return nil, nil
   258  }
   259  
   260  func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   261  	x, y := stack.pop(), stack.peek()
   262  	y.Or(x, y)
   263  
   264  	evm.interpreter.intPool.put(x)
   265  	return nil, nil
   266  }
   267  
   268  func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   269  	x, y := stack.pop(), stack.peek()
   270  	y.Xor(x, y)
   271  
   272  	evm.interpreter.intPool.put(x)
   273  	return nil, nil
   274  }
   275  
   276  func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   277  	th, val := stack.pop(), stack.peek()
   278  	if th.Cmp(common.Big32) < 0 {
   279  		b := math.Byte(val, 32, int(th.Int64()))
   280  		val.SetUint64(uint64(b))
   281  	} else {
   282  		val.SetUint64(0)
   283  	}
   284  	evm.interpreter.intPool.put(th)
   285  	return nil, nil
   286  }
   287  
   288  func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   289  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   290  	if z.Cmp(bigZero) > 0 {
   291  		x.Add(x, y)
   292  		x.Mod(x, z)
   293  		stack.push(math.U256(x))
   294  	} else {
   295  		stack.push(x.SetUint64(0))
   296  	}
   297  	evm.interpreter.intPool.put(y, z)
   298  	return nil, nil
   299  }
   300  
   301  func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   302  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   303  	if z.Cmp(bigZero) > 0 {
   304  		x.Mul(x, y)
   305  		x.Mod(x, z)
   306  		stack.push(math.U256(x))
   307  	} else {
   308  		stack.push(x.SetUint64(0))
   309  	}
   310  	evm.interpreter.intPool.put(y, z)
   311  	return nil, nil
   312  }
   313  
   314  // opSHL implements Shift Left
   315  // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
   316  // and pushes on the stack arg2 shifted to the left by arg1 number of bits.
   317  func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   318  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   319  	shift, value := math.U256(stack.pop()), math.U256(stack.peek())
   320  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   321  
   322  	if shift.Cmp(common.Big256) >= 0 {
   323  		value.SetUint64(0)
   324  		return nil, nil
   325  	}
   326  	n := uint(shift.Uint64())
   327  	math.U256(value.Lsh(value, n))
   328  
   329  	return nil, nil
   330  }
   331  
   332  // opSHR implements Logical Shift Right
   333  // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
   334  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
   335  func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   336  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   337  	shift, value := math.U256(stack.pop()), math.U256(stack.peek())
   338  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   339  
   340  	if shift.Cmp(common.Big256) >= 0 {
   341  		value.SetUint64(0)
   342  		return nil, nil
   343  	}
   344  	n := uint(shift.Uint64())
   345  	math.U256(value.Rsh(value, n))
   346  
   347  	return nil, nil
   348  }
   349  
   350  // opSAR implements Arithmetic Shift Right
   351  // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
   352  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
   353  func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   354  	// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
   355  	shift, value := math.U256(stack.pop()), math.S256(stack.pop())
   356  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   357  
   358  	if shift.Cmp(common.Big256) >= 0 {
   359  		if value.Sign() > 0 {
   360  			value.SetUint64(0)
   361  		} else {
   362  			value.SetInt64(-1)
   363  		}
   364  		stack.push(math.U256(value))
   365  		return nil, nil
   366  	}
   367  	n := uint(shift.Uint64())
   368  	value.Rsh(value, n)
   369  	stack.push(math.U256(value))
   370  
   371  	return nil, nil
   372  }
   373  
   374  func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   375  	offset, size := stack.pop(), stack.pop()
   376  	data := memory.Get(offset.Int64(), size.Int64())
   377  	hash := crypto.Keccak256(data)
   378  
   379  	if evm.vmConfig.EnablePreimageRecording {
   380  		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
   381  	}
   382  	stack.push(evm.interpreter.intPool.get().SetBytes(hash))
   383  
   384  	evm.interpreter.intPool.put(offset, size)
   385  	return nil, nil
   386  }
   387  
   388  func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   389  	stack.push(contract.Address().Big())
   390  	return nil, nil
   391  }
   392  
   393  func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   394  	slot := stack.peek()
   395  	slot.Set(evm.StateDB.GetBalance(common.BigToAddress(slot)))
   396  	return nil, nil
   397  }
   398  
   399  func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   400  	stack.push(evm.Origin.Big())
   401  	return nil, nil
   402  }
   403  
   404  func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   405  	stack.push(contract.Caller().Big())
   406  	return nil, nil
   407  }
   408  
   409  func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   410  	stack.push(evm.interpreter.intPool.get().Set(contract.value))
   411  	return nil, nil
   412  }
   413  
   414  func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   415  	stack.push(evm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32)))
   416  	return nil, nil
   417  }
   418  
   419  func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   420  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
   421  	return nil, nil
   422  }
   423  
   424  func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   425  	var (
   426  		memOffset  = stack.pop()
   427  		dataOffset = stack.pop()
   428  		length     = stack.pop()
   429  	)
   430  	memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length))
   431  
   432  	evm.interpreter.intPool.put(memOffset, dataOffset, length)
   433  	return nil, nil
   434  }
   435  
   436  func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   437  	stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData))))
   438  	return nil, nil
   439  }
   440  
   441  func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   442  	var (
   443  		memOffset  = stack.pop()
   444  		dataOffset = stack.pop()
   445  		length     = stack.pop()
   446  
   447  		end = evm.interpreter.intPool.get().Add(dataOffset, length)
   448  	)
   449  	defer evm.interpreter.intPool.put(memOffset, dataOffset, length, end)
   450  
   451  	if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() {
   452  		return nil, errReturnDataOutOfBounds
   453  	}
   454  	memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()])
   455  
   456  	return nil, nil
   457  }
   458  
   459  func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   460  	slot := stack.peek()
   461  	slot.SetUint64(uint64(evm.StateDB.GetCodeSize(common.BigToAddress(slot))))
   462  
   463  	return nil, nil
   464  }
   465  
   466  func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   467  	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
   468  	stack.push(l)
   469  
   470  	return nil, nil
   471  }
   472  
   473  func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   474  	var (
   475  		memOffset  = stack.pop()
   476  		codeOffset = stack.pop()
   477  		length     = stack.pop()
   478  	)
   479  	codeCopy := getDataBig(contract.Code, codeOffset, length)
   480  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   481  
   482  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   483  	return nil, nil
   484  }
   485  
   486  func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   487  	var (
   488  		addr       = common.BigToAddress(stack.pop())
   489  		memOffset  = stack.pop()
   490  		codeOffset = stack.pop()
   491  		length     = stack.pop()
   492  	)
   493  	codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length)
   494  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   495  
   496  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   497  	return nil, nil
   498  }
   499  
   500  func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   501  	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
   502  	return nil, nil
   503  }
   504  
   505  func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   506  	num := stack.pop()
   507  
   508  	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
   509  	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
   510  		stack.push(evm.GetHash(num.Uint64()).Big())
   511  	} else {
   512  		stack.push(evm.interpreter.intPool.getZero())
   513  	}
   514  	evm.interpreter.intPool.put(num, n)
   515  	return nil, nil
   516  }
   517  
   518  func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   519  	stack.push(evm.Coinbase.Big())
   520  	return nil, nil
   521  }
   522  
   523  func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   524  	stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Time)))
   525  	return nil, nil
   526  }
   527  
   528  func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   529  	stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockNumber)))
   530  	return nil, nil
   531  }
   532  
   533  func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   534  	stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Difficulty)))
   535  	return nil, nil
   536  }
   537  
   538  func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   539  	stack.push(math.U256(evm.interpreter.intPool.get().SetUint64(evm.GasLimit)))
   540  	return nil, nil
   541  }
   542  
   543  func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   544  	evm.interpreter.intPool.put(stack.pop())
   545  	return nil, nil
   546  }
   547  
   548  func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   549  	offset := stack.pop()
   550  	val := evm.interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32))
   551  	stack.push(val)
   552  
   553  	evm.interpreter.intPool.put(offset)
   554  	return nil, nil
   555  }
   556  
   557  func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   558  	// pop value of the stack
   559  	mStart, val := stack.pop(), stack.pop()
   560  	memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
   561  
   562  	evm.interpreter.intPool.put(mStart, val)
   563  	return nil, nil
   564  }
   565  
   566  func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   567  	off, val := stack.pop().Int64(), stack.pop().Int64()
   568  	memory.store[off] = byte(val & 0xff)
   569  
   570  	return nil, nil
   571  }
   572  
   573  func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   574  	loc := common.BigToHash(stack.pop())
   575  	val := evm.StateDB.GetState(contract.Address(), loc).Big()
   576  	stack.push(val)
   577  	return nil, nil
   578  }
   579  
   580  func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   581  	loc := common.BigToHash(stack.pop())
   582  	val := stack.pop()
   583  	evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
   584  
   585  	evm.interpreter.intPool.put(val)
   586  	return nil, nil
   587  }
   588  
   589  func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   590  	pos := stack.pop()
   591  	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   592  		nop := contract.GetOp(pos.Uint64())
   593  		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   594  	}
   595  	*pc = pos.Uint64()
   596  
   597  	evm.interpreter.intPool.put(pos)
   598  	return nil, nil
   599  }
   600  
   601  func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   602  	pos, cond := stack.pop(), stack.pop()
   603  	if cond.Sign() != 0 {
   604  		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   605  			nop := contract.GetOp(pos.Uint64())
   606  			return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   607  		}
   608  		*pc = pos.Uint64()
   609  	} else {
   610  		*pc++
   611  	}
   612  
   613  	evm.interpreter.intPool.put(pos, cond)
   614  	return nil, nil
   615  }
   616  
   617  func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   618  	return nil, nil
   619  }
   620  
   621  func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   622  	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
   623  	return nil, nil
   624  }
   625  
   626  func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   627  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
   628  	return nil, nil
   629  }
   630  
   631  func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   632  	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
   633  	return nil, nil
   634  }
   635  
   636  func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   637  	var (
   638  		value        = stack.pop()
   639  		offset, size = stack.pop(), stack.pop()
   640  		input        = memory.Get(offset.Int64(), size.Int64())
   641  		gas          = contract.Gas
   642  	)
   643  	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
   644  		gas -= gas / 64
   645  	}
   646  
   647  	contract.UseGas(gas)
   648  	res, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
   649  	// Push item on the stack based on the returned error. If the ruleset is
   650  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   651  	// rule) and treat as an error, if the ruleset is frontier we must
   652  	// ignore this error and pretend the operation was successful.
   653  	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
   654  		stack.push(evm.interpreter.intPool.getZero())
   655  	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
   656  		stack.push(evm.interpreter.intPool.getZero())
   657  	} else {
   658  		stack.push(addr.Big())
   659  	}
   660  	contract.Gas += returnGas
   661  	evm.interpreter.intPool.put(value, offset, size)
   662  
   663  	if suberr == errExecutionReverted {
   664  		return res, nil
   665  	}
   666  	return nil, nil
   667  }
   668  
   669  func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   670  	// Pop gas. The actual gas in in evm.callGasTemp.
   671  	evm.interpreter.intPool.put(stack.pop())
   672  	gas := evm.callGasTemp
   673  	// Pop other call parameters.
   674  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   675  	toAddr := common.BigToAddress(addr)
   676  	value = math.U256(value)
   677  	// Get the arguments from the memory.
   678  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   679  
   680  	if value.Sign() != 0 {
   681  		gas += params.CallStipend
   682  	}
   683  	ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value)
   684  	if err != nil {
   685  		stack.push(evm.interpreter.intPool.getZero())
   686  	} else {
   687  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   688  	}
   689  	if err == nil || err == errExecutionReverted {
   690  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   691  	}
   692  	contract.Gas += returnGas
   693  
   694  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   695  	return ret, nil
   696  }
   697  
   698  func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   699  	// Pop gas. The actual gas is in evm.callGasTemp.
   700  	evm.interpreter.intPool.put(stack.pop())
   701  	gas := evm.callGasTemp
   702  	// Pop other call parameters.
   703  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   704  	toAddr := common.BigToAddress(addr)
   705  	value = math.U256(value)
   706  	// Get arguments from the memory.
   707  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   708  
   709  	if value.Sign() != 0 {
   710  		gas += params.CallStipend
   711  	}
   712  	ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value)
   713  	if err != nil {
   714  		stack.push(evm.interpreter.intPool.getZero())
   715  	} else {
   716  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   717  	}
   718  	if err == nil || err == errExecutionReverted {
   719  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   720  	}
   721  	contract.Gas += returnGas
   722  
   723  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   724  	return ret, nil
   725  }
   726  
   727  func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   728  	// Pop gas. The actual gas is in evm.callGasTemp.
   729  	evm.interpreter.intPool.put(stack.pop())
   730  	gas := evm.callGasTemp
   731  	// Pop other call parameters.
   732  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   733  	toAddr := common.BigToAddress(addr)
   734  	// Get arguments from the memory.
   735  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   736  
   737  	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
   738  	if err != nil {
   739  		stack.push(evm.interpreter.intPool.getZero())
   740  	} else {
   741  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   742  	}
   743  	if err == nil || err == errExecutionReverted {
   744  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   745  	}
   746  	contract.Gas += returnGas
   747  
   748  	evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
   749  	return ret, nil
   750  }
   751  
   752  func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   753  	// Pop gas. The actual gas is in evm.callGasTemp.
   754  	evm.interpreter.intPool.put(stack.pop())
   755  	gas := evm.callGasTemp
   756  	// Pop other call parameters.
   757  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   758  	toAddr := common.BigToAddress(addr)
   759  	// Get arguments from the memory.
   760  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   761  
   762  	ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas)
   763  	if err != nil {
   764  		stack.push(evm.interpreter.intPool.getZero())
   765  	} else {
   766  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   767  	}
   768  	if err == nil || err == errExecutionReverted {
   769  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   770  	}
   771  	contract.Gas += returnGas
   772  
   773  	evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
   774  	return ret, nil
   775  }
   776  
   777  func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   778  	offset, size := stack.pop(), stack.pop()
   779  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   780  
   781  	evm.interpreter.intPool.put(offset, size)
   782  	return ret, nil
   783  }
   784  
   785  func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   786  	offset, size := stack.pop(), stack.pop()
   787  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   788  
   789  	evm.interpreter.intPool.put(offset, size)
   790  	return ret, nil
   791  }
   792  
   793  func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   794  	return nil, nil
   795  }
   796  
   797  func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   798  	balance := evm.StateDB.GetBalance(contract.Address())
   799  	evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
   800  
   801  	evm.StateDB.Suicide(contract.Address())
   802  	return nil, nil
   803  }
   804  
   805  // following functions are used by the instruction jump  table
   806  
   807  // make log instruction function
   808  func makeLog(size int) executionFunc {
   809  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   810  		topics := make([]common.Hash, size)
   811  		mStart, mSize := stack.pop(), stack.pop()
   812  		for i := 0; i < size; i++ {
   813  			topics[i] = common.BigToHash(stack.pop())
   814  		}
   815  
   816  		d := memory.Get(mStart.Int64(), mSize.Int64())
   817  		evm.StateDB.AddLog(&types.Log{
   818  			Address: contract.Address(),
   819  			Topics:  topics,
   820  			Data:    d,
   821  			// This is a non-consensus field, but assigned here because
   822  			// core/state doesn't know the current block number.
   823  			BlockNumber: evm.BlockNumber.Uint64(),
   824  		})
   825  
   826  		evm.interpreter.intPool.put(mStart, mSize)
   827  		return nil, nil
   828  	}
   829  }
   830  
   831  // make push instruction function
   832  func makePush(size uint64, pushByteSize int) executionFunc {
   833  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   834  		codeLen := len(contract.Code)
   835  
   836  		startMin := codeLen
   837  		if int(*pc+1) < startMin {
   838  			startMin = int(*pc + 1)
   839  		}
   840  
   841  		endMin := codeLen
   842  		if startMin+pushByteSize < endMin {
   843  			endMin = startMin + pushByteSize
   844  		}
   845  
   846  		integer := evm.interpreter.intPool.get()
   847  		stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
   848  
   849  		*pc += size
   850  		return nil, nil
   851  	}
   852  }
   853  
   854  // make push instruction function
   855  func makeDup(size int64) executionFunc {
   856  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   857  		stack.dup(evm.interpreter.intPool, int(size))
   858  		return nil, nil
   859  	}
   860  }
   861  
   862  // make swap instruction function
   863  func makeSwap(size int64) executionFunc {
   864  	// switch n + 1 otherwise n would be swapped with n
   865  	size += 1
   866  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   867  		stack.swap(int(size))
   868  		return nil, nil
   869  	}
   870  }