github.com/ylsgit/go-ethereum@v1.6.5/core/vm/instructions.go (about)

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