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