github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/core/vm/instructions.go (about)

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