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