github.com/dominant-strategies/go-quai@v0.28.2/core/vm/instructions.go (about)

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