github.com/klaytn/klaytn@v1.12.1/blockchain/vm/instructions.go (about)

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