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