github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/vm/instructions.go (about)

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