github.com/myafeier/go-ethereum@v1.6.8-0.20170719123245-3e0dbe0eaa72/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.peek()
   260  	if th.Cmp(common.Big32) < 0 {
   261  		b := math.Byte(val, 32, int(th.Int64()))
   262  		val.SetUint64(uint64(b))
   263  	} else {
   264  		val.SetUint64(0)
   265  	}
   266  	evm.interpreter.intPool.put(th)
   267  	return nil, nil
   268  }
   269  func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   270  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   271  	if z.Cmp(bigZero) > 0 {
   272  		add := x.Add(x, y)
   273  		add.Mod(add, z)
   274  		stack.push(math.U256(add))
   275  	} else {
   276  		stack.push(new(big.Int))
   277  	}
   278  
   279  	evm.interpreter.intPool.put(y, z)
   280  	return nil, nil
   281  }
   282  func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   283  	x, y, z := stack.pop(), stack.pop(), stack.pop()
   284  	if z.Cmp(bigZero) > 0 {
   285  		mul := x.Mul(x, y)
   286  		mul.Mod(mul, z)
   287  		stack.push(math.U256(mul))
   288  	} else {
   289  		stack.push(new(big.Int))
   290  	}
   291  
   292  	evm.interpreter.intPool.put(y, z)
   293  	return nil, nil
   294  }
   295  
   296  func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   297  	offset, size := stack.pop(), stack.pop()
   298  	data := memory.Get(offset.Int64(), size.Int64())
   299  	hash := crypto.Keccak256(data)
   300  
   301  	if evm.vmConfig.EnablePreimageRecording {
   302  		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
   303  	}
   304  
   305  	stack.push(new(big.Int).SetBytes(hash))
   306  
   307  	evm.interpreter.intPool.put(offset, size)
   308  	return nil, nil
   309  }
   310  
   311  func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   312  	stack.push(contract.Address().Big())
   313  	return nil, nil
   314  }
   315  
   316  func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   317  	addr := common.BigToAddress(stack.pop())
   318  	balance := evm.StateDB.GetBalance(addr)
   319  
   320  	stack.push(new(big.Int).Set(balance))
   321  	return nil, nil
   322  }
   323  
   324  func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   325  	stack.push(evm.Origin.Big())
   326  	return nil, nil
   327  }
   328  
   329  func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   330  	stack.push(contract.Caller().Big())
   331  	return nil, nil
   332  }
   333  
   334  func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   335  	stack.push(evm.interpreter.intPool.get().Set(contract.value))
   336  	return nil, nil
   337  }
   338  
   339  func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   340  	stack.push(new(big.Int).SetBytes(getData(contract.Input, stack.pop(), common.Big32)))
   341  	return nil, nil
   342  }
   343  
   344  func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   345  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
   346  	return nil, nil
   347  }
   348  
   349  func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   350  	var (
   351  		mOff = stack.pop()
   352  		cOff = stack.pop()
   353  		l    = stack.pop()
   354  	)
   355  	memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
   356  
   357  	evm.interpreter.intPool.put(mOff, cOff, l)
   358  	return nil, nil
   359  }
   360  
   361  func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   362  	a := stack.pop()
   363  
   364  	addr := common.BigToAddress(a)
   365  	a.SetInt64(int64(evm.StateDB.GetCodeSize(addr)))
   366  	stack.push(a)
   367  
   368  	return nil, nil
   369  }
   370  
   371  func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   372  	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
   373  	stack.push(l)
   374  	return nil, nil
   375  }
   376  
   377  func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   378  	var (
   379  		mOff = stack.pop()
   380  		cOff = stack.pop()
   381  		l    = stack.pop()
   382  	)
   383  	codeCopy := getData(contract.Code, cOff, l)
   384  
   385  	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
   386  
   387  	evm.interpreter.intPool.put(mOff, cOff, l)
   388  	return nil, nil
   389  }
   390  
   391  func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   392  	var (
   393  		addr = common.BigToAddress(stack.pop())
   394  		mOff = stack.pop()
   395  		cOff = stack.pop()
   396  		l    = stack.pop()
   397  	)
   398  	codeCopy := getData(evm.StateDB.GetCode(addr), cOff, l)
   399  
   400  	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
   401  
   402  	evm.interpreter.intPool.put(mOff, cOff, l)
   403  
   404  	return nil, nil
   405  }
   406  
   407  func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   408  	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
   409  	return nil, nil
   410  }
   411  
   412  func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   413  	num := stack.pop()
   414  
   415  	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
   416  	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
   417  		stack.push(evm.GetHash(num.Uint64()).Big())
   418  	} else {
   419  		stack.push(new(big.Int))
   420  	}
   421  
   422  	evm.interpreter.intPool.put(num, n)
   423  	return nil, nil
   424  }
   425  
   426  func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   427  	stack.push(evm.Coinbase.Big())
   428  	return nil, nil
   429  }
   430  
   431  func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   432  	stack.push(math.U256(new(big.Int).Set(evm.Time)))
   433  	return nil, nil
   434  }
   435  
   436  func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   437  	stack.push(math.U256(new(big.Int).Set(evm.BlockNumber)))
   438  	return nil, nil
   439  }
   440  
   441  func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   442  	stack.push(math.U256(new(big.Int).Set(evm.Difficulty)))
   443  	return nil, nil
   444  }
   445  
   446  func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   447  	stack.push(math.U256(new(big.Int).Set(evm.GasLimit)))
   448  	return nil, nil
   449  }
   450  
   451  func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   452  	evm.interpreter.intPool.put(stack.pop())
   453  	return nil, nil
   454  }
   455  
   456  func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   457  	offset := stack.pop()
   458  	val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32))
   459  	stack.push(val)
   460  
   461  	evm.interpreter.intPool.put(offset)
   462  	return nil, nil
   463  }
   464  
   465  func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   466  	// pop value of the stack
   467  	mStart, val := stack.pop(), stack.pop()
   468  	memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
   469  
   470  	evm.interpreter.intPool.put(mStart, val)
   471  	return nil, nil
   472  }
   473  
   474  func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   475  	off, val := stack.pop().Int64(), stack.pop().Int64()
   476  	memory.store[off] = byte(val & 0xff)
   477  
   478  	return nil, nil
   479  }
   480  
   481  func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   482  	loc := common.BigToHash(stack.pop())
   483  	val := evm.StateDB.GetState(contract.Address(), loc).Big()
   484  	stack.push(val)
   485  	return nil, nil
   486  }
   487  
   488  func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   489  	loc := common.BigToHash(stack.pop())
   490  	val := stack.pop()
   491  	evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
   492  
   493  	evm.interpreter.intPool.put(val)
   494  	return nil, nil
   495  }
   496  
   497  func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   498  	pos := stack.pop()
   499  	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   500  		nop := contract.GetOp(pos.Uint64())
   501  		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   502  	}
   503  	*pc = pos.Uint64()
   504  
   505  	evm.interpreter.intPool.put(pos)
   506  	return nil, nil
   507  }
   508  func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   509  	pos, cond := stack.pop(), stack.pop()
   510  	if cond.Sign() != 0 {
   511  		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
   512  			nop := contract.GetOp(pos.Uint64())
   513  			return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
   514  		}
   515  		*pc = pos.Uint64()
   516  	} else {
   517  		*pc++
   518  	}
   519  
   520  	evm.interpreter.intPool.put(pos, cond)
   521  	return nil, nil
   522  }
   523  func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   524  	return nil, nil
   525  }
   526  
   527  func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   528  	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
   529  	return nil, nil
   530  }
   531  
   532  func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   533  	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
   534  	return nil, nil
   535  }
   536  
   537  func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   538  	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
   539  	return nil, nil
   540  }
   541  
   542  func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   543  	var (
   544  		value        = stack.pop()
   545  		offset, size = stack.pop(), stack.pop()
   546  		input        = memory.Get(offset.Int64(), size.Int64())
   547  		gas          = contract.Gas
   548  	)
   549  	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
   550  		gas -= gas / 64
   551  	}
   552  
   553  	contract.UseGas(gas)
   554  	_, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
   555  	// Push item on the stack based on the returned error. If the ruleset is
   556  	// homestead we must check for CodeStoreOutOfGasError (homestead only
   557  	// rule) and treat as an error, if the ruleset is frontier we must
   558  	// ignore this error and pretend the operation was successful.
   559  	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
   560  		stack.push(new(big.Int))
   561  	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
   562  		stack.push(new(big.Int))
   563  	} else {
   564  		stack.push(addr.Big())
   565  	}
   566  	contract.Gas += returnGas
   567  
   568  	evm.interpreter.intPool.put(value, offset, size)
   569  
   570  	return nil, nil
   571  }
   572  
   573  func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   574  	gas := stack.pop().Uint64()
   575  	// pop gas and value of the stack.
   576  	addr, value := stack.pop(), stack.pop()
   577  	value = math.U256(value)
   578  	// pop input size and offset
   579  	inOffset, inSize := stack.pop(), stack.pop()
   580  	// pop return size and offset
   581  	retOffset, retSize := stack.pop(), stack.pop()
   582  
   583  	address := common.BigToAddress(addr)
   584  
   585  	// Get the arguments from the memory
   586  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   587  
   588  	if value.Sign() != 0 {
   589  		gas += params.CallStipend
   590  	}
   591  
   592  	ret, returnGas, err := evm.Call(contract, address, args, gas, value)
   593  	if err != nil {
   594  		stack.push(new(big.Int))
   595  	} else {
   596  		stack.push(big.NewInt(1))
   597  
   598  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   599  	}
   600  	contract.Gas += returnGas
   601  
   602  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   603  	return ret, nil
   604  }
   605  
   606  func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   607  	gas := stack.pop().Uint64()
   608  	// pop gas and value of the stack.
   609  	addr, value := stack.pop(), stack.pop()
   610  	value = math.U256(value)
   611  	// pop input size and offset
   612  	inOffset, inSize := stack.pop(), stack.pop()
   613  	// pop return size and offset
   614  	retOffset, retSize := stack.pop(), stack.pop()
   615  
   616  	address := common.BigToAddress(addr)
   617  
   618  	// Get the arguments from the memory
   619  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   620  
   621  	if value.Sign() != 0 {
   622  		gas += params.CallStipend
   623  	}
   624  
   625  	ret, returnGas, err := evm.CallCode(contract, address, args, gas, value)
   626  	if err != nil {
   627  		stack.push(new(big.Int))
   628  
   629  	} else {
   630  		stack.push(big.NewInt(1))
   631  
   632  		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
   633  	}
   634  	contract.Gas += returnGas
   635  
   636  	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
   637  	return ret, nil
   638  }
   639  
   640  func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   641  	gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
   642  
   643  	toAddr := common.BigToAddress(to)
   644  	args := memory.Get(inOffset.Int64(), inSize.Int64())
   645  
   646  	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
   647  	if err != nil {
   648  		stack.push(new(big.Int))
   649  	} else {
   650  		stack.push(big.NewInt(1))
   651  		memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
   652  	}
   653  	contract.Gas += returnGas
   654  
   655  	evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize)
   656  	return ret, nil
   657  }
   658  
   659  func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   660  	offset, size := stack.pop(), stack.pop()
   661  	ret := memory.GetPtr(offset.Int64(), size.Int64())
   662  
   663  	evm.interpreter.intPool.put(offset, size)
   664  
   665  	return ret, nil
   666  }
   667  
   668  func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   669  	return nil, nil
   670  }
   671  
   672  func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   673  	balance := evm.StateDB.GetBalance(contract.Address())
   674  	evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
   675  
   676  	evm.StateDB.Suicide(contract.Address())
   677  
   678  	return nil, nil
   679  }
   680  
   681  // following functions are used by the instruction jump  table
   682  
   683  // make log instruction function
   684  func makeLog(size int) executionFunc {
   685  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   686  		topics := make([]common.Hash, size)
   687  		mStart, mSize := stack.pop(), stack.pop()
   688  		for i := 0; i < size; i++ {
   689  			topics[i] = common.BigToHash(stack.pop())
   690  		}
   691  
   692  		d := memory.Get(mStart.Int64(), mSize.Int64())
   693  		evm.StateDB.AddLog(&types.Log{
   694  			Address: contract.Address(),
   695  			Topics:  topics,
   696  			Data:    d,
   697  			// This is a non-consensus field, but assigned here because
   698  			// core/state doesn't know the current block number.
   699  			BlockNumber: evm.BlockNumber.Uint64(),
   700  		})
   701  
   702  		evm.interpreter.intPool.put(mStart, mSize)
   703  		return nil, nil
   704  	}
   705  }
   706  
   707  // make push instruction function
   708  func makePush(size uint64, pushByteSize int) executionFunc {
   709  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   710  		codeLen := len(contract.Code)
   711  
   712  		startMin := codeLen
   713  		if int(*pc+1) < startMin {
   714  			startMin = int(*pc + 1)
   715  		}
   716  
   717  		endMin := codeLen
   718  		if startMin+pushByteSize < endMin {
   719  			endMin = startMin + pushByteSize
   720  		}
   721  
   722  		integer := evm.interpreter.intPool.get()
   723  		stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))
   724  
   725  		*pc += size
   726  		return nil, nil
   727  	}
   728  }
   729  
   730  // make push instruction function
   731  func makeDup(size int64) executionFunc {
   732  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   733  		stack.dup(evm.interpreter.intPool, int(size))
   734  		return nil, nil
   735  	}
   736  }
   737  
   738  // make swap instruction function
   739  func makeSwap(size int64) executionFunc {
   740  	// switch n + 1 otherwise n would be swapped with n
   741  	size += 1
   742  	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
   743  		stack.swap(int(size))
   744  		return nil, nil
   745  	}
   746  }