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