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