gitlab.com/flarenetwork/coreth@v0.1.1/core/vm/instructions.go (about)

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