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