github.com/klaytn/klaytn@v1.10.2/blockchain/vm/instructions.go (about)

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