github.com/core-coin/go-core@v1.1.7/core/vm/instructions.go (about)

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