github.com/MikyChow/arbitrum-go-ethereum@v0.0.0-20230306102812-078da49636de/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  	"math/big"
    21  	"sync/atomic"
    22  
    23  	"github.com/MikyChow/arbitrum-go-ethereum/common"
    24  	"github.com/MikyChow/arbitrum-go-ethereum/core/types"
    25  	"github.com/MikyChow/arbitrum-go-ethereum/params"
    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 opKeccak256(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 := common.Address(slot.Bytes20())
   265  	slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address))
   266  	return nil, nil
   267  }
   268  
   269  func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   270  	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
   271  	return nil, nil
   272  }
   273  func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   274  	scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes()))
   275  	return nil, nil
   276  }
   277  
   278  func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   279  	v, _ := uint256.FromBig(scope.Contract.value)
   280  	scope.Stack.push(v)
   281  	return nil, nil
   282  }
   283  
   284  func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   285  	x := scope.Stack.peek()
   286  	if offset, overflow := x.Uint64WithOverflow(); !overflow {
   287  		data := getData(scope.Contract.Input, offset, 32)
   288  		x.SetBytes(data)
   289  	} else {
   290  		x.Clear()
   291  	}
   292  	return nil, nil
   293  }
   294  
   295  func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   296  	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input))))
   297  	return nil, nil
   298  }
   299  
   300  func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   301  	var (
   302  		memOffset  = scope.Stack.pop()
   303  		dataOffset = scope.Stack.pop()
   304  		length     = scope.Stack.pop()
   305  	)
   306  	dataOffset64, overflow := dataOffset.Uint64WithOverflow()
   307  	if overflow {
   308  		dataOffset64 = 0xffffffffffffffff
   309  	}
   310  	// These values are checked for overflow during gas cost calculation
   311  	memOffset64 := memOffset.Uint64()
   312  	length64 := length.Uint64()
   313  	scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64))
   314  
   315  	return nil, nil
   316  }
   317  
   318  func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   319  	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
   320  	return nil, nil
   321  }
   322  
   323  func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   324  	var (
   325  		memOffset  = scope.Stack.pop()
   326  		dataOffset = scope.Stack.pop()
   327  		length     = scope.Stack.pop()
   328  	)
   329  
   330  	offset64, overflow := dataOffset.Uint64WithOverflow()
   331  	if overflow {
   332  		return nil, ErrReturnDataOutOfBounds
   333  	}
   334  	// we can reuse dataOffset now (aliasing it for clarity)
   335  	var end = dataOffset
   336  	end.Add(&dataOffset, &length)
   337  	end64, overflow := end.Uint64WithOverflow()
   338  	if overflow || uint64(len(interpreter.returnData)) < end64 {
   339  		return nil, ErrReturnDataOutOfBounds
   340  	}
   341  	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
   342  	return nil, nil
   343  }
   344  
   345  func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   346  	slot := scope.Stack.peek()
   347  	slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
   348  	return nil, nil
   349  }
   350  
   351  func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   352  	l := new(uint256.Int)
   353  	l.SetUint64(uint64(len(scope.Contract.Code)))
   354  	scope.Stack.push(l)
   355  	return nil, nil
   356  }
   357  
   358  func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   359  	var (
   360  		memOffset  = scope.Stack.pop()
   361  		codeOffset = scope.Stack.pop()
   362  		length     = scope.Stack.pop()
   363  	)
   364  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   365  	if overflow {
   366  		uint64CodeOffset = 0xffffffffffffffff
   367  	}
   368  	codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
   369  	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   370  
   371  	return nil, nil
   372  }
   373  
   374  func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   375  	var (
   376  		stack      = scope.Stack
   377  		a          = stack.pop()
   378  		memOffset  = stack.pop()
   379  		codeOffset = stack.pop()
   380  		length     = stack.pop()
   381  	)
   382  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   383  	if overflow {
   384  		uint64CodeOffset = 0xffffffffffffffff
   385  	}
   386  	addr := common.Address(a.Bytes20())
   387  	codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64())
   388  	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   389  
   390  	return nil, nil
   391  }
   392  
   393  // opExtCodeHash returns the code hash of a specified account.
   394  // There are several cases when the function is called, while we can relay everything
   395  // to `state.GetCodeHash` function to ensure the correctness.
   396  //
   397  //	(1) Caller tries to get the code hash of a normal contract account, state
   398  //
   399  // should return the relative code hash and set it as the result.
   400  //
   401  //	(2) Caller tries to get the code hash of a non-existent account, state should
   402  //
   403  // return common.Hash{} and zero will be set as the result.
   404  //
   405  //	(3) Caller tries to get the code hash for an account without contract code,
   406  //
   407  // state should return emptyCodeHash(0xc5d246...) as the result.
   408  //
   409  //	(4) Caller tries to get the code hash of a precompiled account, the result
   410  //
   411  // should be zero or emptyCodeHash.
   412  //
   413  // It is worth noting that in order to avoid unnecessary create and clean,
   414  // all precompile accounts on mainnet have been transferred 1 wei, so the return
   415  // here should be emptyCodeHash.
   416  // If the precompile account is not transferred any amount on a private or
   417  // customized chain, the return value will be zero.
   418  //
   419  //	(5) Caller tries to get the code hash for an account which is marked as suicided
   420  //
   421  // in the current transaction, the code hash of this account should be returned.
   422  //
   423  //	(6) Caller tries to get the code hash for an account which is marked as deleted,
   424  //
   425  // this account should be regarded as a non-existent account and zero should be returned.
   426  func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   427  	slot := scope.Stack.peek()
   428  	address := common.Address(slot.Bytes20())
   429  	if interpreter.evm.StateDB.Empty(address) {
   430  		slot.Clear()
   431  	} else {
   432  		slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
   433  	}
   434  	return nil, nil
   435  }
   436  
   437  func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   438  
   439  	// Arbitrum: provide an opportunity to remove the tip from the gas price
   440  	gasPrice := interpreter.evm.ProcessingHook.GasPriceOp(interpreter.evm)
   441  
   442  	v, _ := uint256.FromBig(gasPrice)
   443  	scope.Stack.push(v)
   444  	return nil, nil
   445  }
   446  
   447  func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   448  	num := scope.Stack.peek()
   449  	num64, overflow := num.Uint64WithOverflow()
   450  	if overflow {
   451  		num.Clear()
   452  		return nil, nil
   453  	}
   454  	upper, err := interpreter.evm.ProcessingHook.L1BlockNumber(interpreter.evm.Context)
   455  	if err != nil {
   456  		return nil, err
   457  	}
   458  	var lower uint64
   459  	if upper < 257 {
   460  		lower = 0
   461  	} else {
   462  		lower = upper - 256
   463  	}
   464  	if num64 >= lower && num64 < upper {
   465  		h, err := interpreter.evm.ProcessingHook.L1BlockHash(interpreter.evm.Context, num64)
   466  		if err != nil {
   467  			return nil, err
   468  		}
   469  		num.SetBytes(h.Bytes())
   470  	} else {
   471  		num.Clear()
   472  	}
   473  	return nil, nil
   474  }
   475  
   476  func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   477  	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
   478  	return nil, nil
   479  }
   480  
   481  func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   482  	v, _ := uint256.FromBig(interpreter.evm.Context.Time)
   483  	scope.Stack.push(v)
   484  	return nil, nil
   485  }
   486  
   487  func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   488  	bnum, err := interpreter.evm.ProcessingHook.L1BlockNumber(interpreter.evm.Context)
   489  	if err != nil {
   490  		return nil, err
   491  	}
   492  	v, _ := uint256.FromBig(new(big.Int).SetUint64(bnum))
   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 opRandom(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   504  	v := new(uint256.Int).SetBytes(interpreter.evm.Context.Random.Bytes())
   505  	scope.Stack.push(v)
   506  	return nil, nil
   507  }
   508  
   509  func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   510  	scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
   511  	return nil, nil
   512  }
   513  
   514  func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   515  	scope.Stack.pop()
   516  	return nil, nil
   517  }
   518  
   519  func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   520  	v := scope.Stack.peek()
   521  	offset := int64(v.Uint64())
   522  	v.SetBytes(scope.Memory.GetPtr(offset, 32))
   523  	return nil, nil
   524  }
   525  
   526  func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   527  	// pop value of the stack
   528  	mStart, val := scope.Stack.pop(), scope.Stack.pop()
   529  	scope.Memory.Set32(mStart.Uint64(), &val)
   530  	return nil, nil
   531  }
   532  
   533  func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   534  	off, val := scope.Stack.pop(), scope.Stack.pop()
   535  	scope.Memory.store[off.Uint64()] = byte(val.Uint64())
   536  	return nil, nil
   537  }
   538  
   539  func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   540  	loc := scope.Stack.peek()
   541  	hash := common.Hash(loc.Bytes32())
   542  	val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash)
   543  	loc.SetBytes(val.Bytes())
   544  	return nil, nil
   545  }
   546  
   547  func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   548  	if interpreter.readOnly {
   549  		return nil, ErrWriteProtection
   550  	}
   551  	loc := scope.Stack.pop()
   552  	val := scope.Stack.pop()
   553  	interpreter.evm.StateDB.SetState(scope.Contract.Address(),
   554  		loc.Bytes32(), val.Bytes32())
   555  	return nil, nil
   556  }
   557  
   558  func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   559  	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
   560  		return nil, errStopToken
   561  	}
   562  	pos := scope.Stack.pop()
   563  	if !scope.Contract.validJumpdest(&pos) {
   564  		return nil, ErrInvalidJump
   565  	}
   566  	*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
   567  	return nil, nil
   568  }
   569  
   570  func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   571  	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
   572  		return nil, errStopToken
   573  	}
   574  	pos, cond := scope.Stack.pop(), scope.Stack.pop()
   575  	if !cond.IsZero() {
   576  		if !scope.Contract.validJumpdest(&pos) {
   577  			return nil, ErrInvalidJump
   578  		}
   579  		*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
   580  	}
   581  	return nil, nil
   582  }
   583  
   584  func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   585  	return nil, nil
   586  }
   587  
   588  func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   589  	scope.Stack.push(new(uint256.Int).SetUint64(*pc))
   590  	return nil, nil
   591  }
   592  
   593  func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   594  	scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len())))
   595  	return nil, nil
   596  }
   597  
   598  func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   599  	scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas))
   600  	return nil, nil
   601  }
   602  
   603  func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   604  	if interpreter.readOnly {
   605  		return nil, ErrWriteProtection
   606  	}
   607  	var (
   608  		value        = scope.Stack.pop()
   609  		offset, size = scope.Stack.pop(), scope.Stack.pop()
   610  		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
   611  		gas          = scope.Contract.Gas
   612  	)
   613  	if interpreter.evm.chainRules.IsEIP150 {
   614  		gas -= gas / 64
   615  	}
   616  	// reuse size int for stackvalue
   617  	stackvalue := size
   618  
   619  	scope.Contract.UseGas(gas)
   620  	//TODO: use uint256.Int instead of converting with toBig()
   621  	var bigVal = big0
   622  	if !value.IsZero() {
   623  		bigVal = value.ToBig()
   624  	}
   625  
   626  	res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal)
   627  	// Push item on the stack based on the returned error. If the ruleset is
   628  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   629  	// rule) and treat as an error, if the ruleset is frontier we must
   630  	// ignore this error and pretend the operation was successful.
   631  	if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
   632  		stackvalue.Clear()
   633  	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
   634  		stackvalue.Clear()
   635  	} else {
   636  		stackvalue.SetBytes(addr.Bytes())
   637  	}
   638  	scope.Stack.push(&stackvalue)
   639  	scope.Contract.Gas += returnGas
   640  
   641  	if suberr == ErrExecutionReverted {
   642  		interpreter.returnData = res // set REVERT data to return data buffer
   643  		return res, nil
   644  	}
   645  	interpreter.returnData = nil // clear dirty return data buffer
   646  	return nil, nil
   647  }
   648  
   649  func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   650  	if interpreter.readOnly {
   651  		return nil, ErrWriteProtection
   652  	}
   653  	var (
   654  		endowment    = scope.Stack.pop()
   655  		offset, size = scope.Stack.pop(), scope.Stack.pop()
   656  		salt         = scope.Stack.pop()
   657  		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
   658  		gas          = scope.Contract.Gas
   659  	)
   660  
   661  	// Apply EIP150
   662  	gas -= gas / 64
   663  	scope.Contract.UseGas(gas)
   664  	// reuse size int for stackvalue
   665  	stackvalue := size
   666  	//TODO: use uint256.Int instead of converting with toBig()
   667  	bigEndowment := big0
   668  	if !endowment.IsZero() {
   669  		bigEndowment = endowment.ToBig()
   670  	}
   671  	res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas,
   672  		bigEndowment, &salt)
   673  	// Push item on the stack based on the returned error.
   674  	if suberr != nil {
   675  		stackvalue.Clear()
   676  	} else {
   677  		stackvalue.SetBytes(addr.Bytes())
   678  	}
   679  	scope.Stack.push(&stackvalue)
   680  	scope.Contract.Gas += returnGas
   681  
   682  	if suberr == ErrExecutionReverted {
   683  		interpreter.returnData = res // set REVERT data to return data buffer
   684  		return res, nil
   685  	}
   686  	interpreter.returnData = nil // clear dirty return data buffer
   687  	return nil, nil
   688  }
   689  
   690  func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   691  	stack := scope.Stack
   692  	// Pop gas. The actual gas in interpreter.evm.callGasTemp.
   693  	// We can use this as a temporary value
   694  	temp := stack.pop()
   695  	gas := interpreter.evm.callGasTemp
   696  	// Pop other call parameters.
   697  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   698  	toAddr := common.Address(addr.Bytes20())
   699  	// Get the arguments from the memory.
   700  	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   701  
   702  	if interpreter.readOnly && !value.IsZero() {
   703  		return nil, ErrWriteProtection
   704  	}
   705  	var bigVal = big0
   706  	//TODO: use uint256.Int instead of converting with toBig()
   707  	// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
   708  	// but it would make more sense to extend the usage of uint256.Int
   709  	if !value.IsZero() {
   710  		gas += params.CallStipend
   711  		bigVal = value.ToBig()
   712  	}
   713  
   714  	ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal)
   715  
   716  	if err != nil {
   717  		temp.Clear()
   718  	} else {
   719  		temp.SetOne()
   720  	}
   721  	stack.push(&temp)
   722  	if err == nil || err == ErrExecutionReverted {
   723  		ret = common.CopyBytes(ret)
   724  		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   725  	}
   726  	scope.Contract.Gas += returnGas
   727  
   728  	interpreter.returnData = ret
   729  	return ret, nil
   730  }
   731  
   732  func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   733  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   734  	stack := scope.Stack
   735  	// We use it as a temporary value
   736  	temp := stack.pop()
   737  	gas := interpreter.evm.callGasTemp
   738  	// Pop other call parameters.
   739  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   740  	toAddr := common.Address(addr.Bytes20())
   741  	// Get arguments from the memory.
   742  	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   743  
   744  	//TODO: use uint256.Int instead of converting with toBig()
   745  	var bigVal = big0
   746  	if !value.IsZero() {
   747  		gas += params.CallStipend
   748  		bigVal = value.ToBig()
   749  	}
   750  
   751  	ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal)
   752  	if err != nil {
   753  		temp.Clear()
   754  	} else {
   755  		temp.SetOne()
   756  	}
   757  	stack.push(&temp)
   758  	if err == nil || err == ErrExecutionReverted {
   759  		ret = common.CopyBytes(ret)
   760  		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   761  	}
   762  	scope.Contract.Gas += returnGas
   763  
   764  	interpreter.returnData = ret
   765  	return ret, nil
   766  }
   767  
   768  func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   769  	stack := scope.Stack
   770  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   771  	// We use it as a temporary value
   772  	temp := stack.pop()
   773  	gas := interpreter.evm.callGasTemp
   774  	// Pop other call parameters.
   775  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   776  	toAddr := common.Address(addr.Bytes20())
   777  	// Get arguments from the memory.
   778  	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   779  
   780  	ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
   781  	if err != nil {
   782  		temp.Clear()
   783  	} else {
   784  		temp.SetOne()
   785  	}
   786  	stack.push(&temp)
   787  	if err == nil || err == ErrExecutionReverted {
   788  		ret = common.CopyBytes(ret)
   789  		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   790  	}
   791  	scope.Contract.Gas += returnGas
   792  
   793  	interpreter.returnData = ret
   794  	return ret, nil
   795  }
   796  
   797  func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   798  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   799  	stack := scope.Stack
   800  	// We use it as a temporary value
   801  	temp := stack.pop()
   802  	gas := interpreter.evm.callGasTemp
   803  	// Pop other call parameters.
   804  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   805  	toAddr := common.Address(addr.Bytes20())
   806  	// Get arguments from the memory.
   807  	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   808  
   809  	ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
   810  	if err != nil {
   811  		temp.Clear()
   812  	} else {
   813  		temp.SetOne()
   814  	}
   815  	stack.push(&temp)
   816  	if err == nil || err == ErrExecutionReverted {
   817  		ret = common.CopyBytes(ret)
   818  		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   819  	}
   820  	scope.Contract.Gas += returnGas
   821  
   822  	interpreter.returnData = ret
   823  	return ret, nil
   824  }
   825  
   826  func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   827  	offset, size := scope.Stack.pop(), scope.Stack.pop()
   828  	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
   829  
   830  	return ret, errStopToken
   831  }
   832  
   833  func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   834  	offset, size := scope.Stack.pop(), scope.Stack.pop()
   835  	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
   836  
   837  	interpreter.returnData = ret
   838  	return ret, ErrExecutionReverted
   839  }
   840  
   841  func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   842  	return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])}
   843  }
   844  
   845  func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   846  	return nil, errStopToken
   847  }
   848  
   849  func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   850  	if interpreter.readOnly {
   851  		return nil, ErrWriteProtection
   852  	}
   853  	beneficiary := scope.Stack.pop()
   854  	balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
   855  	interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance)
   856  	interpreter.evm.StateDB.Suicide(scope.Contract.Address())
   857  	if beneficiary.Bytes20() == scope.Contract.Address() {
   858  		// Arbitrum: calling selfdestruct(this) burns the balance
   859  		interpreter.evm.StateDB.ExpectBalanceBurn(balance)
   860  	}
   861  	if interpreter.cfg.Debug {
   862  		interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance)
   863  		interpreter.cfg.Tracer.CaptureExit([]byte{}, 0, nil)
   864  	}
   865  	return nil, errStopToken
   866  }
   867  
   868  // following functions are used by the instruction jump  table
   869  
   870  // make log instruction function
   871  func makeLog(size int) executionFunc {
   872  	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   873  		if interpreter.readOnly {
   874  			return nil, ErrWriteProtection
   875  		}
   876  		topics := make([]common.Hash, size)
   877  		stack := scope.Stack
   878  		mStart, mSize := stack.pop(), stack.pop()
   879  		for i := 0; i < size; i++ {
   880  			addr := stack.pop()
   881  			topics[i] = addr.Bytes32()
   882  		}
   883  
   884  		d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
   885  		interpreter.evm.StateDB.AddLog(&types.Log{
   886  			Address: scope.Contract.Address(),
   887  			Topics:  topics,
   888  			Data:    d,
   889  			// This is a non-consensus field, but assigned here because
   890  			// core/state doesn't know the current block number.
   891  			BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
   892  		})
   893  
   894  		return nil, nil
   895  	}
   896  }
   897  
   898  // opPush1 is a specialized version of pushN
   899  func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   900  	var (
   901  		codeLen = uint64(len(scope.Contract.Code))
   902  		integer = new(uint256.Int)
   903  	)
   904  	*pc += 1
   905  	if *pc < codeLen {
   906  		scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc])))
   907  	} else {
   908  		scope.Stack.push(integer.Clear())
   909  	}
   910  	return nil, nil
   911  }
   912  
   913  // make push instruction function
   914  func makePush(size uint64, pushByteSize int) executionFunc {
   915  	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   916  		codeLen := len(scope.Contract.Code)
   917  
   918  		startMin := codeLen
   919  		if int(*pc+1) < startMin {
   920  			startMin = int(*pc + 1)
   921  		}
   922  
   923  		endMin := codeLen
   924  		if startMin+pushByteSize < endMin {
   925  			endMin = startMin + pushByteSize
   926  		}
   927  
   928  		integer := new(uint256.Int)
   929  		scope.Stack.push(integer.SetBytes(common.RightPadBytes(
   930  			scope.Contract.Code[startMin:endMin], pushByteSize)))
   931  
   932  		*pc += size
   933  		return nil, nil
   934  	}
   935  }
   936  
   937  // make dup instruction function
   938  func makeDup(size int64) executionFunc {
   939  	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   940  		scope.Stack.dup(int(size))
   941  		return nil, nil
   942  	}
   943  }
   944  
   945  // make swap instruction function
   946  func makeSwap(size int64) executionFunc {
   947  	// switch n + 1 otherwise n would be swapped with n
   948  	size++
   949  	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
   950  		scope.Stack.swap(int(size))
   951  		return nil, nil
   952  	}
   953  }