github.com/luckypickle/go-ethereum-vet@v1.14.2/core/vm/instructions.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 24 "github.com/luckypickle/go-ethereum-vet/common" 25 "github.com/luckypickle/go-ethereum-vet/common/math" 26 "github.com/luckypickle/go-ethereum-vet/core/types" 27 "github.com/luckypickle/go-ethereum-vet/crypto" 28 "github.com/luckypickle/go-ethereum-vet/params" 29 ) 30 31 var ( 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 40 func 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 48 func 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 56 func 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 65 func 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 76 func 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 95 func 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 106 func 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 125 func 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 134 func 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 154 func 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 160 func 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 171 func 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 182 func 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 206 func 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 230 func 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 241 func 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 251 func 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 259 func 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 267 func 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 275 func 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 287 func 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 300 func 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. 316 func 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. 334 func 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. 352 func 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 373 func 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 388 func 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 393 func 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 399 func 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 404 func 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 409 func 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 414 func 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 419 func 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 424 func 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 436 func 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 441 func 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 459 func 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 466 func 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 473 func 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 486 func 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 // 504 // (1) Caller tries to get the code hash of a normal contract account, state 505 // 506 // should return the relative code hash and set it as the result. 507 // 508 // (2) Caller tries to get the code hash of a non-existent account, state should 509 // 510 // return common.Hash{} and zero will be set as the result. 511 // 512 // (3) Caller tries to get the code hash for an account without contract code, 513 // 514 // state should return emptyCodeHash(0xc5d246...) as the result. 515 // 516 // (4) Caller tries to get the code hash of a precompiled account, the result 517 // 518 // should be zero or emptyCodeHash. 519 // 520 // It is worth noting that in order to avoid unnecessary create and clean, 521 // all precompile accounts on mainnet have been transferred 1 wei, so the return 522 // here should be emptyCodeHash. 523 // If the precompile account is not transferred any amount on a private or 524 // customized chain, the return value will be zero. 525 // 526 // (5) Caller tries to get the code hash for an account which is marked as suicided 527 // 528 // in the current transaction, the code hash of this account should be returned. 529 // 530 // (6) Caller tries to get the code hash for an account which is marked as deleted, 531 // 532 // this account should be regarded as a non-existent account and zero should be returned. 533 func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 534 slot := stack.peek() 535 slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(common.BigToAddress(slot)).Bytes()) 536 return nil, nil 537 } 538 539 func opGasprice(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 540 stack.push(interpreter.intPool.get().Set(interpreter.evm.GasPrice)) 541 return nil, nil 542 } 543 544 func opBlockhash(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 545 num := stack.pop() 546 547 n := interpreter.intPool.get().Sub(interpreter.evm.BlockNumber, common.Big257) 548 if num.Cmp(n) > 0 && num.Cmp(interpreter.evm.BlockNumber) < 0 { 549 stack.push(interpreter.evm.GetHash(num.Uint64()).Big()) 550 } else { 551 stack.push(interpreter.intPool.getZero()) 552 } 553 interpreter.intPool.put(num, n) 554 return nil, nil 555 } 556 557 func opCoinbase(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 558 stack.push(interpreter.evm.Coinbase.Big()) 559 return nil, nil 560 } 561 562 func opTimestamp(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 563 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Time))) 564 return nil, nil 565 } 566 567 func opNumber(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 568 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.BlockNumber))) 569 return nil, nil 570 } 571 572 func opDifficulty(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 573 stack.push(math.U256(interpreter.intPool.get().Set(interpreter.evm.Difficulty))) 574 return nil, nil 575 } 576 577 func opGasLimit(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 578 stack.push(math.U256(interpreter.intPool.get().SetUint64(interpreter.evm.GasLimit))) 579 return nil, nil 580 } 581 582 func opPop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 583 interpreter.intPool.put(stack.pop()) 584 return nil, nil 585 } 586 587 func opMload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 588 offset := stack.pop() 589 val := interpreter.intPool.get().SetBytes(memory.Get(offset.Int64(), 32)) 590 stack.push(val) 591 592 interpreter.intPool.put(offset) 593 return nil, nil 594 } 595 596 func opMstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 597 // pop value of the stack 598 mStart, val := stack.pop(), stack.pop() 599 memory.Set32(mStart.Uint64(), val) 600 601 interpreter.intPool.put(mStart, val) 602 return nil, nil 603 } 604 605 func opMstore8(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 606 off, val := stack.pop().Int64(), stack.pop().Int64() 607 memory.store[off] = byte(val & 0xff) 608 609 return nil, nil 610 } 611 612 func opSload(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 613 loc := stack.peek() 614 val := interpreter.evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) 615 loc.SetBytes(val.Bytes()) 616 return nil, nil 617 } 618 619 func opSstore(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 620 loc := common.BigToHash(stack.pop()) 621 val := stack.pop() 622 interpreter.evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 623 624 interpreter.intPool.put(val) 625 return nil, nil 626 } 627 628 func opJump(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 629 pos := stack.pop() 630 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 631 nop := contract.GetOp(pos.Uint64()) 632 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 633 } 634 *pc = pos.Uint64() 635 636 interpreter.intPool.put(pos) 637 return nil, nil 638 } 639 640 func opJumpi(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 641 pos, cond := stack.pop(), stack.pop() 642 if cond.Sign() != 0 { 643 if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) { 644 nop := contract.GetOp(pos.Uint64()) 645 return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos) 646 } 647 *pc = pos.Uint64() 648 } else { 649 *pc++ 650 } 651 652 interpreter.intPool.put(pos, cond) 653 return nil, nil 654 } 655 656 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 657 return nil, nil 658 } 659 660 func opPc(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 661 stack.push(interpreter.intPool.get().SetUint64(*pc)) 662 return nil, nil 663 } 664 665 func opMsize(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 666 stack.push(interpreter.intPool.get().SetInt64(int64(memory.Len()))) 667 return nil, nil 668 } 669 670 func opGas(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 671 stack.push(interpreter.intPool.get().SetUint64(contract.Gas)) 672 return nil, nil 673 } 674 675 func opCreate(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 676 var ( 677 value = stack.pop() 678 offset, size = stack.pop(), stack.pop() 679 input = memory.Get(offset.Int64(), size.Int64()) 680 gas = contract.Gas 681 ) 682 if interpreter.evm.ChainConfig().IsEIP150(interpreter.evm.BlockNumber) { 683 gas -= gas / 64 684 } 685 686 contract.UseGas(gas) 687 res, addr, returnGas, suberr := interpreter.evm.Create(contract, input, gas, value) 688 // Push item on the stack based on the returned error. If the ruleset is 689 // homestead we must check for CodeStoreOutOfGasError (homestead only 690 // rule) and treat as an error, if the ruleset is frontier we must 691 // ignore this error and pretend the operation was successful. 692 if interpreter.evm.ChainConfig().IsHomestead(interpreter.evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas { 693 stack.push(interpreter.intPool.getZero()) 694 } else if suberr != nil && suberr != ErrCodeStoreOutOfGas { 695 stack.push(interpreter.intPool.getZero()) 696 } else { 697 stack.push(addr.Big()) 698 } 699 contract.Gas += returnGas 700 interpreter.intPool.put(value, offset, size) 701 702 if suberr == errExecutionReverted { 703 return res, nil 704 } 705 return nil, nil 706 } 707 708 func opCreate2(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 709 var ( 710 endowment = stack.pop() 711 offset, size = stack.pop(), stack.pop() 712 salt = stack.pop() 713 input = memory.Get(offset.Int64(), size.Int64()) 714 gas = contract.Gas 715 ) 716 717 // Apply EIP150 718 gas -= gas / 64 719 contract.UseGas(gas) 720 res, addr, returnGas, suberr := interpreter.evm.Create2(contract, input, gas, endowment, salt) 721 // Push item on the stack based on the returned error. 722 if suberr != nil { 723 stack.push(interpreter.intPool.getZero()) 724 } else { 725 stack.push(addr.Big()) 726 } 727 contract.Gas += returnGas 728 interpreter.intPool.put(endowment, offset, size, salt) 729 730 if suberr == errExecutionReverted { 731 return res, nil 732 } 733 return nil, nil 734 } 735 736 func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 737 // Pop gas. The actual gas in in interpreter.evm.callGasTemp. 738 interpreter.intPool.put(stack.pop()) 739 gas := interpreter.evm.callGasTemp 740 // Pop other call parameters. 741 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 742 toAddr := common.BigToAddress(addr) 743 value = math.U256(value) 744 // Get the arguments from the memory. 745 args := memory.Get(inOffset.Int64(), inSize.Int64()) 746 747 if value.Sign() != 0 { 748 gas += params.CallStipend 749 } 750 ret, returnGas, err := interpreter.evm.Call(contract, toAddr, args, gas, value) 751 if err != nil { 752 stack.push(interpreter.intPool.getZero()) 753 } else { 754 stack.push(interpreter.intPool.get().SetUint64(1)) 755 } 756 if err == nil || err == errExecutionReverted { 757 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 758 } 759 contract.Gas += returnGas 760 761 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 762 return ret, nil 763 } 764 765 func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 766 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 767 interpreter.intPool.put(stack.pop()) 768 gas := interpreter.evm.callGasTemp 769 // Pop other call parameters. 770 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 771 toAddr := common.BigToAddress(addr) 772 value = math.U256(value) 773 // Get arguments from the memory. 774 args := memory.Get(inOffset.Int64(), inSize.Int64()) 775 776 if value.Sign() != 0 { 777 gas += params.CallStipend 778 } 779 ret, returnGas, err := interpreter.evm.CallCode(contract, toAddr, args, gas, value) 780 if err != nil { 781 stack.push(interpreter.intPool.getZero()) 782 } else { 783 stack.push(interpreter.intPool.get().SetUint64(1)) 784 } 785 if err == nil || err == errExecutionReverted { 786 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 787 } 788 contract.Gas += returnGas 789 790 interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 791 return ret, nil 792 } 793 794 func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 795 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 796 interpreter.intPool.put(stack.pop()) 797 gas := interpreter.evm.callGasTemp 798 // Pop other call parameters. 799 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 800 toAddr := common.BigToAddress(addr) 801 // Get arguments from the memory. 802 args := memory.Get(inOffset.Int64(), inSize.Int64()) 803 804 ret, returnGas, err := interpreter.evm.DelegateCall(contract, toAddr, args, gas) 805 if err != nil { 806 stack.push(interpreter.intPool.getZero()) 807 } else { 808 stack.push(interpreter.intPool.get().SetUint64(1)) 809 } 810 if err == nil || err == errExecutionReverted { 811 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 812 } 813 contract.Gas += returnGas 814 815 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 816 return ret, nil 817 } 818 819 func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 820 // Pop gas. The actual gas is in interpreter.evm.callGasTemp. 821 interpreter.intPool.put(stack.pop()) 822 gas := interpreter.evm.callGasTemp 823 // Pop other call parameters. 824 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 825 toAddr := common.BigToAddress(addr) 826 // Get arguments from the memory. 827 args := memory.Get(inOffset.Int64(), inSize.Int64()) 828 829 ret, returnGas, err := interpreter.evm.StaticCall(contract, toAddr, args, gas) 830 if err != nil { 831 stack.push(interpreter.intPool.getZero()) 832 } else { 833 stack.push(interpreter.intPool.get().SetUint64(1)) 834 } 835 if err == nil || err == errExecutionReverted { 836 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 837 } 838 contract.Gas += returnGas 839 840 interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 841 return ret, nil 842 } 843 844 func opReturn(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 845 offset, size := stack.pop(), stack.pop() 846 ret := memory.GetPtr(offset.Int64(), size.Int64()) 847 848 interpreter.intPool.put(offset, size) 849 return ret, nil 850 } 851 852 func opRevert(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 853 offset, size := stack.pop(), stack.pop() 854 ret := memory.GetPtr(offset.Int64(), size.Int64()) 855 856 interpreter.intPool.put(offset, size) 857 return ret, nil 858 } 859 860 func opStop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 861 return nil, nil 862 } 863 864 func opSuicide(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 865 balance := interpreter.evm.StateDB.GetBalance(contract.Address()) 866 interpreter.evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 867 868 interpreter.evm.StateDB.Suicide(contract.Address()) 869 return nil, nil 870 } 871 872 // following functions are used by the instruction jump table 873 874 // make log instruction function 875 func makeLog(size int) executionFunc { 876 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 877 topics := make([]common.Hash, size) 878 mStart, mSize := stack.pop(), stack.pop() 879 for i := 0; i < size; i++ { 880 topics[i] = common.BigToHash(stack.pop()) 881 } 882 883 d := memory.Get(mStart.Int64(), mSize.Int64()) 884 interpreter.evm.StateDB.AddLog(&types.Log{ 885 Address: contract.Address(), 886 Topics: topics, 887 Data: d, 888 // This is a non-consensus field, but assigned here because 889 // core/state doesn't know the current block number. 890 BlockNumber: interpreter.evm.BlockNumber.Uint64(), 891 }) 892 893 interpreter.intPool.put(mStart, mSize) 894 return nil, nil 895 } 896 } 897 898 // make push instruction function 899 func makePush(size uint64, pushByteSize int) executionFunc { 900 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 901 codeLen := len(contract.Code) 902 903 startMin := codeLen 904 if int(*pc+1) < startMin { 905 startMin = int(*pc + 1) 906 } 907 908 endMin := codeLen 909 if startMin+pushByteSize < endMin { 910 endMin = startMin + pushByteSize 911 } 912 913 integer := interpreter.intPool.get() 914 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 915 916 *pc += size 917 return nil, nil 918 } 919 } 920 921 // make dup instruction function 922 func makeDup(size int64) executionFunc { 923 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 924 stack.dup(interpreter.intPool, int(size)) 925 return nil, nil 926 } 927 } 928 929 // make swap instruction function 930 func makeSwap(size int64) executionFunc { 931 // switch n + 1 otherwise n would be swapped with n 932 size++ 933 return func(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 934 stack.swap(int(size)) 935 return nil, nil 936 } 937 }