github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/core/vm/instructions.go (about)

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