github.com/aaa256/atlantis@v0.0.0-20210707112435-42ee889287a2/core/vm/instructions.go (about)

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