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