github.com/divan/go-ethereum@v1.8.14-0.20180820134928-1de9ada4016d/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/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 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 // (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. 526 func 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 532 func 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 537 func 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 550 func 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 555 func 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 560 func 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 565 func 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 570 func 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 575 func 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 580 func 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 589 func 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 598 func 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 605 func 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 612 func 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 621 func 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 633 func 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 649 func opJumpdest(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 650 return nil, nil 651 } 652 653 func 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 658 func 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 663 func 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 668 func 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 701 func 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 729 func 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 758 func 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 787 func 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 812 func 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 837 func 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 845 func 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 853 func opStop(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 854 return nil, nil 855 } 856 857 func 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 868 func 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 892 func 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 915 func 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 923 func 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 }