github.com/core-coin/go-core/v2@v2.1.9/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/uint256"
    21  	"golang.org/x/crypto/sha3"
    22  
    23  	"github.com/core-coin/go-core/v2/common"
    24  	"github.com/core-coin/go-core/v2/core/types"
    25  	"github.com/core-coin/go-core/v2/params"
    26  )
    27  
    28  func opAdd(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
    29  	x, y := callContext.stack.pop(), callContext.stack.peek()
    30  	y.Add(&x, y)
    31  	return nil, nil
    32  }
    33  
    34  func opSub(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
    35  	x, y := callContext.stack.pop(), callContext.stack.peek()
    36  	y.Sub(&x, y)
    37  	return nil, nil
    38  }
    39  
    40  func opMul(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
    41  	x, y := callContext.stack.pop(), callContext.stack.peek()
    42  	y.Mul(&x, y)
    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 stack, first arg1 and then arg2,
   190  // and pushes on the stack arg2 shifted to the left by arg1 number of bits.
   191  func opSHL(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   192  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   193  	shift, value := 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  	return nil, nil
   200  }
   201  
   202  // opSHR implements Logical Shift Right
   203  // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
   204  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
   205  func opSHR(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   206  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   207  	shift, value := callContext.stack.pop(), callContext.stack.peek()
   208  	if shift.LtUint64(256) {
   209  		value.Rsh(value, uint(shift.Uint64()))
   210  	} else {
   211  		value.Clear()
   212  	}
   213  	return nil, nil
   214  }
   215  
   216  // opSAR implements Arithmetic Shift Right
   217  // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
   218  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
   219  func opSAR(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   220  	shift, value := callContext.stack.pop(), callContext.stack.peek()
   221  	if shift.GtUint64(256) {
   222  		if value.Sign() >= 0 {
   223  			value.Clear()
   224  		} else {
   225  			// Max negative shift: all bits set
   226  			value.SetAllOne()
   227  		}
   228  		return nil, nil
   229  	}
   230  	n := uint(shift.Uint64())
   231  	value.SRsh(value, n)
   232  	return nil, nil
   233  }
   234  
   235  func opSha3(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   236  	offset, size := callContext.stack.pop(), callContext.stack.peek()
   237  	data := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
   238  
   239  	if interpreter.hasher == nil {
   240  		interpreter.hasher = sha3.New256().(keccakState)
   241  	} else {
   242  		interpreter.hasher.Reset()
   243  	}
   244  	interpreter.hasher.Write(data)
   245  	interpreter.hasher.Read(interpreter.hasherBuf[:])
   246  
   247  	cvm := interpreter.cvm
   248  	if cvm.vmConfig.EnablePreimageRecording {
   249  		cvm.StateDB.AddPreimage(interpreter.hasherBuf, data)
   250  	}
   251  
   252  	size.SetBytes(interpreter.hasherBuf[:])
   253  	return nil, nil
   254  }
   255  func opAddress(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   256  	callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Address().Bytes()))
   257  	return nil, nil
   258  }
   259  
   260  func opBalance(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   261  	slot := callContext.stack.peek()
   262  	address := common.Address(slot.Bytes22())
   263  	slot.SetFromBig(interpreter.cvm.StateDB.GetBalance(address))
   264  	return nil, nil
   265  }
   266  
   267  func opOrigin(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   268  	callContext.stack.push(new(uint256.Int).SetBytes(interpreter.cvm.Origin.Bytes()))
   269  	return nil, nil
   270  }
   271  func opCaller(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   272  	callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Caller().Bytes()))
   273  	return nil, nil
   274  }
   275  
   276  func opCallValue(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   277  	v, _ := uint256.FromBig(callContext.contract.value)
   278  	callContext.stack.push(v)
   279  	return nil, nil
   280  }
   281  
   282  func opCallDataLoad(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   283  	x := callContext.stack.peek()
   284  	if offset, overflow := x.Uint64WithOverflow(); !overflow {
   285  		data := getData(callContext.contract.Input, offset, 32)
   286  		x.SetBytes(data)
   287  	} else {
   288  		x.Clear()
   289  	}
   290  	return nil, nil
   291  }
   292  
   293  func opCallDataSize(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   294  	callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(callContext.contract.Input))))
   295  	return nil, nil
   296  }
   297  
   298  func opCallDataCopy(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   299  	var (
   300  		memOffset  = callContext.stack.pop()
   301  		dataOffset = callContext.stack.pop()
   302  		length     = callContext.stack.pop()
   303  	)
   304  	dataOffset64, overflow := dataOffset.Uint64WithOverflow()
   305  	if overflow {
   306  		dataOffset64 = 0xffffffffffffffff
   307  	}
   308  	// These values are checked for overflow during energy cost calculation
   309  	memOffset64 := memOffset.Uint64()
   310  	length64 := length.Uint64()
   311  	callContext.memory.Set(memOffset64, length64, getData(callContext.contract.Input, dataOffset64, length64))
   312  
   313  	return nil, nil
   314  }
   315  
   316  func opReturnDataSize(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   317  	callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
   318  	return nil, nil
   319  }
   320  
   321  func opReturnDataCopy(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   322  	var (
   323  		memOffset  = callContext.stack.pop()
   324  		dataOffset = callContext.stack.pop()
   325  		length     = callContext.stack.pop()
   326  	)
   327  
   328  	offset64, overflow := dataOffset.Uint64WithOverflow()
   329  	if overflow {
   330  		return nil, ErrReturnDataOutOfBounds
   331  	}
   332  	// we can reuse dataOffset now (aliasing it for clarity)
   333  	var end = dataOffset
   334  	end.Add(&dataOffset, &length)
   335  	end64, overflow := end.Uint64WithOverflow()
   336  	if overflow || uint64(len(interpreter.returnData)) < end64 {
   337  		return nil, ErrReturnDataOutOfBounds
   338  	}
   339  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
   340  	return nil, nil
   341  }
   342  
   343  func opExtCodeSize(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   344  	slot := callContext.stack.peek()
   345  	slot.SetUint64(uint64(interpreter.cvm.StateDB.GetCodeSize(slot.Bytes22())))
   346  	return nil, nil
   347  }
   348  
   349  func opCodeSize(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   350  	l := new(uint256.Int)
   351  	l.SetUint64(uint64(len(callContext.contract.Code)))
   352  	callContext.stack.push(l)
   353  	return nil, nil
   354  }
   355  
   356  func opCodeCopy(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   357  	var (
   358  		memOffset  = callContext.stack.pop()
   359  		codeOffset = callContext.stack.pop()
   360  		length     = callContext.stack.pop()
   361  	)
   362  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   363  	if overflow {
   364  		uint64CodeOffset = 0xffffffffffffffff
   365  	}
   366  	codeCopy := getData(callContext.contract.Code, uint64CodeOffset, length.Uint64())
   367  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   368  
   369  	return nil, nil
   370  }
   371  
   372  func opExtCodeCopy(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   373  	var (
   374  		stack      = callContext.stack
   375  		a          = stack.pop()
   376  		memOffset  = stack.pop()
   377  		codeOffset = stack.pop()
   378  		length     = stack.pop()
   379  	)
   380  	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
   381  	if overflow {
   382  		uint64CodeOffset = 0xffffffffffffffff
   383  	}
   384  	addr := common.Address(a.Bytes22())
   385  	codeCopy := getData(interpreter.cvm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64())
   386  	callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   387  
   388  	return nil, nil
   389  }
   390  
   391  // opExtCodeHash returns the code hash of a specified account.
   392  // There are several cases when the function is called, while we can relay everything
   393  // to `state.GetCodeHash` function to ensure the correctness.
   394  //
   395  //	(1) Caller tries to get the code hash of a normal contract account, state
   396  //
   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  //
   401  // return common.Hash{} and zero will be set as the result.
   402  //
   403  //	(3) Caller tries to get the code hash for an account without contract code,
   404  //
   405  // state should return emptyCodeHash(0xc5d246...) as the result.
   406  //
   407  //	(4) Caller tries to get the code hash of a precompiled account, the result
   408  //
   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  //
   419  // in the current transaction, the code hash of this account should be returned.
   420  //
   421  //	(6) Caller tries to get the code hash for an account which is marked as deleted,
   422  //
   423  // this account should be regarded as a non-existent account and zero should be returned.
   424  func opExtCodeHash(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   425  	slot := callContext.stack.peek()
   426  	address := common.Address(slot.Bytes22())
   427  	if interpreter.cvm.StateDB.Empty(address) {
   428  		slot.Clear()
   429  	} else {
   430  		slot.SetBytes(interpreter.cvm.StateDB.GetCodeHash(address).Bytes())
   431  	}
   432  	return nil, nil
   433  }
   434  
   435  func opEnergyprice(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   436  	v, _ := uint256.FromBig(interpreter.cvm.EnergyPrice)
   437  	callContext.stack.push(v)
   438  	return nil, nil
   439  }
   440  
   441  func opBlockhash(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   442  	num := callContext.stack.peek()
   443  	num64, overflow := num.Uint64WithOverflow()
   444  	if overflow {
   445  		num.Clear()
   446  		return nil, nil
   447  	}
   448  	var upper, lower uint64
   449  	upper = interpreter.cvm.Context.BlockNumber.Uint64()
   450  	if upper < 257 {
   451  		lower = 0
   452  	} else {
   453  		lower = upper - 256
   454  	}
   455  	if num64 >= lower && num64 < upper {
   456  		num.SetBytes(interpreter.cvm.Context.GetHash(num64).Bytes())
   457  	} else {
   458  		num.Clear()
   459  	}
   460  	return nil, nil
   461  }
   462  
   463  func opCoinbase(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   464  	callContext.stack.push(new(uint256.Int).SetBytes(interpreter.cvm.Context.Coinbase.Bytes()))
   465  	return nil, nil
   466  }
   467  
   468  func opTimestamp(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   469  	v, _ := uint256.FromBig(interpreter.cvm.Context.Time)
   470  	callContext.stack.push(v)
   471  	return nil, nil
   472  }
   473  
   474  func opNumber(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   475  	v, _ := uint256.FromBig(interpreter.cvm.Context.BlockNumber)
   476  	callContext.stack.push(v)
   477  	return nil, nil
   478  }
   479  
   480  func opDifficulty(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   481  	v, _ := uint256.FromBig(interpreter.cvm.Context.Difficulty)
   482  	callContext.stack.push(v)
   483  	return nil, nil
   484  }
   485  
   486  func opEnergyLimit(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   487  	callContext.stack.push(new(uint256.Int).SetUint64(interpreter.cvm.Context.EnergyLimit))
   488  	return nil, nil
   489  }
   490  
   491  func opPop(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   492  	callContext.stack.pop()
   493  	return nil, nil
   494  }
   495  
   496  func opMload(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   497  	v := callContext.stack.peek()
   498  	offset := int64(v.Uint64())
   499  	v.SetBytes(callContext.memory.GetPtr(offset, 32))
   500  	return nil, nil
   501  }
   502  
   503  func opMstore(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   504  	// pop value of the stack
   505  	mStart, val := callContext.stack.pop(), callContext.stack.pop()
   506  	callContext.memory.Set32(mStart.Uint64(), &val)
   507  	return nil, nil
   508  }
   509  
   510  func opMstore8(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   511  	off, val := callContext.stack.pop(), callContext.stack.pop()
   512  	callContext.memory.store[off.Uint64()] = byte(val.Uint64())
   513  	return nil, nil
   514  }
   515  
   516  func opSload(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   517  	loc := callContext.stack.peek()
   518  	hash := common.Hash(loc.Bytes32())
   519  	val := interpreter.cvm.StateDB.GetState(callContext.contract.Address(), hash)
   520  	loc.SetBytes(val.Bytes())
   521  	return nil, nil
   522  }
   523  
   524  func opSstore(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   525  	loc := callContext.stack.pop()
   526  	val := callContext.stack.pop()
   527  	interpreter.cvm.StateDB.SetState(callContext.contract.Address(),
   528  		loc.Bytes32(), val.Bytes32())
   529  	return nil, nil
   530  }
   531  
   532  func opJump(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   533  	pos := callContext.stack.pop()
   534  	if !callContext.contract.validJumpdest(&pos) {
   535  		return nil, ErrInvalidJump
   536  	}
   537  	*pc = pos.Uint64()
   538  	return nil, nil
   539  }
   540  
   541  func opJumpi(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   542  	pos, cond := callContext.stack.pop(), callContext.stack.pop()
   543  	if !cond.IsZero() {
   544  		if !callContext.contract.validJumpdest(&pos) {
   545  			return nil, ErrInvalidJump
   546  		}
   547  		*pc = pos.Uint64()
   548  	} else {
   549  		*pc++
   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  	energy -= energy / 64
   613  	// reuse size int for stackvalue
   614  	stackvalue := size
   615  
   616  	callContext.contract.UseEnergy(energy)
   617  	//TODO: use uint256.Int instead of converting with toBig()
   618  	var bigVal = big0
   619  	if !value.IsZero() {
   620  		bigVal = value.ToBig()
   621  	}
   622  
   623  	res, addr, returnEnergy, suberr := interpreter.cvm.Create(callContext.contract, input, energy, bigVal)
   624  	// Push item on the stack based on the returned error. If the ruleset is
   625  	// homestead we must check for CodeStoreOutOfEnergyError (homestead only
   626  	// rule) and treat as an error, if the ruleset is frontier we must
   627  	// ignore this error and pretend the operation was successful.
   628  	if suberr == ErrCodeStoreOutOfEnergy {
   629  		stackvalue.Clear()
   630  	} else if suberr != nil && suberr != ErrCodeStoreOutOfEnergy {
   631  		stackvalue.Clear()
   632  	} else {
   633  		stackvalue.SetBytes(addr.Bytes())
   634  	}
   635  	callContext.stack.push(&stackvalue)
   636  	callContext.contract.Energy += returnEnergy
   637  
   638  	if suberr == ErrExecutionReverted {
   639  		return res, nil
   640  	}
   641  	return nil, nil
   642  }
   643  
   644  func opCreate2(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   645  	var (
   646  		endowment    = callContext.stack.pop()
   647  		offset, size = callContext.stack.pop(), callContext.stack.pop()
   648  		salt         = callContext.stack.pop()
   649  		input        = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
   650  		energy       = callContext.contract.Energy
   651  	)
   652  
   653  	// Apply CIP150
   654  	energy -= energy / 64
   655  	callContext.contract.UseEnergy(energy)
   656  	// reuse size int for stackvalue
   657  	stackvalue := size
   658  	//TODO: use uint256.Int instead of converting with toBig()
   659  	bigEndowment := big0
   660  	if !endowment.IsZero() {
   661  		bigEndowment = endowment.ToBig()
   662  	}
   663  	res, addr, returnEnergy, suberr := interpreter.cvm.Create2(callContext.contract, input, energy,
   664  		bigEndowment, &salt)
   665  	// Push item on the stack based on the returned error.
   666  	if suberr != nil {
   667  		stackvalue.Clear()
   668  	} else {
   669  		stackvalue.SetBytes(addr.Bytes())
   670  	}
   671  	callContext.stack.push(&stackvalue)
   672  	callContext.contract.Energy += returnEnergy
   673  
   674  	if suberr == ErrExecutionReverted {
   675  		return res, nil
   676  	}
   677  	return nil, nil
   678  }
   679  
   680  func opCall(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   681  	stack := callContext.stack
   682  	// Pop energy. The actual energy in interpreter.cvm.callEnergyTemp.
   683  	// We can use this as a temporary value
   684  	temp := stack.pop()
   685  	energy := interpreter.cvm.callEnergyTemp
   686  	// Pop other call parameters.
   687  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   688  	toAddr := common.Address(addr.Bytes22())
   689  	// Get the arguments from the memory.
   690  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   691  
   692  	var bigVal = big0
   693  	//TODO: use uint256.Int instead of converting with toBig()
   694  	// By using big0 here, we save an alloc for the most common case (non-core-transferring contract calls),
   695  	// but it would make more sense to extend the usage of uint256.Int
   696  	if !value.IsZero() {
   697  		energy += params.CallStipend
   698  		bigVal = value.ToBig()
   699  	}
   700  
   701  	ret, returnEnergy, err := interpreter.cvm.Call(callContext.contract, toAddr, args, energy, bigVal)
   702  
   703  	if err != nil {
   704  		temp.Clear()
   705  	} else {
   706  		temp.SetOne()
   707  	}
   708  	stack.push(&temp)
   709  	if err == nil || err == ErrExecutionReverted {
   710  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   711  	}
   712  	callContext.contract.Energy += returnEnergy
   713  
   714  	return ret, nil
   715  }
   716  
   717  func opCallCode(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   718  	// Pop energy. The actual energy is in interpreter.cvm.callEnergyTemp.
   719  	stack := callContext.stack
   720  	// We use it as a temporary value
   721  	temp := stack.pop()
   722  	energy := interpreter.cvm.callEnergyTemp
   723  	// Pop other call parameters.
   724  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   725  	toAddr := common.Address(addr.Bytes22())
   726  	// Get arguments from the memory.
   727  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   728  
   729  	//TODO: use uint256.Int instead of converting with toBig()
   730  	var bigVal = big0
   731  	if !value.IsZero() {
   732  		energy += params.CallStipend
   733  		bigVal = value.ToBig()
   734  	}
   735  
   736  	ret, returnEnergy, err := interpreter.cvm.CallCode(callContext.contract, toAddr, args, energy, bigVal)
   737  	if err != nil {
   738  		temp.Clear()
   739  	} else {
   740  		temp.SetOne()
   741  	}
   742  	stack.push(&temp)
   743  	if err == nil || err == ErrExecutionReverted {
   744  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   745  	}
   746  	callContext.contract.Energy += returnEnergy
   747  
   748  	return ret, nil
   749  }
   750  
   751  func opDelegateCall(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   752  	stack := callContext.stack
   753  	// Pop energy. The actual energy is in interpreter.cvm.callEnergyTemp.
   754  	// We use it as a temporary value
   755  	temp := stack.pop()
   756  	energy := interpreter.cvm.callEnergyTemp
   757  	// Pop other call parameters.
   758  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   759  	toAddr := common.Address(addr.Bytes22())
   760  	// Get arguments from the memory.
   761  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   762  
   763  	ret, returnEnergy, err := interpreter.cvm.DelegateCall(callContext.contract, toAddr, args, energy)
   764  	if err != nil {
   765  		temp.Clear()
   766  	} else {
   767  		temp.SetOne()
   768  	}
   769  	stack.push(&temp)
   770  	if err == nil || err == ErrExecutionReverted {
   771  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   772  	}
   773  	callContext.contract.Energy += returnEnergy
   774  
   775  	return ret, nil
   776  }
   777  
   778  func opStaticCall(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   779  	// Pop energy. The actual energy is in interpreter.cvm.callEnergyTemp.
   780  	stack := callContext.stack
   781  	// We use it as a temporary value
   782  	temp := stack.pop()
   783  	energy := interpreter.cvm.callEnergyTemp
   784  	// Pop other call parameters.
   785  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   786  	toAddr := common.Address(addr.Bytes22())
   787  	// Get arguments from the memory.
   788  	args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
   789  
   790  	ret, returnEnergy, err := interpreter.cvm.StaticCall(callContext.contract, toAddr, args, energy)
   791  	if err != nil {
   792  		temp.Clear()
   793  	} else {
   794  		temp.SetOne()
   795  	}
   796  	stack.push(&temp)
   797  	if err == nil || err == ErrExecutionReverted {
   798  		callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   799  	}
   800  	callContext.contract.Energy += returnEnergy
   801  
   802  	return ret, nil
   803  }
   804  
   805  func opReturn(pc *uint64, interpreter *CVMInterpreter, 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 *CVMInterpreter, 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 *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   820  	return nil, nil
   821  }
   822  
   823  func opSuicide(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   824  	beneficiary := callContext.stack.pop()
   825  	balance := interpreter.cvm.StateDB.GetBalance(callContext.contract.Address())
   826  	interpreter.cvm.StateDB.AddBalance(beneficiary.Bytes22(), balance)
   827  	interpreter.cvm.StateDB.Suicide(callContext.contract.Address())
   828  	return nil, nil
   829  }
   830  
   831  // following functions are used by the instruction jump  table
   832  
   833  // make log instruction function
   834  func makeLog(size int) executionFunc {
   835  	return func(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   836  		topics := make([]common.Hash, size)
   837  		stack := callContext.stack
   838  		mStart, mSize := stack.pop(), stack.pop()
   839  		for i := 0; i < size; i++ {
   840  			addr := stack.pop()
   841  			topics[i] = addr.Bytes32()
   842  		}
   843  
   844  		d := callContext.memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
   845  		interpreter.cvm.StateDB.AddLog(&types.Log{
   846  			Address: callContext.contract.Address(),
   847  			Topics:  topics,
   848  			Data:    d,
   849  			// This is a non-consensus field, but assigned here because
   850  			// core/state doesn't know the current block number.
   851  			BlockNumber: interpreter.cvm.Context.BlockNumber.Uint64(),
   852  		})
   853  
   854  		return nil, nil
   855  	}
   856  }
   857  
   858  // opPush1 is a specialized version of pushN
   859  func opPush1(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   860  	var (
   861  		codeLen = uint64(len(callContext.contract.Code))
   862  		integer = new(uint256.Int)
   863  	)
   864  	*pc += 1
   865  	if *pc < codeLen {
   866  		callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc])))
   867  	} else {
   868  		callContext.stack.push(integer.Clear())
   869  	}
   870  	return nil, nil
   871  }
   872  
   873  // make push instruction function
   874  func makePush(size uint64, pushByteSize int) executionFunc {
   875  	return func(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   876  		codeLen := len(callContext.contract.Code)
   877  
   878  		startMin := codeLen
   879  		if int(*pc+1) < startMin {
   880  			startMin = int(*pc + 1)
   881  		}
   882  
   883  		endMin := codeLen
   884  		if startMin+pushByteSize < endMin {
   885  			endMin = startMin + pushByteSize
   886  		}
   887  
   888  		integer := new(uint256.Int)
   889  		callContext.stack.push(integer.SetBytes(common.RightPadBytes(
   890  			callContext.contract.Code[startMin:endMin], pushByteSize)))
   891  
   892  		*pc += size
   893  		return nil, nil
   894  	}
   895  }
   896  
   897  // make dup instruction function
   898  func makeDup(size int64) executionFunc {
   899  	return func(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   900  		callContext.stack.dup(int(size))
   901  		return nil, nil
   902  	}
   903  }
   904  
   905  // make swap instruction function
   906  func makeSwap(size int64) executionFunc {
   907  	// switch n + 1 otherwise n would be swapped with n
   908  	size++
   909  	return func(pc *uint64, interpreter *CVMInterpreter, callContext *callCtx) ([]byte, error) {
   910  		callContext.stack.swap(int(size))
   911  		return nil, nil
   912  	}
   913  }