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
17package vm
18
19import (
20	"sync/atomic"
21
22	"github.com/ethereum/go-ethereum/common"
23	"github.com/ethereum/go-ethereum/core/types"
24	"github.com/ethereum/go-ethereum/params"
25	"github.com/holiman/uint256"
26	"golang.org/x/crypto/sha3"
27)
28
29func opAdd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
30	x, y := scope.Stack.pop(), scope.Stack.peek()
31	y.Add(&x, y)
32	return nil, nil
33}
34
35func opSub(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
36	x, y := scope.Stack.pop(), scope.Stack.peek()
37	y.Sub(&x, y)
38	return nil, nil
39}
40
41func opMul(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
42	x, y := scope.Stack.pop(), scope.Stack.peek()
43	y.Mul(&x, y)
44	return nil, nil
45}
46
47func opDiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
48	x, y := scope.Stack.pop(), scope.Stack.peek()
49	y.Div(&x, y)
50	return nil, nil
51}
52
53func opSdiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
54	x, y := scope.Stack.pop(), scope.Stack.peek()
55	y.SDiv(&x, y)
56	return nil, nil
57}
58
59func opMod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
60	x, y := scope.Stack.pop(), scope.Stack.peek()
61	y.Mod(&x, y)
62	return nil, nil
63}
64
65func opSmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
66	x, y := scope.Stack.pop(), scope.Stack.peek()
67	y.SMod(&x, y)
68	return nil, nil
69}
70
71func opExp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
72	base, exponent := scope.Stack.pop(), scope.Stack.peek()
73	exponent.Exp(&base, exponent)
74	return nil, nil
75}
76
77func opSignExtend(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
78	back, num := scope.Stack.pop(), scope.Stack.peek()
79	num.ExtendSign(num, &back)
80	return nil, nil
81}
82
83func opNot(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
84	x := scope.Stack.peek()
85	x.Not(x)
86	return nil, nil
87}
88
89func opLt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
90	x, y := scope.Stack.pop(), scope.Stack.peek()
91	if x.Lt(y) {
92		y.SetOne()
93	} else {
94		y.Clear()
95	}
96	return nil, nil
97}
98
99func opGt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
100	x, y := scope.Stack.pop(), scope.Stack.peek()
101	if x.Gt(y) {
102		y.SetOne()
103	} else {
104		y.Clear()
105	}
106	return nil, nil
107}
108
109func opSlt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
110	x, y := scope.Stack.pop(), scope.Stack.peek()
111	if x.Slt(y) {
112		y.SetOne()
113	} else {
114		y.Clear()
115	}
116	return nil, nil
117}
118
119func opSgt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
120	x, y := scope.Stack.pop(), scope.Stack.peek()
121	if x.Sgt(y) {
122		y.SetOne()
123	} else {
124		y.Clear()
125	}
126	return nil, nil
127}
128
129func opEq(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
130	x, y := scope.Stack.pop(), scope.Stack.peek()
131	if x.Eq(y) {
132		y.SetOne()
133	} else {
134		y.Clear()
135	}
136	return nil, nil
137}
138
139func opIszero(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
140	x := scope.Stack.peek()
141	if x.IsZero() {
142		x.SetOne()
143	} else {
144		x.Clear()
145	}
146	return nil, nil
147}
148
149func opAnd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
150	x, y := scope.Stack.pop(), scope.Stack.peek()
151	y.And(&x, y)
152	return nil, nil
153}
154
155func opOr(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
156	x, y := scope.Stack.pop(), scope.Stack.peek()
157	y.Or(&x, y)
158	return nil, nil
159}
160
161func opXor(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
162	x, y := scope.Stack.pop(), scope.Stack.peek()
163	y.Xor(&x, y)
164	return nil, nil
165}
166
167func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
168	th, val := scope.Stack.pop(), scope.Stack.peek()
169	val.Byte(&th)
170	return nil, nil
171}
172
173func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
174	x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek()
175	if z.IsZero() {
176		z.Clear()
177	} else {
178		z.AddMod(&x, &y, z)
179	}
180	return nil, nil
181}
182
183func opMulmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
184	x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek()
185	z.MulMod(&x, &y, z)
186	return nil, nil
187}
188
189// opSHL implements Shift Left
190// The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
191// and pushes on the stack arg2 shifted to the left by arg1 number of bits.
192func opSHL(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
193	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
194	shift, value := scope.Stack.pop(), scope.Stack.peek()
195	if shift.LtUint64(256) {
196		value.Lsh(value, uint(shift.Uint64()))
197	} else {
198		value.Clear()
199	}
200	return nil, nil
201}
202
203// opSHR implements Logical Shift Right
204// The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
205// and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
206func opSHR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
207	// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
208	shift, value := scope.Stack.pop(), scope.Stack.peek()
209	if shift.LtUint64(256) {
210		value.Rsh(value, uint(shift.Uint64()))
211	} else {
212		value.Clear()
213	}
214	return nil, nil
215}
216
217// opSAR implements Arithmetic Shift Right
218// The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
219// and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
220func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
221	shift, value := scope.Stack.pop(), scope.Stack.peek()
222	if shift.GtUint64(256) {
223		if value.Sign() >= 0 {
224			value.Clear()
225		} else {
226			// Max negative shift: all bits set
227			value.SetAllOne()
228		}
229		return nil, nil
230	}
231	n := uint(shift.Uint64())
232	value.SRsh(value, n)
233	return nil, nil
234}
235
236func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
237	offset, size := scope.Stack.pop(), scope.Stack.peek()
238	data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
239
240	if interpreter.hasher == nil {
241		interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState)
242	} else {
243		interpreter.hasher.Reset()
244	}
245	interpreter.hasher.Write(data)
246	interpreter.hasher.Read(interpreter.hasherBuf[:])
247
248	evm := interpreter.evm
249	if evm.Config.EnablePreimageRecording {
250		evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
251	}
252
253	size.SetBytes(interpreter.hasherBuf[:])
254	return nil, nil
255}
256func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
257	scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Address().Bytes()))
258	return nil, nil
259}
260
261func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
262	slot := scope.Stack.peek()
263	address := common.Address(slot.Bytes20())
264	slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address))
265	return nil, nil
266}
267
268func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
269	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
270	return nil, nil
271}
272func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
273	scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes()))
274	return nil, nil
275}
276
277func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
278	v, _ := uint256.FromBig(scope.Contract.value)
279	scope.Stack.push(v)
280	return nil, nil
281}
282
283func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
284	x := scope.Stack.peek()
285	if offset, overflow := x.Uint64WithOverflow(); !overflow {
286		data := getData(scope.Contract.Input, offset, 32)
287		x.SetBytes(data)
288	} else {
289		x.Clear()
290	}
291	return nil, nil
292}
293
294func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
295	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input))))
296	return nil, nil
297}
298
299func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
300	var (
301		memOffset  = scope.Stack.pop()
302		dataOffset = scope.Stack.pop()
303		length     = scope.Stack.pop()
304	)
305	dataOffset64, overflow := dataOffset.Uint64WithOverflow()
306	if overflow {
307		dataOffset64 = 0xffffffffffffffff
308	}
309	// These values are checked for overflow during gas cost calculation
310	memOffset64 := memOffset.Uint64()
311	length64 := length.Uint64()
312	scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64))
313
314	return nil, nil
315}
316
317func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
318	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
319	return nil, nil
320}
321
322func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
323	var (
324		memOffset  = scope.Stack.pop()
325		dataOffset = scope.Stack.pop()
326		length     = scope.Stack.pop()
327	)
328
329	offset64, overflow := dataOffset.Uint64WithOverflow()
330	if overflow {
331		return nil, ErrReturnDataOutOfBounds
332	}
333	// we can reuse dataOffset now (aliasing it for clarity)
334	var end = dataOffset
335	end.Add(&dataOffset, &length)
336	end64, overflow := end.Uint64WithOverflow()
337	if overflow || uint64(len(interpreter.returnData)) < end64 {
338		return nil, ErrReturnDataOutOfBounds
339	}
340	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
341	return nil, nil
342}
343
344func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
345	slot := scope.Stack.peek()
346	slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
347	return nil, nil
348}
349
350func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
351	l := new(uint256.Int)
352	l.SetUint64(uint64(len(scope.Contract.Code)))
353	scope.Stack.push(l)
354	return nil, nil
355}
356
357func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
358	var (
359		memOffset  = scope.Stack.pop()
360		codeOffset = scope.Stack.pop()
361		length     = scope.Stack.pop()
362	)
363	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
364	if overflow {
365		uint64CodeOffset = 0xffffffffffffffff
366	}
367	codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
368	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
369
370	return nil, nil
371}
372
373func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
374	var (
375		stack      = scope.Stack
376		a          = stack.pop()
377		memOffset  = stack.pop()
378		codeOffset = stack.pop()
379		length     = stack.pop()
380	)
381	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
382	if overflow {
383		uint64CodeOffset = 0xffffffffffffffff
384	}
385	addr := common.Address(a.Bytes20())
386	codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64())
387	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
388
389	return nil, nil
390}
391
392// opExtCodeHash returns the code hash of a specified account.
393// There are several cases when the function is called, while we can relay everything
394// to `state.GetCodeHash` function to ensure the correctness.
395//   (1) Caller tries to get the code hash of a normal contract account, state
396// should return the relative code hash and set it as the result.
397//
398//   (2) Caller tries to get the code hash of a non-existent account, state should
399// return common.Hash{} and zero will be set as the result.
400//
401//   (3) Caller tries to get the code hash for an account without contract code,
402// state should return emptyCodeHash(0xc5d246...) as the result.
403//
404//   (4) Caller tries to get the code hash of a precompiled account, the result
405// should be zero or emptyCodeHash.
406//
407// It is worth noting that in order to avoid unnecessary create and clean,
408// all precompile accounts on mainnet have been transferred 1 wei, so the return
409// here should be emptyCodeHash.
410// If the precompile account is not transferred any amount on a private or
411// customized chain, the return value will be zero.
412//
413//   (5) Caller tries to get the code hash for an account which is marked as suicided
414// in the current transaction, the code hash of this account should be returned.
415//
416//   (6) Caller tries to get the code hash for an account which is marked as deleted,
417// this account should be regarded as a non-existent account and zero should be returned.
418func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
419	slot := scope.Stack.peek()
420	address := common.Address(slot.Bytes20())
421	if interpreter.evm.StateDB.Empty(address) {
422		slot.Clear()
423	} else {
424		slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
425	}
426	return nil, nil
427}
428
429func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
430	v, _ := uint256.FromBig(interpreter.evm.GasPrice)
431	scope.Stack.push(v)
432	return nil, nil
433}
434
435func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
436	num := scope.Stack.peek()
437	num64, overflow := num.Uint64WithOverflow()
438	if overflow {
439		num.Clear()
440		return nil, nil
441	}
442	var upper, lower uint64
443	upper = interpreter.evm.Context.BlockNumber.Uint64()
444	if upper < 257 {
445		lower = 0
446	} else {
447		lower = upper - 256
448	}
449	if num64 >= lower && num64 < upper {
450		num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
451	} else {
452		num.Clear()
453	}
454	return nil, nil
455}
456
457func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
458	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
459	return nil, nil
460}
461
462func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
463	v, _ := uint256.FromBig(interpreter.evm.Context.Time)
464	scope.Stack.push(v)
465	return nil, nil
466}
467
468func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
469	v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber)
470	scope.Stack.push(v)
471	return nil, nil
472}
473
474func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
475	v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty)
476	scope.Stack.push(v)
477	return nil, nil
478}
479
480func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
481	scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
482	return nil, nil
483}
484
485func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
486	scope.Stack.pop()
487	return nil, nil
488}
489
490func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
491	v := scope.Stack.peek()
492	offset := int64(v.Uint64())
493	v.SetBytes(scope.Memory.GetPtr(offset, 32))
494	return nil, nil
495}
496
497func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
498	// pop value of the stack
499	mStart, val := scope.Stack.pop(), scope.Stack.pop()
500	scope.Memory.Set32(mStart.Uint64(), &val)
501	return nil, nil
502}
503
504func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
505	off, val := scope.Stack.pop(), scope.Stack.pop()
506	scope.Memory.store[off.Uint64()] = byte(val.Uint64())
507	return nil, nil
508}
509
510func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
511	loc := scope.Stack.peek()
512	hash := common.Hash(loc.Bytes32())
513	val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash)
514	loc.SetBytes(val.Bytes())
515	return nil, nil
516}
517
518func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
519	if interpreter.readOnly {
520		return nil, ErrWriteProtection
521	}
522	loc := scope.Stack.pop()
523	val := scope.Stack.pop()
524	interpreter.evm.StateDB.SetState(scope.Contract.Address(),
525		loc.Bytes32(), val.Bytes32())
526	return nil, nil
527}
528
529func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
530	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
531		return nil, errStopToken
532	}
533	pos := scope.Stack.pop()
534	if !scope.Contract.validJumpdest(&pos) {
535		return nil, ErrInvalidJump
536	}
537	*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
538	return nil, nil
539}
540
541func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
542	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
543		return nil, errStopToken
544	}
545	pos, cond := scope.Stack.pop(), scope.Stack.pop()
546	if !cond.IsZero() {
547		if !scope.Contract.validJumpdest(&pos) {
548			return nil, ErrInvalidJump
549		}
550		*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
551	}
552	return nil, nil
553}
554
555func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
556	return nil, nil
557}
558
559func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
560	scope.Stack.push(new(uint256.Int).SetUint64(*pc))
561	return nil, nil
562}
563
564func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
565	scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len())))
566	return nil, nil
567}
568
569func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
570	scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas))
571	return nil, nil
572}
573
574func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
575	if interpreter.readOnly {
576		return nil, ErrWriteProtection
577	}
578	var (
579		value        = scope.Stack.pop()
580		offset, size = scope.Stack.pop(), scope.Stack.pop()
581		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
582		gas          = scope.Contract.Gas
583	)
584	if interpreter.evm.chainRules.IsEIP150 {
585		gas -= gas / 64
586	}
587	// reuse size int for stackvalue
588	stackvalue := size
589
590	scope.Contract.UseGas(gas)
591	//TODO: use uint256.Int instead of converting with toBig()
592	var bigVal = big0
593	if !value.IsZero() {
594		bigVal = value.ToBig()
595	}
596
597	res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal)
598	// Push item on the stack based on the returned error. If the ruleset is
599	// homestead we must check for CodeStoreOutOfGasError (homestead only
600	// rule) and treat as an error, if the ruleset is frontier we must
601	// ignore this error and pretend the operation was successful.
602	if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
603		stackvalue.Clear()
604	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
605		stackvalue.Clear()
606	} else {
607		stackvalue.SetBytes(addr.Bytes())
608	}
609	scope.Stack.push(&stackvalue)
610	scope.Contract.Gas += returnGas
611
612	if suberr == ErrExecutionReverted {
613		interpreter.returnData = res // set REVERT data to return data buffer
614		return res, nil
615	}
616	interpreter.returnData = nil // clear dirty return data buffer
617	return nil, nil
618}
619
620func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
621	if interpreter.readOnly {
622		return nil, ErrWriteProtection
623	}
624	var (
625		endowment    = scope.Stack.pop()
626		offset, size = scope.Stack.pop(), scope.Stack.pop()
627		salt         = scope.Stack.pop()
628		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
629		gas          = scope.Contract.Gas
630	)
631
632	// Apply EIP150
633	gas -= gas / 64
634	scope.Contract.UseGas(gas)
635	// reuse size int for stackvalue
636	stackvalue := size
637	//TODO: use uint256.Int instead of converting with toBig()
638	bigEndowment := big0
639	if !endowment.IsZero() {
640		bigEndowment = endowment.ToBig()
641	}
642	res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas,
643		bigEndowment, &salt)
644	// Push item on the stack based on the returned error.
645	if suberr != nil {
646		stackvalue.Clear()
647	} else {
648		stackvalue.SetBytes(addr.Bytes())
649	}
650	scope.Stack.push(&stackvalue)
651	scope.Contract.Gas += returnGas
652
653	if suberr == ErrExecutionReverted {
654		interpreter.returnData = res // set REVERT data to return data buffer
655		return res, nil
656	}
657	interpreter.returnData = nil // clear dirty return data buffer
658	return nil, nil
659}
660
661func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
662	stack := scope.Stack
663	// Pop gas. The actual gas in interpreter.evm.callGasTemp.
664	// We can use this as a temporary value
665	temp := stack.pop()
666	gas := interpreter.evm.callGasTemp
667	// Pop other call parameters.
668	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
669	toAddr := common.Address(addr.Bytes20())
670	// Get the arguments from the memory.
671	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
672
673	if interpreter.readOnly && !value.IsZero() {
674		return nil, ErrWriteProtection
675	}
676	var bigVal = big0
677	//TODO: use uint256.Int instead of converting with toBig()
678	// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
679	// but it would make more sense to extend the usage of uint256.Int
680	if !value.IsZero() {
681		gas += params.CallStipend
682		bigVal = value.ToBig()
683	}
684
685	ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal)
686
687	if err != nil {
688		temp.Clear()
689	} else {
690		temp.SetOne()
691	}
692	stack.push(&temp)
693	if err == nil || err == ErrExecutionReverted {
694		ret = common.CopyBytes(ret)
695		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
696	}
697	scope.Contract.Gas += returnGas
698
699	interpreter.returnData = ret
700	return ret, nil
701}
702
703func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
704	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
705	stack := scope.Stack
706	// We use it as a temporary value
707	temp := stack.pop()
708	gas := interpreter.evm.callGasTemp
709	// Pop other call parameters.
710	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
711	toAddr := common.Address(addr.Bytes20())
712	// Get arguments from the memory.
713	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
714
715	//TODO: use uint256.Int instead of converting with toBig()
716	var bigVal = big0
717	if !value.IsZero() {
718		gas += params.CallStipend
719		bigVal = value.ToBig()
720	}
721
722	ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal)
723	if err != nil {
724		temp.Clear()
725	} else {
726		temp.SetOne()
727	}
728	stack.push(&temp)
729	if err == nil || err == ErrExecutionReverted {
730		ret = common.CopyBytes(ret)
731		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
732	}
733	scope.Contract.Gas += returnGas
734
735	interpreter.returnData = ret
736	return ret, nil
737}
738
739func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
740	stack := scope.Stack
741	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
742	// We use it as a temporary value
743	temp := stack.pop()
744	gas := interpreter.evm.callGasTemp
745	// Pop other call parameters.
746	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
747	toAddr := common.Address(addr.Bytes20())
748	// Get arguments from the memory.
749	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
750
751	ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
752	if err != nil {
753		temp.Clear()
754	} else {
755		temp.SetOne()
756	}
757	stack.push(&temp)
758	if err == nil || err == ErrExecutionReverted {
759		ret = common.CopyBytes(ret)
760		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
761	}
762	scope.Contract.Gas += returnGas
763
764	interpreter.returnData = ret
765	return ret, nil
766}
767
768func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
769	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
770	stack := scope.Stack
771	// We use it as a temporary value
772	temp := stack.pop()
773	gas := interpreter.evm.callGasTemp
774	// Pop other call parameters.
775	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
776	toAddr := common.Address(addr.Bytes20())
777	// Get arguments from the memory.
778	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
779
780	ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
781	if err != nil {
782		temp.Clear()
783	} else {
784		temp.SetOne()
785	}
786	stack.push(&temp)
787	if err == nil || err == ErrExecutionReverted {
788		ret = common.CopyBytes(ret)
789		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
790	}
791	scope.Contract.Gas += returnGas
792
793	interpreter.returnData = ret
794	return ret, nil
795}
796
797func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
798	offset, size := scope.Stack.pop(), scope.Stack.pop()
799	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
800
801	return ret, errStopToken
802}
803
804func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
805	offset, size := scope.Stack.pop(), scope.Stack.pop()
806	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
807
808	interpreter.returnData = ret
809	return ret, ErrExecutionReverted
810}
811
812func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
813	return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])}
814}
815
816func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
817	return nil, errStopToken
818}
819
820func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
821	if interpreter.readOnly {
822		return nil, ErrWriteProtection
823	}
824	beneficiary := scope.Stack.pop()
825	balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
826	interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance)
827	interpreter.evm.StateDB.Suicide(scope.Contract.Address())
828	if interpreter.cfg.Debug {
829		interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance)
830		interpreter.cfg.Tracer.CaptureExit([]byte{}, 0, nil)
831	}
832	return nil, errStopToken
833}
834
835// following functions are used by the instruction jump  table
836
837// make log instruction function
838func makeLog(size int) executionFunc {
839	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
840		if interpreter.readOnly {
841			return nil, ErrWriteProtection
842		}
843		topics := make([]common.Hash, size)
844		stack := scope.Stack
845		mStart, mSize := stack.pop(), stack.pop()
846		for i := 0; i < size; i++ {
847			addr := stack.pop()
848			topics[i] = addr.Bytes32()
849		}
850
851		d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
852		interpreter.evm.StateDB.AddLog(&types.Log{
853			Address: scope.Contract.Address(),
854			Topics:  topics,
855			Data:    d,
856			// This is a non-consensus field, but assigned here because
857			// core/state doesn't know the current block number.
858			BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
859		})
860
861		return nil, nil
862	}
863}
864
865// opPush1 is a specialized version of pushN
866func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
867	var (
868		codeLen = uint64(len(scope.Contract.Code))
869		integer = new(uint256.Int)
870	)
871	*pc += 1
872	if *pc < codeLen {
873		scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc])))
874	} else {
875		scope.Stack.push(integer.Clear())
876	}
877	return nil, nil
878}
879
880// make push instruction function
881func makePush(size uint64, pushByteSize int) executionFunc {
882	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
883		codeLen := len(scope.Contract.Code)
884
885		startMin := codeLen
886		if int(*pc+1) < startMin {
887			startMin = int(*pc + 1)
888		}
889
890		endMin := codeLen
891		if startMin+pushByteSize < endMin {
892			endMin = startMin + pushByteSize
893		}
894
895		integer := new(uint256.Int)
896		scope.Stack.push(integer.SetBytes(common.RightPadBytes(
897			scope.Contract.Code[startMin:endMin], pushByteSize)))
898
899		*pc += size
900		return nil, nil
901	}
902}
903
904// make dup instruction function
905func makeDup(size int64) executionFunc {
906	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
907		scope.Stack.dup(int(size))
908		return nil, nil
909	}
910}
911
912// make swap instruction function
913func makeSwap(size int64) executionFunc {
914	// switch n + 1 otherwise n would be swapped with n
915	size++
916	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
917		scope.Stack.swap(int(size))
918		return nil, nil
919	}
920}
921