github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/vm/instructions.go (about)

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