instructions.go 29 KB
Newer Older
1
// Copyright 2015 The go-ethereum Authors
2 3 4 5 6 7 8 9 10 11 12 13 14 15
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16

17 18 19
package vm

import (
20 21
	"sync/atomic"

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
)

29 30
func opAdd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
31
	y.Add(&x, y)
32
	return nil, nil
33 34
}

35 36
func opSub(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
37
	y.Sub(&x, y)
38
	return nil, nil
39 40
}

41 42
func opMul(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
43
	y.Mul(&x, y)
44
	return nil, nil
45 46
}

47 48
func opDiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
49
	y.Div(&x, y)
50
	return nil, nil
51 52
}

53 54
func opSdiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
55
	y.SDiv(&x, y)
56
	return nil, nil
57 58
}

59 60
func opMod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
61
	y.Mod(&x, y)
62
	return nil, nil
63 64
}

65 66
func opSmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
67
	y.SMod(&x, y)
68
	return nil, nil
69 70
}

71 72
func opExp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	base, exponent := scope.Stack.pop(), scope.Stack.peek()
73
	exponent.Exp(&base, exponent)
74
	return nil, nil
75 76
}

77 78
func opSignExtend(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	back, num := scope.Stack.pop(), scope.Stack.peek()
79
	num.ExtendSign(num, &back)
80
	return nil, nil
81 82
}

83 84
func opNot(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x := scope.Stack.peek()
85
	x.Not(x)
86
	return nil, nil
87 88
}

89 90
func opLt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
91 92
	if x.Lt(y) {
		y.SetOne()
93
	} else {
94
		y.Clear()
95
	}
96
	return nil, nil
97 98
}

99 100
func opGt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
101 102
	if x.Gt(y) {
		y.SetOne()
103
	} else {
104
		y.Clear()
105
	}
106
	return nil, nil
107 108
}

109 110
func opSlt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
111 112 113 114
	if x.Slt(y) {
		y.SetOne()
	} else {
		y.Clear()
115
	}
116
	return nil, nil
117 118
}

119 120
func opSgt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
121 122 123 124
	if x.Sgt(y) {
		y.SetOne()
	} else {
		y.Clear()
125
	}
126
	return nil, nil
127 128
}

129 130
func opEq(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
131 132
	if x.Eq(y) {
		y.SetOne()
133
	} else {
134
		y.Clear()
135
	}
136
	return nil, nil
137 138
}

139 140
func opIszero(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x := scope.Stack.peek()
141 142
	if x.IsZero() {
		x.SetOne()
143
	} else {
144
		x.Clear()
145
	}
146
	return nil, nil
147 148
}

149 150
func opAnd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
151
	y.And(&x, y)
152
	return nil, nil
153
}
154

155 156
func opOr(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
157
	y.Or(&x, y)
158
	return nil, nil
159
}
160

161 162
func opXor(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y := scope.Stack.pop(), scope.Stack.peek()
163
	y.Xor(&x, y)
164
	return nil, nil
165
}
166

167 168
func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	th, val := scope.Stack.pop(), scope.Stack.peek()
169
	val.Byte(&th)
170
	return nil, nil
171
}
172

173 174
func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek()
175 176
	if z.IsZero() {
		z.Clear()
177
	} else {
178
		z.AddMod(&x, &y, z)
179
	}
180
	return nil, nil
181
}
182

183 184
func opMulmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	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 190 191
// opSHL implements Shift Left
// The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the left by arg1 number of bits.
192
func 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 196 197 198
	if shift.LtUint64(256) {
		value.Lsh(value, uint(shift.Uint64()))
	} else {
		value.Clear()
199 200 201 202 203 204 205
	}
	return nil, nil
}

// opSHR implements Logical Shift Right
// The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
206
func 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 210 211 212
	if shift.LtUint64(256) {
		value.Rsh(value, uint(shift.Uint64()))
	} else {
		value.Clear()
213 214 215 216 217 218 219
	}
	return nil, nil
}

// opSAR implements Arithmetic Shift Right
// The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
220 221
func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	shift, value := scope.Stack.pop(), scope.Stack.peek()
222
	if shift.GtUint64(256) {
223
		if value.Sign() >= 0 {
224
			value.Clear()
225
		} else {
226 227
			// Max negative shift: all bits set
			value.SetAllOne()
228 229 230 231
		}
		return nil, nil
	}
	n := uint(shift.Uint64())
232
	value.SRsh(value, n)
233 234 235
	return nil, nil
}

236
func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
237 238
	offset, size := scope.Stack.pop(), scope.Stack.peek()
	data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
239

240
	if interpreter.hasher == nil {
241
		interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState)
242 243 244 245 246 247 248
	} else {
		interpreter.hasher.Reset()
	}
	interpreter.hasher.Write(data)
	interpreter.hasher.Read(interpreter.hasherBuf[:])

	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
}
256 257
func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Address().Bytes()))
258
	return nil, nil
259 260
}

261 262
func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	slot := scope.Stack.peek()
263 264
	address := common.Address(slot.Bytes20())
	slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address))
265
	return nil, nil
266 267
}

268 269
func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
270
	return nil, nil
271
}
272 273
func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes()))
274
	return nil, nil
275 276
}

277 278 279
func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	v, _ := uint256.FromBig(scope.Contract.value)
	scope.Stack.push(v)
280
	return nil, nil
281 282
}

283 284
func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	x := scope.Stack.peek()
285
	if offset, overflow := x.Uint64WithOverflow(); !overflow {
286
		data := getData(scope.Contract.Input, offset, 32)
287 288 289 290
		x.SetBytes(data)
	} else {
		x.Clear()
	}
291
	return nil, nil
292 293
}

294 295
func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input))))
296
	return nil, nil
297 298
}

299
func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
300
	var (
301 302 303
		memOffset  = scope.Stack.pop()
		dataOffset = scope.Stack.pop()
		length     = scope.Stack.pop()
304
	)
305 306 307 308 309 310 311
	dataOffset64, overflow := dataOffset.Uint64WithOverflow()
	if overflow {
		dataOffset64 = 0xffffffffffffffff
	}
	// These values are checked for overflow during gas cost calculation
	memOffset64 := memOffset.Uint64()
	length64 := length.Uint64()
312
	scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64))
313

314
	return nil, nil
315 316
}

317 318
func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
319 320 321
	return nil, nil
}

322
func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
323
	var (
324 325 326
		memOffset  = scope.Stack.pop()
		dataOffset = scope.Stack.pop()
		length     = scope.Stack.pop()
327 328
	)

329 330
	offset64, overflow := dataOffset.Uint64WithOverflow()
	if overflow {
331
		return nil, ErrReturnDataOutOfBounds
332
	}
333 334 335 336 337 338 339
	// we can reuse dataOffset now (aliasing it for clarity)
	var end = dataOffset
	end.Add(&dataOffset, &length)
	end64, overflow := end.Uint64WithOverflow()
	if overflow || uint64(len(interpreter.returnData)) < end64 {
		return nil, ErrReturnDataOutOfBounds
	}
340
	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
341 342 343
	return nil, nil
}

344 345
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	slot := scope.Stack.peek()
346
	slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
347
	return nil, nil
348 349
}

350
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
351
	l := new(uint256.Int)
352 353
	l.SetUint64(uint64(len(scope.Contract.Code)))
	scope.Stack.push(l)
354
	return nil, nil
355 356
}

357
func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
358
	var (
359 360 361
		memOffset  = scope.Stack.pop()
		codeOffset = scope.Stack.pop()
		length     = scope.Stack.pop()
362
	)
363 364 365 366
	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
	if overflow {
		uint64CodeOffset = 0xffffffffffffffff
	}
367 368
	codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
	scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
369

370
	return nil, nil
371 372
}

373
func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
374
	var (
375
		stack      = scope.Stack
376 377 378 379
		a          = stack.pop()
		memOffset  = stack.pop()
		codeOffset = stack.pop()
		length     = stack.pop()
380
	)
381 382 383 384 385 386
	uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
	if overflow {
		uint64CodeOffset = 0xffffffffffffffff
	}
	addr := common.Address(a.Bytes20())
	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 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
// opExtCodeHash returns the code hash of a specified account.
// There are several cases when the function is called, while we can relay everything
// to `state.GetCodeHash` function to ensure the correctness.
//   (1) Caller tries to get the code hash of a normal contract account, state
// should return the relative code hash and set it as the result.
//
//   (2) Caller tries to get the code hash of a non-existent account, state should
// return common.Hash{} and zero will be set as the result.
//
//   (3) Caller tries to get the code hash for an account without contract code,
// state should return emptyCodeHash(0xc5d246...) as the result.
//
//   (4) Caller tries to get the code hash of a precompiled account, the result
// should be zero or emptyCodeHash.
//
// It is worth noting that in order to avoid unnecessary create and clean,
// all precompile accounts on mainnet have been transferred 1 wei, so the return
// here should be emptyCodeHash.
// If the precompile account is not transferred any amount on a private or
// customized chain, the return value will be zero.
//
//   (5) Caller tries to get the code hash for an account which is marked as suicided
// in the current transaction, the code hash of this account should be returned.
//
//   (6) Caller tries to get the code hash for an account which is marked as deleted,
// this account should be regarded as a non-existent account and zero should be returned.
418 419
func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	slot := scope.Stack.peek()
420
	address := common.Address(slot.Bytes20())
421
	if interpreter.evm.StateDB.Empty(address) {
422
		slot.Clear()
423 424 425
	} else {
		slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
	}
426 427 428
	return nil, nil
}

429
func 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
}

435 436
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	num := scope.Stack.peek()
437 438 439 440 441 442
	num64, overflow := num.Uint64WithOverflow()
	if overflow {
		num.Clear()
		return nil, nil
	}
	var upper, lower uint64
443
	upper = interpreter.evm.Context.BlockNumber.Uint64()
444 445
	if upper < 257 {
		lower = 0
446
	} else {
447 448 449
		lower = upper - 256
	}
	if num64 >= lower && num64 < upper {
450
		num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes())
451 452
	} else {
		num.Clear()
453
	}
454
	return nil, nil
455 456
}

457 458
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
459
	return nil, nil
460 461
}

462
func 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
}

468
func 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
}

474
func 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
}

480 481 482 483 484 485
func opRandom(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	v := new(uint256.Int).SetBytes((interpreter.evm.Context.Random.Bytes()))
	scope.Stack.push(v)
	return nil, nil
}

486 487
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
488
	return nil, nil
489 490
}

491 492
func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.pop()
493
	return nil, nil
494 495
}

496 497
func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	v := scope.Stack.peek()
498
	offset := int64(v.Uint64())
499
	v.SetBytes(scope.Memory.GetPtr(offset, 32))
500
	return nil, nil
501 502
}

503
func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
504
	// pop value of the stack
505 506
	mStart, val := scope.Stack.pop(), scope.Stack.pop()
	scope.Memory.Set32(mStart.Uint64(), &val)
507
	return nil, nil
508 509
}

510 511 512
func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	off, val := scope.Stack.pop(), scope.Stack.pop()
	scope.Memory.store[off.Uint64()] = byte(val.Uint64())
513
	return nil, nil
514 515
}

516 517
func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	loc := scope.Stack.peek()
518
	hash := common.Hash(loc.Bytes32())
519
	val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash)
520
	loc.SetBytes(val.Bytes())
521
	return nil, nil
522 523
}

524
func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
525 526 527
	if interpreter.readOnly {
		return nil, ErrWriteProtection
	}
528 529 530
	loc := scope.Stack.pop()
	val := scope.Stack.pop()
	interpreter.evm.StateDB.SetState(scope.Contract.Address(),
531
		loc.Bytes32(), val.Bytes32())
532
	return nil, nil
533 534
}

535
func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
536 537 538
	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
		return nil, errStopToken
	}
539 540
	pos := scope.Stack.pop()
	if !scope.Contract.validJumpdest(&pos) {
541
		return nil, ErrInvalidJump
542
	}
543
	*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
544
	return nil, nil
545
}
546

547
func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
548 549 550
	if atomic.LoadInt32(&interpreter.evm.abort) != 0 {
		return nil, errStopToken
	}
551
	pos, cond := scope.Stack.pop(), scope.Stack.pop()
552
	if !cond.IsZero() {
553
		if !scope.Contract.validJumpdest(&pos) {
554
			return nil, ErrInvalidJump
555
		}
556
		*pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop
557 558
	}
	return nil, nil
559
}
560

561
func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
562
	return nil, nil
563
}
564

565 566
func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(*pc))
567
	return nil, nil
568 569
}

570 571
func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len())))
572
	return nil, nil
573 574
}

575 576
func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas))
577
	return nil, nil
578 579
}

580
func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
581 582 583
	if interpreter.readOnly {
		return nil, ErrWriteProtection
	}
584
	var (
585 586 587 588
		value        = scope.Stack.pop()
		offset, size = scope.Stack.pop(), scope.Stack.pop()
		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
		gas          = scope.Contract.Gas
589
	)
590
	if interpreter.evm.chainRules.IsEIP150 {
591
		gas -= gas / 64
592
	}
593 594
	// reuse size int for stackvalue
	stackvalue := size
595

596
	scope.Contract.UseGas(gas)
597 598 599 600 601 602
	//TODO: use uint256.Int instead of converting with toBig()
	var bigVal = big0
	if !value.IsZero() {
		bigVal = value.ToBig()
	}

603
	res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal)
604 605 606 607
	// Push item on the stack based on the returned error. If the ruleset is
	// homestead we must check for CodeStoreOutOfGasError (homestead only
	// rule) and treat as an error, if the ruleset is frontier we must
	// ignore this error and pretend the operation was successful.
608
	if interpreter.evm.chainRules.IsHomestead && suberr == ErrCodeStoreOutOfGas {
609
		stackvalue.Clear()
610
	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
611
		stackvalue.Clear()
612
	} else {
613
		stackvalue.SetBytes(addr.Bytes())
614
	}
615 616
	scope.Stack.push(&stackvalue)
	scope.Contract.Gas += returnGas
617

618
	if suberr == ErrExecutionReverted {
619
		interpreter.returnData = res // set REVERT data to return data buffer
620 621
		return res, nil
	}
622
	interpreter.returnData = nil // clear dirty return data buffer
623
	return nil, nil
624 625
}

626
func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
627 628 629
	if interpreter.readOnly {
		return nil, ErrWriteProtection
	}
630
	var (
631 632 633 634 635
		endowment    = scope.Stack.pop()
		offset, size = scope.Stack.pop(), scope.Stack.pop()
		salt         = scope.Stack.pop()
		input        = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
		gas          = scope.Contract.Gas
636 637 638 639
	)

	// Apply EIP150
	gas -= gas / 64
640
	scope.Contract.UseGas(gas)
641 642
	// reuse size int for stackvalue
	stackvalue := size
643 644 645 646 647
	//TODO: use uint256.Int instead of converting with toBig()
	bigEndowment := big0
	if !endowment.IsZero() {
		bigEndowment = endowment.ToBig()
	}
648
	res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas,
649
		bigEndowment, &salt)
650 651
	// Push item on the stack based on the returned error.
	if suberr != nil {
652
		stackvalue.Clear()
653
	} else {
654
		stackvalue.SetBytes(addr.Bytes())
655
	}
656 657
	scope.Stack.push(&stackvalue)
	scope.Contract.Gas += returnGas
658

659
	if suberr == ErrExecutionReverted {
660
		interpreter.returnData = res // set REVERT data to return data buffer
661 662
		return res, nil
	}
663
	interpreter.returnData = nil // clear dirty return data buffer
664 665 666
	return nil, nil
}

667 668
func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	stack := scope.Stack
669
	// Pop gas. The actual gas in interpreter.evm.callGasTemp.
670 671
	// We can use this as a temporary value
	temp := stack.pop()
672
	gas := interpreter.evm.callGasTemp
673
	// Pop other call parameters.
674 675
	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
	toAddr := common.Address(addr.Bytes20())
676
	// Get the arguments from the memory.
677
	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
678

679 680 681
	if interpreter.readOnly && !value.IsZero() {
		return nil, ErrWriteProtection
	}
682 683 684 685
	var bigVal = big0
	//TODO: use uint256.Int instead of converting with toBig()
	// By using big0 here, we save an alloc for the most common case (non-ether-transferring contract calls),
	// but it would make more sense to extend the usage of uint256.Int
686
	if !value.IsZero() {
687
		gas += params.CallStipend
688
		bigVal = value.ToBig()
689
	}
690

691
	ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal)
692

693
	if err != nil {
694
		temp.Clear()
695
	} else {
696
		temp.SetOne()
697
	}
698
	stack.push(&temp)
699
	if err == nil || err == ErrExecutionReverted {
700
		ret = common.CopyBytes(ret)
701
		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
702
	}
703
	scope.Contract.Gas += returnGas
704

705
	interpreter.returnData = ret
706
	return ret, nil
707 708
}

709
func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
710
	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
711
	stack := scope.Stack
712 713
	// We use it as a temporary value
	temp := stack.pop()
714
	gas := interpreter.evm.callGasTemp
715
	// Pop other call parameters.
716 717
	addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
	toAddr := common.Address(addr.Bytes20())
718
	// Get arguments from the memory.
719
	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
720

721 722
	//TODO: use uint256.Int instead of converting with toBig()
	var bigVal = big0
723
	if !value.IsZero() {
724
		gas += params.CallStipend
725
		bigVal = value.ToBig()
726
	}
727

728
	ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal)
729
	if err != nil {
730
		temp.Clear()
731
	} else {
732
		temp.SetOne()
733
	}
734
	stack.push(&temp)
735
	if err == nil || err == ErrExecutionReverted {
736
		ret = common.CopyBytes(ret)
737
		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
738
	}
739
	scope.Contract.Gas += returnGas
740

741
	interpreter.returnData = ret
742
	return ret, nil
743 744
}

745 746
func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	stack := scope.Stack
747
	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
748 749
	// We use it as a temporary value
	temp := stack.pop()
750
	gas := interpreter.evm.callGasTemp
751
	// Pop other call parameters.
752 753
	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
	toAddr := common.Address(addr.Bytes20())
754
	// Get arguments from the memory.
755
	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
756

757
	ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
758
	if err != nil {
759
		temp.Clear()
760
	} else {
761
		temp.SetOne()
762
	}
763
	stack.push(&temp)
764
	if err == nil || err == ErrExecutionReverted {
765
		ret = common.CopyBytes(ret)
766
		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
767
	}
768
	scope.Contract.Gas += returnGas
769

770
	interpreter.returnData = ret
771
	return ret, nil
772 773
}

774
func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
775
	// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
776
	stack := scope.Stack
777 778
	// We use it as a temporary value
	temp := stack.pop()
779
	gas := interpreter.evm.callGasTemp
780
	// Pop other call parameters.
781 782
	addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
	toAddr := common.Address(addr.Bytes20())
783
	// Get arguments from the memory.
784
	args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
785

786
	ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
787
	if err != nil {
788
		temp.Clear()
789
	} else {
790
		temp.SetOne()
791
	}
792
	stack.push(&temp)
793
	if err == nil || err == ErrExecutionReverted {
794
		ret = common.CopyBytes(ret)
795
		scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
796
	}
797
	scope.Contract.Gas += returnGas
798

799
	interpreter.returnData = ret
800 801 802
	return ret, nil
}

803 804 805
func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	offset, size := scope.Stack.pop(), scope.Stack.pop()
	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
806

807
	return ret, errStopToken
808
}
809

810 811 812
func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	offset, size := scope.Stack.pop(), scope.Stack.pop()
	ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
813

814 815
	interpreter.returnData = ret
	return ret, ErrExecutionReverted
816
}
817

818 819 820 821
func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
	return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])}
}

822
func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
823
	return nil, errStopToken
824 825
}

826
func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
827 828 829
	if interpreter.readOnly {
		return nil, ErrWriteProtection
	}
830 831
	beneficiary := scope.Stack.pop()
	balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
832
	interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance)
833
	interpreter.evm.StateDB.Suicide(scope.Contract.Address())
834 835 836 837
	if interpreter.cfg.Debug {
		interpreter.cfg.Tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance)
		interpreter.cfg.Tracer.CaptureExit([]byte{}, 0, nil)
	}
838
	return nil, errStopToken
839 840 841 842 843
}

// following functions are used by the instruction jump  table

// make log instruction function
844
func makeLog(size int) executionFunc {
845
	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
846 847 848
		if interpreter.readOnly {
			return nil, ErrWriteProtection
		}
849
		topics := make([]common.Hash, size)
850
		stack := scope.Stack
851
		mStart, mSize := stack.pop(), stack.pop()
852
		for i := 0; i < size; i++ {
853
			addr := stack.pop()
854
			topics[i] = addr.Bytes32()
855 856
		}

857
		d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
858
		interpreter.evm.StateDB.AddLog(&types.Log{
859
			Address: scope.Contract.Address(),
860 861 862 863
			Topics:  topics,
			Data:    d,
			// This is a non-consensus field, but assigned here because
			// core/state doesn't know the current block number.
864
			BlockNumber: interpreter.evm.Context.BlockNumber.Uint64(),
865
		})
866

867
		return nil, nil
868 869
	}
}
870

871
// opPush1 is a specialized version of pushN
872
func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
873
	var (
874
		codeLen = uint64(len(scope.Contract.Code))
875
		integer = new(uint256.Int)
876 877 878
	)
	*pc += 1
	if *pc < codeLen {
879
		scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc])))
880
	} else {
881
		scope.Stack.push(integer.Clear())
882 883 884 885
	}
	return nil, nil
}

886
// make push instruction function
887
func makePush(size uint64, pushByteSize int) executionFunc {
888 889
	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
		codeLen := len(scope.Contract.Code)
890 891 892 893 894 895 896 897 898 899 900

		startMin := codeLen
		if int(*pc+1) < startMin {
			startMin = int(*pc + 1)
		}

		endMin := codeLen
		if startMin+pushByteSize < endMin {
			endMin = startMin + pushByteSize
		}

901
		integer := new(uint256.Int)
902 903
		scope.Stack.push(integer.SetBytes(common.RightPadBytes(
			scope.Contract.Code[startMin:endMin], pushByteSize)))
904

905
		*pc += size
906
		return nil, nil
907 908
	}
}
909

910
// make dup instruction function
911
func makeDup(size int64) executionFunc {
912 913
	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
		scope.Stack.dup(int(size))
914
		return nil, nil
915 916
	}
}
917

918
// make swap instruction function
919
func makeSwap(size int64) executionFunc {
920
	// switch n + 1 otherwise n would be swapped with n
921
	size++
922 923
	return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
		scope.Stack.swap(int(size))
924
		return nil, nil
925
	}
926
}