github.com/amazechain/amc@v0.1.3/internal/vm/instructions.go (about)

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