github.com/aquanetwork/aquachain@v1.7.8/core/vm/instructions.go (about)

     1  // Copyright 2015 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain 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 aquachain 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 aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vm
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"gitlab.com/aquachain/aquachain/common"
    25  	"gitlab.com/aquachain/aquachain/common/math"
    26  	"gitlab.com/aquachain/aquachain/core/types"
    27  	"gitlab.com/aquachain/aquachain/crypto"
    28  	"gitlab.com/aquachain/aquachain/params"
    29  )
    30  
    31  var (
    32  	bigZero                  = new(big.Int)
    33  	errWriteProtection       = errors.New("evm: write protection")
    34  	errReturnDataOutOfBounds = errors.New("evm: return data out of bounds")
    35  	errExecutionReverted     = errors.New("evm: execution reverted")
    36  	errMaxCodeSizeExceeded   = errors.New("evm: max code size exceeded")
    37  )
    38  
    39  func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    40  	x, y := stack.pop(), stack.pop()
    41  	stack.push(math.U256(x.Add(x, y)))
    42  
    43  	evm.interpreter.intPool.put(y)
    44  
    45  	return nil, nil
    46  }
    47  
    48  func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    49  	x, y := stack.pop(), stack.pop()
    50  	stack.push(math.U256(x.Sub(x, y)))
    51  
    52  	evm.interpreter.intPool.put(y)
    53  
    54  	return nil, nil
    55  }
    56  
    57  func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    58  	x, y := stack.pop(), stack.pop()
    59  	stack.push(math.U256(x.Mul(x, y)))
    60  
    61  	evm.interpreter.intPool.put(y)
    62  
    63  	return nil, nil
    64  }
    65  
    66  func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    67  	x, y := stack.pop(), stack.pop()
    68  	if y.Sign() != 0 {
    69  		stack.push(math.U256(x.Div(x, y)))
    70  	} else {
    71  		stack.push(new(big.Int))
    72  	}
    73  
    74  	evm.interpreter.intPool.put(y)
    75  
    76  	return nil, nil
    77  }
    78  
    79  func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
    80  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
    81  	if y.Sign() == 0 {
    82  		stack.push(new(big.Int))
    83  		return nil, nil
    84  	} else {
    85  		n := new(big.Int)
    86  		if evm.interpreter.intPool.get().Mul(x, y).Sign() < 0 {
    87  			n.SetInt64(-1)
    88  		} else {
    89  			n.SetInt64(1)
    90  		}
    91  
    92  		res := x.Div(x.Abs(x), y.Abs(y))
    93  		res.Mul(res, n)
    94  
    95  		stack.push(math.U256(res))
    96  	}
    97  	evm.interpreter.intPool.put(y)
    98  	return nil, nil
    99  }
   100  
   101  func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   102  	x, y := stack.pop(), stack.pop()
   103  	if y.Sign() == 0 {
   104  		stack.push(new(big.Int))
   105  	} else {
   106  		stack.push(math.U256(x.Mod(x, y)))
   107  	}
   108  	evm.interpreter.intPool.put(y)
   109  	return nil, nil
   110  }
   111  
   112  func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   113  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   114  
   115  	if y.Sign() == 0 {
   116  		stack.push(new(big.Int))
   117  	} else {
   118  		n := new(big.Int)
   119  		if x.Sign() < 0 {
   120  			n.SetInt64(-1)
   121  		} else {
   122  			n.SetInt64(1)
   123  		}
   124  
   125  		res := x.Mod(x.Abs(x), y.Abs(y))
   126  		res.Mul(res, n)
   127  
   128  		stack.push(math.U256(res))
   129  	}
   130  	evm.interpreter.intPool.put(y)
   131  	return nil, nil
   132  }
   133  
   134  func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   135  	base, exponent := stack.pop(), stack.pop()
   136  	stack.push(math.Exp(base, exponent))
   137  
   138  	evm.interpreter.intPool.put(base, exponent)
   139  
   140  	return nil, nil
   141  }
   142  
   143  func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   144  	back := stack.pop()
   145  	if back.Cmp(big.NewInt(31)) < 0 {
   146  		bit := uint(back.Uint64()*8 + 7)
   147  		num := stack.pop()
   148  		mask := back.Lsh(common.Big1, bit)
   149  		mask.Sub(mask, common.Big1)
   150  		if num.Bit(int(bit)) > 0 {
   151  			num.Or(num, mask.Not(mask))
   152  		} else {
   153  			num.And(num, mask)
   154  		}
   155  
   156  		stack.push(math.U256(num))
   157  	}
   158  
   159  	evm.interpreter.intPool.put(back)
   160  	return nil, nil
   161  }
   162  
   163  func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   164  	x := stack.pop()
   165  	stack.push(math.U256(x.Not(x)))
   166  	return nil, nil
   167  }
   168  
   169  func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   170  	x, y := stack.pop(), stack.pop()
   171  	if x.Cmp(y) < 0 {
   172  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   173  	} else {
   174  		stack.push(new(big.Int))
   175  	}
   176  
   177  	evm.interpreter.intPool.put(x, y)
   178  	return nil, nil
   179  }
   180  
   181  func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   182  	x, y := stack.pop(), stack.pop()
   183  	if x.Cmp(y) > 0 {
   184  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   185  	} else {
   186  		stack.push(new(big.Int))
   187  	}
   188  
   189  	evm.interpreter.intPool.put(x, y)
   190  	return nil, nil
   191  }
   192  
   193  func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   194  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   195  	if x.Cmp(math.S256(y)) < 0 {
   196  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   197  	} else {
   198  		stack.push(new(big.Int))
   199  	}
   200  
   201  	evm.interpreter.intPool.put(x, y)
   202  	return nil, nil
   203  }
   204  
   205  func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   206  	x, y := math.S256(stack.pop()), math.S256(stack.pop())
   207  	if x.Cmp(y) > 0 {
   208  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   209  	} else {
   210  		stack.push(new(big.Int))
   211  	}
   212  
   213  	evm.interpreter.intPool.put(x, y)
   214  	return nil, nil
   215  }
   216  
   217  func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   218  	x, y := stack.pop(), stack.pop()
   219  	if x.Cmp(y) == 0 {
   220  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   221  	} else {
   222  		stack.push(new(big.Int))
   223  	}
   224  
   225  	evm.interpreter.intPool.put(x, y)
   226  	return nil, nil
   227  }
   228  
   229  func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   230  	x := stack.pop()
   231  	if x.Sign() > 0 {
   232  		stack.push(new(big.Int))
   233  	} else {
   234  		stack.push(evm.interpreter.intPool.get().SetUint64(1))
   235  	}
   236  
   237  	evm.interpreter.intPool.put(x)
   238  	return nil, nil
   239  }
   240  
   241  func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   242  	x, y := stack.pop(), stack.pop()
   243  	stack.push(x.And(x, y))
   244  
   245  	evm.interpreter.intPool.put(y)
   246  	return nil, nil
   247  }
   248  
   249  func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   250  	x, y := stack.pop(), stack.pop()
   251  	stack.push(x.Or(x, y))
   252  
   253  	evm.interpreter.intPool.put(y)
   254  	return nil, nil
   255  }
   256  
   257  func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   258  	x, y := stack.pop(), stack.pop()
   259  	stack.push(x.Xor(x, y))
   260  
   261  	evm.interpreter.intPool.put(y)
   262  	return nil, nil
   263  }
   264  
   265  func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   266  	th, val := stack.pop(), stack.peek()
   267  	if th.Cmp(common.Big32) < 0 {
   268  		b := math.Byte(val, 32, int(th.Int64()))
   269  		val.SetUint64(uint64(b))
   270  	} else {
   271  		val.SetUint64(0)
   272  	}
   273  	evm.interpreter.intPool.put(th)
   274  	return nil, nil
   275  }
   276  
   277  func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   278  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   279  	if z.Cmp(bigZero) > 0 {
   280  		add := x.Add(x, y)
   281  		add.Mod(add, z)
   282  		stack.push(math.U256(add))
   283  	} else {
   284  		stack.push(new(big.Int))
   285  	}
   286  
   287  	evm.interpreter.intPool.put(y, z)
   288  	return nil, nil
   289  }
   290  
   291  func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   292  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   293  	if z.Cmp(bigZero) > 0 {
   294  		mul := x.Mul(x, y)
   295  		mul.Mod(mul, z)
   296  		stack.push(math.U256(mul))
   297  	} else {
   298  		stack.push(new(big.Int))
   299  	}
   300  
   301  	evm.interpreter.intPool.put(y, z)
   302  	return nil, nil
   303  }
   304  
   305  // opSHL implements Shift Left
   306  // The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
   307  // and pushes on the stack arg2 shifted to the left by arg1 number of bits.
   308  func opSHL(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   309  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   310  	shift, value := math.U256(stack.pop()), math.U256(stack.peek())
   311  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   312  
   313  	if shift.Cmp(common.Big256) >= 0 {
   314  		value.SetUint64(0)
   315  		return nil, nil
   316  	}
   317  	n := uint(shift.Uint64())
   318  	math.U256(value.Lsh(value, n))
   319  
   320  	return nil, nil
   321  }
   322  
   323  // opSHR implements Logical Shift Right
   324  // The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
   325  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
   326  func opSHR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   327  	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
   328  	shift, value := math.U256(stack.pop()), math.U256(stack.peek())
   329  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   330  
   331  	if shift.Cmp(common.Big256) >= 0 {
   332  		value.SetUint64(0)
   333  		return nil, nil
   334  	}
   335  	n := uint(shift.Uint64())
   336  	math.U256(value.Rsh(value, n))
   337  
   338  	return nil, nil
   339  }
   340  
   341  // opSAR implements Arithmetic Shift Right
   342  // The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
   343  // and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
   344  func opSAR(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   345  	// Note, S256 returns (potentially) a new bigint, so we're popping, not peeking this one
   346  	shift, value := math.U256(stack.pop()), math.S256(stack.pop())
   347  	defer evm.interpreter.intPool.put(shift) // First operand back into the pool
   348  
   349  	if shift.Cmp(common.Big256) >= 0 {
   350  		if value.Sign() > 0 {
   351  			value.SetUint64(0)
   352  		} else {
   353  			value.SetInt64(-1)
   354  		}
   355  		stack.push(math.U256(value))
   356  		return nil, nil
   357  	}
   358  	n := uint(shift.Uint64())
   359  	value.Rsh(value, n)
   360  	stack.push(math.U256(value))
   361  
   362  	return nil, nil
   363  }
   364  
   365  func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   366  	offset, size := stack.pop(), stack.pop()
   367  	data := memory.Get(offset.Int64(), size.Int64())
   368  	hash := crypto.Keccak256(data)
   369  
   370  	if evm.vmConfig.EnablePreimageRecording {
   371  		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
   372  	}
   373  
   374  	stack.push(new(big.Int).SetBytes(hash))
   375  
   376  	evm.interpreter.intPool.put(offset, size)
   377  	return nil, nil
   378  }
   379  
   380  func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   381  	stack.push(contract.Address().Big())
   382  	return nil, nil
   383  }
   384  
   385  func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   386  	addr := common.BigToAddress(stack.pop())
   387  	balance := evm.StateDB.GetBalance(addr)
   388  
   389  	stack.push(new(big.Int).Set(balance))
   390  	return nil, nil
   391  }
   392  
   393  func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   394  	stack.push(evm.Origin.Big())
   395  	return nil, nil
   396  }
   397  
   398  func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   399  	stack.push(contract.Caller().Big())
   400  	return nil, nil
   401  }
   402  
   403  func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   404  	stack.push(evm.interpreter.intPool.get().Set(contract.value))
   405  	return nil, nil
   406  }
   407  
   408  func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   409  	stack.push(new(big.Int).SetBytes(getDataBig(contract.Input, stack.pop(), big32)))
   410  	return nil, nil
   411  }
   412  
   413  func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   414  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
   415  	return nil, nil
   416  }
   417  
   418  func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   419  	var (
   420  		memOffset  = stack.pop()
   421  		dataOffset = stack.pop()
   422  		length     = stack.pop()
   423  	)
   424  	memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length))
   425  
   426  	evm.interpreter.intPool.put(memOffset, dataOffset, length)
   427  	return nil, nil
   428  }
   429  
   430  func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   431  	stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData))))
   432  	return nil, nil
   433  }
   434  
   435  func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   436  	var (
   437  		memOffset  = stack.pop()
   438  		dataOffset = stack.pop()
   439  		length     = stack.pop()
   440  	)
   441  	defer evm.interpreter.intPool.put(memOffset, dataOffset, length)
   442  
   443  	end := new(big.Int).Add(dataOffset, length)
   444  	if end.BitLen() > 64 || uint64(len(evm.interpreter.returnData)) < end.Uint64() {
   445  		return nil, errReturnDataOutOfBounds
   446  	}
   447  	memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()])
   448  
   449  	return nil, nil
   450  }
   451  
   452  func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   453  	a := stack.pop()
   454  
   455  	addr := common.BigToAddress(a)
   456  	a.SetInt64(int64(evm.StateDB.GetCodeSize(addr)))
   457  	stack.push(a)
   458  
   459  	return nil, nil
   460  }
   461  
   462  func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   463  	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
   464  	stack.push(l)
   465  	return nil, nil
   466  }
   467  
   468  func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   469  	var (
   470  		memOffset  = stack.pop()
   471  		codeOffset = stack.pop()
   472  		length     = stack.pop()
   473  	)
   474  	codeCopy := getDataBig(contract.Code, codeOffset, length)
   475  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   476  
   477  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   478  	return nil, nil
   479  }
   480  
   481  func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   482  	var (
   483  		addr       = common.BigToAddress(stack.pop())
   484  		memOffset  = stack.pop()
   485  		codeOffset = stack.pop()
   486  		length     = stack.pop()
   487  	)
   488  	codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length)
   489  	memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
   490  
   491  	evm.interpreter.intPool.put(memOffset, codeOffset, length)
   492  	return nil, nil
   493  }
   494  
   495  func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   496  	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
   497  	return nil, nil
   498  }
   499  
   500  func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   501  	num := stack.pop()
   502  
   503  	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
   504  	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
   505  		stack.push(evm.GetHash(num.Uint64()).Big())
   506  	} else {
   507  		stack.push(new(big.Int))
   508  	}
   509  
   510  	evm.interpreter.intPool.put(num, n)
   511  	return nil, nil
   512  }
   513  
   514  func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   515  	stack.push(evm.Coinbase.Big())
   516  	return nil, nil
   517  }
   518  
   519  func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   520  	stack.push(math.U256(new(big.Int).Set(evm.Time)))
   521  	return nil, nil
   522  }
   523  
   524  func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   525  	stack.push(math.U256(new(big.Int).Set(evm.BlockNumber)))
   526  	return nil, nil
   527  }
   528  
   529  func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   530  	stack.push(math.U256(new(big.Int).Set(evm.Difficulty)))
   531  	return nil, nil
   532  }
   533  
   534  func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   535  	stack.push(math.U256(new(big.Int).SetUint64(evm.GasLimit)))
   536  	return nil, nil
   537  }
   538  
   539  func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   540  	evm.interpreter.intPool.put(stack.pop())
   541  	return nil, nil
   542  }
   543  
   544  func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   545  	offset := stack.pop()
   546  	val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32))
   547  	stack.push(val)
   548  
   549  	evm.interpreter.intPool.put(offset)
   550  	return nil, nil
   551  }
   552  
   553  func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   554  	// pop value of the stack
   555  	mStart, val := stack.pop(), stack.pop()
   556  	memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
   557  
   558  	evm.interpreter.intPool.put(mStart, val)
   559  	return nil, nil
   560  }
   561  
   562  func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   563  	off, val := stack.pop().Int64(), stack.pop().Int64()
   564  	memory.store[off] = byte(val & 0xff)
   565  
   566  	return nil, nil
   567  }
   568  
   569  func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   570  	loc := common.BigToHash(stack.pop())
   571  	val := evm.StateDB.GetState(contract.Address(), loc).Big()
   572  	stack.push(val)
   573  	return nil, nil
   574  }
   575  
   576  func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   577  	loc := common.BigToHash(stack.pop())
   578  	val := stack.pop()
   579  	evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
   580  
   581  	evm.interpreter.intPool.put(val)
   582  	return nil, nil
   583  }
   584  
   585  func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   586  	pos := stack.pop()
   587  	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   588  		nop := contract.GetOp(pos.Uint64())
   589  		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   590  	}
   591  	*pc = pos.Uint64()
   592  
   593  	evm.interpreter.intPool.put(pos)
   594  	return nil, nil
   595  }
   596  
   597  func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   598  	pos, cond := stack.pop(), stack.pop()
   599  	if cond.Sign() != 0 {
   600  		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   601  			nop := contract.GetOp(pos.Uint64())
   602  			return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   603  		}
   604  		*pc = pos.Uint64()
   605  	} else {
   606  		*pc++
   607  	}
   608  
   609  	evm.interpreter.intPool.put(pos, cond)
   610  	return nil, nil
   611  }
   612  
   613  func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   614  	return nil, nil
   615  }
   616  
   617  func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   618  	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
   619  	return nil, nil
   620  }
   621  
   622  func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   623  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
   624  	return nil, nil
   625  }
   626  
   627  func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   628  	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
   629  	return nil, nil
   630  }
   631  
   632  func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   633  	var (
   634  		value        = stack.pop()
   635  		offset, size = stack.pop(), stack.pop()
   636  		input        = memory.Get(offset.Int64(), size.Int64())
   637  		gas          = contract.Gas
   638  	)
   639  	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
   640  		gas -= gas / 64
   641  	}
   642  
   643  	contract.UseGas(gas)
   644  	res, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
   645  	// Push item on the stack based on the returned error. If the ruleset is
   646  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   647  	// rule) and treat as an error, if the ruleset is frontier we must
   648  	// ignore this error and pretend the operation was successful.
   649  	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
   650  		stack.push(new(big.Int))
   651  	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
   652  		stack.push(new(big.Int))
   653  	} else {
   654  		stack.push(addr.Big())
   655  	}
   656  	contract.Gas += returnGas
   657  	evm.interpreter.intPool.put(value, offset, size)
   658  
   659  	if suberr == errExecutionReverted {
   660  		return res, nil
   661  	}
   662  	return nil, nil
   663  }
   664  
   665  func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   666  	// Pop gas. The actual gas in in evm.callGasTemp.
   667  	evm.interpreter.intPool.put(stack.pop())
   668  	gas := evm.callGasTemp
   669  	// Pop other call parameters.
   670  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   671  	toAddr := common.BigToAddress(addr)
   672  	value = math.U256(value)
   673  	// Get the arguments from the memory.
   674  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   675  
   676  	if value.Sign() != 0 {
   677  		gas += params.CallStipend
   678  	}
   679  	ret, returnGas, err := evm.Call(contract, toAddr, args, gas, value)
   680  	if err != nil {
   681  		stack.push(new(big.Int))
   682  	} else {
   683  		stack.push(big.NewInt(1))
   684  	}
   685  	if err == nil || err == errExecutionReverted {
   686  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   687  	}
   688  	contract.Gas += returnGas
   689  
   690  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   691  	return ret, nil
   692  }
   693  
   694  func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   695  	// Pop gas. The actual gas is in evm.callGasTemp.
   696  	evm.interpreter.intPool.put(stack.pop())
   697  	gas := evm.callGasTemp
   698  	// Pop other call parameters.
   699  	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   700  	toAddr := common.BigToAddress(addr)
   701  	value = math.U256(value)
   702  	// Get arguments from the memory.
   703  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   704  
   705  	if value.Sign() != 0 {
   706  		gas += params.CallStipend
   707  	}
   708  	ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value)
   709  	if err != nil {
   710  		stack.push(new(big.Int))
   711  	} else {
   712  		stack.push(big.NewInt(1))
   713  	}
   714  	if err == nil || err == errExecutionReverted {
   715  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   716  	}
   717  	contract.Gas += returnGas
   718  
   719  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   720  	return ret, nil
   721  }
   722  
   723  func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   724  	// Pop gas. The actual gas is in evm.callGasTemp.
   725  	evm.interpreter.intPool.put(stack.pop())
   726  	gas := evm.callGasTemp
   727  	// Pop other call parameters.
   728  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   729  	toAddr := common.BigToAddress(addr)
   730  	// Get arguments from the memory.
   731  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   732  
   733  	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
   734  	if err != nil {
   735  		stack.push(new(big.Int))
   736  	} else {
   737  		stack.push(big.NewInt(1))
   738  	}
   739  	if err == nil || err == errExecutionReverted {
   740  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   741  	}
   742  	contract.Gas += returnGas
   743  
   744  	evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
   745  	return ret, nil
   746  }
   747  
   748  func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   749  	// Pop gas. The actual gas is in evm.callGasTemp.
   750  	evm.interpreter.intPool.put(stack.pop())
   751  	gas := evm.callGasTemp
   752  	// Pop other call parameters.
   753  	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   754  	toAddr := common.BigToAddress(addr)
   755  	// Get arguments from the memory.
   756  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   757  
   758  	ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas)
   759  	if err != nil {
   760  		stack.push(new(big.Int))
   761  	} else {
   762  		stack.push(big.NewInt(1))
   763  	}
   764  	if err == nil || err == errExecutionReverted {
   765  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   766  	}
   767  	contract.Gas += returnGas
   768  
   769  	evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize)
   770  	return ret, nil
   771  }
   772  
   773  func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   774  	offset, size := stack.pop(), stack.pop()
   775  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   776  
   777  	evm.interpreter.intPool.put(offset, size)
   778  	return ret, nil
   779  }
   780  
   781  func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   782  	offset, size := stack.pop(), stack.pop()
   783  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   784  
   785  	evm.interpreter.intPool.put(offset, size)
   786  	return ret, nil
   787  }
   788  
   789  func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   790  	return nil, nil
   791  }
   792  
   793  func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   794  	balance := evm.StateDB.GetBalance(contract.Address())
   795  	evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
   796  
   797  	evm.StateDB.Suicide(contract.Address())
   798  	return nil, nil
   799  }
   800  
   801  // following functions are used by the instruction jump  table
   802  
   803  // make log instruction function
   804  func makeLog(size int) executionFunc {
   805  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   806  		topics := make([]common.Hash, size)
   807  		mStart, mSize := stack.pop(), stack.pop()
   808  		for i := 0; i < size; i++ {
   809  			topics[i] = common.BigToHash(stack.pop())
   810  		}
   811  
   812  		d := memory.Get(mStart.Int64(), mSize.Int64())
   813  		evm.StateDB.AddLog(&types.Log{
   814  			Address: contract.Address(),
   815  			Topics:  topics,
   816  			Data:    d,
   817  			// This is a non-consensus field, but assigned here because
   818  			// core/state doesn't know the current block number.
   819  			BlockNumber: evm.BlockNumber.Uint64(),
   820  		})
   821  
   822  		evm.interpreter.intPool.put(mStart, mSize)
   823  		return nil, nil
   824  	}
   825  }
   826  
   827  // make push instruction function
   828  func makePush(size uint64, pushByteSize int) executionFunc {
   829  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   830  		codeLen := len(contract.Code)
   831  
   832  		startMin := codeLen
   833  		if int(*pc+1) < startMin {
   834  			startMin = int(*pc + 1)
   835  		}
   836  
   837  		endMin := codeLen
   838  		if startMin+pushByteSize < endMin {
   839  			endMin = startMin + pushByteSize
   840  		}
   841  
   842  		integer := evm.interpreter.intPool.get()
   843  		stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
   844  
   845  		*pc += size
   846  		return nil, nil
   847  	}
   848  }
   849  
   850  // make push instruction function
   851  func makeDup(size int64) executionFunc {
   852  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   853  		stack.dup(evm.interpreter.intPool, int(size))
   854  		return nil, nil
   855  	}
   856  }
   857  
   858  // make swap instruction function
   859  func makeSwap(size int64) executionFunc {
   860  	// switch n + 1 otherwise n would be swapped with n
   861  	size += 1
   862  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   863  		stack.swap(int(size))
   864  		return nil, nil
   865  	}
   866  }