github.com/ontio/ontology@v1.14.4/vm/evm/instructions.go (about)

     1  // Copyright (C) 2021 The Ontology Authors
     2  // Copyright 2015 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package evm
    19  
    20  import (
    21  	"github.com/ethereum/go-ethereum/common"
    22  	"github.com/holiman/uint256"
    23  	"github.com/ontio/ontology/core/types"
    24  	"github.com/ontio/ontology/vm/evm/errors"
    25  	"github.com/ontio/ontology/vm/evm/params"
    26  	"golang.org/x/crypto/sha3"
    27  )
    28  
    29  func opAdd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    30  	x, y := callContext.stack.pop(), callContext.stack.peek()
    31  	y.Add(&x, y)
    32  	return nil, nil
    33  }
    34  
    35  func opSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    36  	x, y := callContext.stack.pop(), callContext.stack.peek()
    37  	y.Sub(&x, y)
    38  	return nil, nil
    39  }
    40  
    41  func opMul(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    42  	x, y := callContext.stack.pop(), callContext.stack.peek()
    43  	y.Mul(&x, y)
    44  	return nil, nil
    45  }
    46  
    47  func opDiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    48  	x, y := callContext.stack.pop(), callContext.stack.peek()
    49  	y.Div(&x, y)
    50  	return nil, nil
    51  }
    52  
    53  func opSdiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    54  	x, y := callContext.stack.pop(), callContext.stack.peek()
    55  	y.SDiv(&x, y)
    56  	return nil, nil
    57  }
    58  
    59  func opMod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    60  	x, y := callContext.stack.pop(), callContext.stack.peek()
    61  	y.Mod(&x, y)
    62  	return nil, nil
    63  }
    64  
    65  func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    66  	x, y := callContext.stack.pop(), callContext.stack.peek()
    67  	y.SMod(&x, y)
    68  	return nil, nil
    69  }
    70  
    71  func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    72  	base, exponent := callContext.stack.pop(), callContext.stack.peek()
    73  	exponent.Exp(&base, exponent)
    74  	return nil, nil
    75  }
    76  
    77  func opSignExtend(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    78  	back, num := callContext.stack.pop(), callContext.stack.peek()
    79  	num.ExtendSign(num, &back)
    80  	return nil, nil
    81  }
    82  
    83  func opNot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    84  	x := callContext.stack.peek()
    85  	x.Not(x)
    86  	return nil, nil
    87  }
    88  
    89  func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
    90  	x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   100  	x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   110  	x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   120  	x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   130  	x, y := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   140  	x := callContext.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, callContext *callCtx) ([]byte, error) {
   150  	x, y := callContext.stack.pop(), callContext.stack.peek()
   151  	y.And(&x, y)
   152  	return nil, nil
   153  }
   154  
   155  func opOr(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   156  	x, y := callContext.stack.pop(), callContext.stack.peek()
   157  	y.Or(&x, y)
   158  	return nil, nil
   159  }
   160  
   161  func opXor(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   162  	x, y := callContext.stack.pop(), callContext.stack.peek()
   163  	y.Xor(&x, y)
   164  	return nil, nil
   165  }
   166  
   167  func opByte(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   168  	th, val := callContext.stack.pop(), callContext.stack.peek()
   169  	val.Byte(&th)
   170  	return nil, nil
   171  }
   172  
   173  func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   174  	x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   184  	x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.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, callContext *callCtx) ([]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 := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]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 := callContext.stack.pop(), callContext.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, callContext *callCtx) ([]byte, error) {
   221  	shift, value := callContext.stack.pop(), callContext.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 opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   237  	offset, size := callContext.stack.pop(), callContext.stack.peek()
   238  	data := callContext.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.vmConfig.EnablePreimageRecording {
   250  		evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
   251  	}
   252  
   253  	size.SetBytes(interpreter.hasherBuf[:])
   254  	return nil, nil
   255  }
   256  func opAddress(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   257  	callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Address().Bytes()))
   258  	return nil, nil
   259  }
   260  
   261  func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   262  	slot := callContext.stack.peek()
   263  	address := common.Address(slot.Bytes20())
   264  	slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address))
   265  	return nil, nil
   266  }
   267  
   268  func opOrigin(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   269  	callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
   270  	return nil, nil
   271  }
   272  func opCaller(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   273  	callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Caller().Bytes()))
   274  	return nil, nil
   275  }
   276  
   277  func opCallValue(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   278  	v, _ := uint256.FromBig(callContext.contract.value)
   279  	callContext.stack.push(v)
   280  	return nil, nil
   281  }
   282  
   283  func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   284  	x := callContext.stack.peek()
   285  	if offset, overflow := x.Uint64WithOverflow(); !overflow {
   286  		data := getData(callContext.contract.Input, offset, 32)
   287  		x.SetBytes(data)
   288  	} else {
   289  		x.Clear()
   290  	}
   291  	return nil, nil
   292  }
   293  
   294  func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   295  	callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(callContext.contract.Input))))
   296  	return nil, nil
   297  }
   298  
   299  func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   300  	var (
   301  		memOffset  = callContext.stack.pop()
   302  		dataOffset = callContext.stack.pop()
   303  		length     = callContext.stack.pop()
   304  	)
   305  	dataOffset64, overflow := dataOffset.Uint64WithOverflow()
   306  	if overflow {
   307  		dataOffset64 = 0xffffffffffffffff
   308  	}
   309  	// These values are checked for overflow during gas cost calculation
   310  	memOffset64 := memOffset.Uint64()
   311  	length64 := length.Uint64()
   312  	callContext.memory.Set(memOffset64, length64, getData(callContext.contract.Input, dataOffset64, length64))
   313  
   314  	return nil, nil
   315  }
   316  
   317  func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   318  	callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
   319  	return nil, nil
   320  }
   321  
   322  func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   323  	var (
   324  		memOffset  = callContext.stack.pop()
   325  		dataOffset = callContext.stack.pop()
   326  		length     = callContext.stack.pop()
   327  	)
   328  
   329  	offset64, overflow := dataOffset.Uint64WithOverflow()
   330  	if overflow {
   331  		return nil, errors.ErrReturnDataOutOfBounds
   332  	}
   333  	// we can reuse dataOffset now (aliasing it for clarity)
   334  	var end = dataOffset
   335  	end.Add(&dataOffset, &length)
   336  	end64, overflow := end.Uint64WithOverflow()
   337  	if overflow || uint64(len(interpreter.returnData)) < end64 {
   338  		return nil, errors.ErrReturnDataOutOfBounds
   339  	}
   340  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
   341  	return nil, nil
   342  }
   343  
   344  func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   345  	slot := callContext.stack.peek()
   346  	slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
   347  	return nil, nil
   348  }
   349  
   350  func opCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   351  	l := new(uint256.Int)
   352  	l.SetUint64(uint64(len(callContext.contract.Code)))
   353  	callContext.stack.push(l)
   354  	return nil, nil
   355  }
   356  
   357  func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   358  	var (
   359  		memOffset  = callContext.stack.pop()
   360  		codeOffset = callContext.stack.pop()
   361  		length     = callContext.stack.pop()
   362  	)
   363  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   364  	if overflow {
   365  		uint64CodeOffset = 0xffffffffffffffff
   366  	}
   367  	codeCopy := getData(callContext.contract.Code, uint64CodeOffset, length.Uint64())
   368  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   369  
   370  	return nil, nil
   371  }
   372  
   373  func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   374  	var (
   375  		stack      = callContext.stack
   376  		a          = stack.pop()
   377  		memOffset  = stack.pop()
   378  		codeOffset = stack.pop()
   379  		length     = stack.pop()
   380  	)
   381  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   382  	if overflow {
   383  		uint64CodeOffset = 0xffffffffffffffff
   384  	}
   385  	addr := common.Address(a.Bytes20())
   386  	codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64())
   387  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   388  
   389  	return nil, nil
   390  }
   391  
   392  // opExtCodeHash returns the code hash of a specified account.
   393  // There are several cases when the function is called, while we can relay everything
   394  // to `state.GetCodeHash` function to ensure the correctness.
   395  //   (1) Caller tries to get the code hash of a normal contract account, state
   396  // should return the relative code hash and set it as the result.
   397  //
   398  //   (2) Caller tries to get the code hash of a non-existent account, state should
   399  // return common.Hash{} and zero will be set as the result.
   400  //
   401  //   (3) Caller tries to get the code hash for an account without contract code,
   402  // state should return emptyCodeHash(0xc5d246...) as the result.
   403  //
   404  //   (4) Caller tries to get the code hash of a precompiled account, the result
   405  // should be zero or emptyCodeHash.
   406  //
   407  // It is worth noting that in order to avoid unnecessary create and clean,
   408  // all precompile accounts on mainnet have been transferred 1 wei, so the return
   409  // here should be emptyCodeHash.
   410  // If the precompile account is not transferred any amount on a private or
   411  // customized chain, the return value will be zero.
   412  //
   413  //   (5) Caller tries to get the code hash for an account which is marked as suicided
   414  // in the current transaction, the code hash of this account should be returned.
   415  //
   416  //   (6) Caller tries to get the code hash for an account which is marked as deleted,
   417  // this account should be regarded as a non-existent account and zero should be returned.
   418  func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   419  	slot := callContext.stack.peek()
   420  	address := common.Address(slot.Bytes20())
   421  	if interpreter.evm.StateDB.Empty(address) {
   422  		slot.Clear()
   423  	} else {
   424  		slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
   425  	}
   426  	return nil, nil
   427  }
   428  
   429  func opGasprice(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   430  	v, _ := uint256.FromBig(interpreter.evm.GasPrice)
   431  	callContext.stack.push(v)
   432  	return nil, nil
   433  }
   434  
   435  func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   436  	num := callContext.stack.peek()
   437  	num64, overflow := num.Uint64WithOverflow()
   438  	if overflow {
   439  		num.Clear()
   440  		return nil, nil
   441  	}
   442  	var upper, lower uint64
   443  	upper = interpreter.evm.Context.BlockNumber.Uint64()
   444  	if upper < 257 {
   445  		lower = 0
   446  	} else {
   447  		lower = upper - 256
   448  	}
   449  	if num64 >= lower && num64 < upper {
   450  		num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
   451  	} else {
   452  		num.Clear()
   453  	}
   454  	return nil, nil
   455  }
   456  
   457  func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   458  	callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
   459  	return nil, nil
   460  }
   461  
   462  func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   463  	v, _ := uint256.FromBig(interpreter.evm.Context.Time)
   464  	callContext.stack.push(v)
   465  	return nil, nil
   466  }
   467  
   468  func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   469  	v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber)
   470  	callContext.stack.push(v)
   471  	return nil, nil
   472  }
   473  
   474  func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   475  	v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty)
   476  	callContext.stack.push(v)
   477  	return nil, nil
   478  }
   479  
   480  func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   481  	callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
   482  	return nil, nil
   483  }
   484  
   485  func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   486  	callContext.stack.pop()
   487  	return nil, nil
   488  }
   489  
   490  func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   491  	v := callContext.stack.peek()
   492  	offset := int64(v.Uint64())
   493  	v.SetBytes(callContext.memory.GetPtr(offset, 32))
   494  	return nil, nil
   495  }
   496  
   497  func opMstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   498  	// pop value of the stack
   499  	mStart, val := callContext.stack.pop(), callContext.stack.pop()
   500  	callContext.memory.Set32(mStart.Uint64(), &val)
   501  	return nil, nil
   502  }
   503  
   504  func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   505  	off, val := callContext.stack.pop(), callContext.stack.pop()
   506  	callContext.memory.store[off.Uint64()] = byte(val.Uint64())
   507  	return nil, nil
   508  }
   509  
   510  func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   511  	loc := callContext.stack.peek()
   512  	hash := common.Hash(loc.Bytes32())
   513  	val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), hash)
   514  	loc.SetBytes(val.Bytes())
   515  	return nil, nil
   516  }
   517  
   518  func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   519  	loc := callContext.stack.pop()
   520  	val := callContext.stack.pop()
   521  	interpreter.evm.StateDB.SetState(callContext.contract.Address(),
   522  		loc.Bytes32(), val.Bytes32())
   523  	return nil, nil
   524  }
   525  
   526  func opJump(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   527  	pos := callContext.stack.pop()
   528  	if !callContext.contract.validJumpdest(&pos) {
   529  		return nil, errors.ErrInvalidJump
   530  	}
   531  	*pc = pos.Uint64()
   532  	return nil, nil
   533  }
   534  
   535  func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   536  	pos, cond := callContext.stack.pop(), callContext.stack.pop()
   537  	if !cond.IsZero() {
   538  		if !callContext.contract.validJumpdest(&pos) {
   539  			return nil, errors.ErrInvalidJump
   540  		}
   541  		*pc = pos.Uint64()
   542  	} else {
   543  		*pc++
   544  	}
   545  	return nil, nil
   546  }
   547  
   548  func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   549  	return nil, nil
   550  }
   551  
   552  func opBeginSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   553  	return nil, errors.ErrInvalidSubroutineEntry
   554  }
   555  
   556  func opJumpSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   557  	if len(callContext.rstack.data) >= 1023 {
   558  		return nil, errors.ErrReturnStackExceeded
   559  	}
   560  	pos := callContext.stack.pop()
   561  	if !pos.IsUint64() {
   562  		return nil, errors.ErrInvalidJump
   563  	}
   564  	posU64 := pos.Uint64()
   565  	if !callContext.contract.validJumpSubdest(posU64) {
   566  		return nil, errors.ErrInvalidJump
   567  	}
   568  	callContext.rstack.push(uint32(*pc))
   569  	*pc = posU64 + 1
   570  	return nil, nil
   571  }
   572  
   573  func opReturnSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   574  	if len(callContext.rstack.data) == 0 {
   575  		return nil, errors.ErrInvalidRetsub
   576  	}
   577  	// Other than the check that the return stack is not empty, there is no
   578  	// need to validate the pc from 'returns', since we only ever push valid
   579  	//values onto it via jumpsub.
   580  	*pc = uint64(callContext.rstack.pop()) + 1
   581  	return nil, nil
   582  }
   583  
   584  func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   585  	callContext.stack.push(new(uint256.Int).SetUint64(*pc))
   586  	return nil, nil
   587  }
   588  
   589  func opMsize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   590  	callContext.stack.push(new(uint256.Int).SetUint64(uint64(callContext.memory.Len())))
   591  	return nil, nil
   592  }
   593  
   594  func opGas(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   595  	callContext.stack.push(new(uint256.Int).SetUint64(callContext.contract.Gas))
   596  	return nil, nil
   597  }
   598  
   599  func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   600  	var (
   601  		value        = callContext.stack.pop()
   602  		offset, size = callContext.stack.pop(), callContext.stack.pop()
   603  		input        = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
   604  		gas          = callContext.contract.Gas
   605  	)
   606  	if interpreter.evm.chainRules.IsEIP150 {
   607  		gas -= gas / 64
   608  	}
   609  	// reuse size int for stackvalue
   610  	stackvalue := size
   611  
   612  	callContext.contract.UseGas(gas)
   613  	//TODO: use uint256.Int instead of converting with toBig()
   614  	var bigVal = big0
   615  	if !value.IsZero() {
   616  		bigVal = value.ToBig()
   617  	}
   618  
   619  	res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, bigVal)
   620  	// Push item on the stack based on the returned error. If the ruleset is
   621  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   622  	// rule) and treat as an error, if the ruleset is frontier we must
   623  	// ignore this error and pretend the operation was successful.
   624  	if interpreter.evm.chainRules.IsHomestead && suberr == errors.ErrCodeStoreOutOfGas {
   625  		stackvalue.Clear()
   626  	} else if suberr != nil && suberr != errors.ErrCodeStoreOutOfGas {
   627  		stackvalue.Clear()
   628  	} else {
   629  		stackvalue.SetBytes(addr.Bytes())
   630  	}
   631  	callContext.stack.push(&stackvalue)
   632  	callContext.contract.Gas += returnGas
   633  
   634  	if suberr == errors.ErrExecutionReverted {
   635  		return res, nil
   636  	}
   637  	return nil, nil
   638  }
   639  
   640  func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   641  	var (
   642  		endowment    = callContext.stack.pop()
   643  		offset, size = callContext.stack.pop(), callContext.stack.pop()
   644  		salt         = callContext.stack.pop()
   645  		input        = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
   646  		gas          = callContext.contract.Gas
   647  	)
   648  
   649  	// Apply EIP150
   650  	gas -= gas / 64
   651  	callContext.contract.UseGas(gas)
   652  	// reuse size int for stackvalue
   653  	stackvalue := size
   654  	//TODO: use uint256.Int instead of converting with toBig()
   655  	bigEndowment := big0
   656  	if !endowment.IsZero() {
   657  		bigEndowment = endowment.ToBig()
   658  	}
   659  	res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas,
   660  		bigEndowment, &salt)
   661  	// Push item on the stack based on the returned error.
   662  	if suberr != nil {
   663  		stackvalue.Clear()
   664  	} else {
   665  		stackvalue.SetBytes(addr.Bytes())
   666  	}
   667  	callContext.stack.push(&stackvalue)
   668  	callContext.contract.Gas += returnGas
   669  
   670  	if suberr == errors.ErrExecutionReverted {
   671  		return res, nil
   672  	}
   673  	return nil, nil
   674  }
   675  
   676  func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   677  	stack := callContext.stack
   678  	// Pop gas. The actual gas in interpreter.evm.callGasTemp.
   679  	// We can use this as a temporary value
   680  	temp := stack.pop()
   681  	gas := interpreter.evm.callGasTemp
   682  	// Pop other call parameters.
   683  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   684  	toAddr := common.Address(addr.Bytes20())
   685  	// Get the arguments from the memory.
   686  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   687  
   688  	var bigVal = big0
   689  	//TODO: use uint256.Int instead of converting with toBig()
   690  	// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
   691  	// but it would make more sense to extend the usage of uint256.Int
   692  	if !value.IsZero() {
   693  		gas += params.CallStipend
   694  		bigVal = value.ToBig()
   695  	}
   696  
   697  	ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, bigVal)
   698  
   699  	if err != nil {
   700  		temp.Clear()
   701  	} else {
   702  		temp.SetOne()
   703  	}
   704  	stack.push(&temp)
   705  	if err == nil || err == errors.ErrExecutionReverted {
   706  		ret = common.CopyBytes(ret)
   707  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   708  	}
   709  	callContext.contract.Gas += returnGas
   710  
   711  	return ret, nil
   712  }
   713  
   714  func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   715  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   716  	stack := callContext.stack
   717  	// We use it as a temporary value
   718  	temp := stack.pop()
   719  	gas := interpreter.evm.callGasTemp
   720  	// Pop other call parameters.
   721  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   722  	toAddr := common.Address(addr.Bytes20())
   723  	// Get arguments from the memory.
   724  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   725  
   726  	//TODO: use uint256.Int instead of converting with toBig()
   727  	var bigVal = big0
   728  	if !value.IsZero() {
   729  		gas += params.CallStipend
   730  		bigVal = value.ToBig()
   731  	}
   732  
   733  	ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, bigVal)
   734  	if err != nil {
   735  		temp.Clear()
   736  	} else {
   737  		temp.SetOne()
   738  	}
   739  	stack.push(&temp)
   740  	if err == nil || err == errors.ErrExecutionReverted {
   741  		ret = common.CopyBytes(ret)
   742  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   743  	}
   744  	callContext.contract.Gas += returnGas
   745  
   746  	return ret, nil
   747  }
   748  
   749  func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   750  	stack := callContext.stack
   751  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   752  	// We use it as a temporary value
   753  	temp := stack.pop()
   754  	gas := interpreter.evm.callGasTemp
   755  	// Pop other call parameters.
   756  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   757  	toAddr := common.Address(addr.Bytes20())
   758  	// Get arguments from the memory.
   759  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   760  
   761  	ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas)
   762  	if err != nil {
   763  		temp.Clear()
   764  	} else {
   765  		temp.SetOne()
   766  	}
   767  	stack.push(&temp)
   768  	if err == nil || err == errors.ErrExecutionReverted {
   769  		ret = common.CopyBytes(ret)
   770  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   771  	}
   772  	callContext.contract.Gas += returnGas
   773  
   774  	return ret, nil
   775  }
   776  
   777  func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   778  	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
   779  	stack := callContext.stack
   780  	// We use it as a temporary value
   781  	temp := stack.pop()
   782  	gas := interpreter.evm.callGasTemp
   783  	// Pop other call parameters.
   784  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   785  	toAddr := common.Address(addr.Bytes20())
   786  	// Get arguments from the memory.
   787  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   788  
   789  	ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas)
   790  	if err != nil {
   791  		temp.Clear()
   792  	} else {
   793  		temp.SetOne()
   794  	}
   795  	stack.push(&temp)
   796  	if err == nil || err == errors.ErrExecutionReverted {
   797  		ret = common.CopyBytes(ret)
   798  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   799  	}
   800  	callContext.contract.Gas += returnGas
   801  
   802  	return ret, nil
   803  }
   804  
   805  func opReturn(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   806  	offset, size := callContext.stack.pop(), callContext.stack.pop()
   807  	ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
   808  
   809  	return ret, nil
   810  }
   811  
   812  func opRevert(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   813  	offset, size := callContext.stack.pop(), callContext.stack.pop()
   814  	ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
   815  
   816  	return ret, nil
   817  }
   818  
   819  func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   820  	return nil, nil
   821  }
   822  
   823  func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   824  	beneficiary := callContext.stack.pop()
   825  	balance := interpreter.evm.StateDB.GetBalance(callContext.contract.Address())
   826  	interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance)
   827  	MakeOngTransferLog(interpreter.evm.StateDB, callContext.contract.Address(), beneficiary.Bytes20(), balance)
   828  	interpreter.evm.StateDB.Suicide(callContext.contract.Address())
   829  	return nil, nil
   830  }
   831  
   832  // following functions are used by the instruction jump  table
   833  
   834  // make log instruction function
   835  func makeLog(size int) executionFunc {
   836  	return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   837  		topics := make([]common.Hash, size)
   838  		stack := callContext.stack
   839  		mStart, mSize := stack.pop(), stack.pop()
   840  		for i := 0; i < size; i++ {
   841  			addr := stack.pop()
   842  			topics[i] = addr.Bytes32()
   843  		}
   844  
   845  		d := callContext.memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
   846  		interpreter.evm.StateDB.AddLog(&types.StorageLog{
   847  			Address: callContext.contract.Address(),
   848  			Topics:  topics,
   849  			Data:    d,
   850  		})
   851  
   852  		return nil, nil
   853  	}
   854  }
   855  
   856  // opPush1 is a specialized version of pushN
   857  func opPush1(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   858  	var (
   859  		codeLen = uint64(len(callContext.contract.Code))
   860  		integer = new(uint256.Int)
   861  	)
   862  	*pc += 1
   863  	if *pc < codeLen {
   864  		callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc])))
   865  	} else {
   866  		callContext.stack.push(integer.Clear())
   867  	}
   868  	return nil, nil
   869  }
   870  
   871  // make push instruction function
   872  func makePush(size uint64, pushByteSize int) executionFunc {
   873  	return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   874  		codeLen := len(callContext.contract.Code)
   875  
   876  		startMin := codeLen
   877  		if int(*pc+1) < startMin {
   878  			startMin = int(*pc + 1)
   879  		}
   880  
   881  		endMin := codeLen
   882  		if startMin+pushByteSize < endMin {
   883  			endMin = startMin + pushByteSize
   884  		}
   885  
   886  		integer := new(uint256.Int)
   887  		callContext.stack.push(integer.SetBytes(common.RightPadBytes(
   888  			callContext.contract.Code[startMin:endMin], pushByteSize)))
   889  
   890  		*pc += size
   891  		return nil, nil
   892  	}
   893  }
   894  
   895  // make dup instruction function
   896  func makeDup(size int64) executionFunc {
   897  	return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   898  		callContext.stack.dup(int(size))
   899  		return nil, nil
   900  	}
   901  }
   902  
   903  // make swap instruction function
   904  func makeSwap(size int64) executionFunc {
   905  	// switch n + 1 otherwise n would be swapped with n
   906  	size++
   907  	return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
   908  		callContext.stack.swap(int(size))
   909  		return nil, nil
   910  	}
   911  }