github.com/klaytn/klaytn@v1.10.2/blockchain/vm/instructions.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/vm/instructions.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package vm 22 23 import ( 24 "math/big" 25 26 "github.com/klaytn/klaytn/blockchain/types" 27 "github.com/klaytn/klaytn/common" 28 "github.com/klaytn/klaytn/common/math" 29 "github.com/klaytn/klaytn/crypto/sha3" 30 "github.com/klaytn/klaytn/params" 31 ) 32 33 var ( 34 bigZero = new(big.Int) 35 tt255 = math.BigPow(2, 255) 36 ) 37 38 func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 39 x, y := stack.pop(), stack.Peek() 40 math.U256(y.Add(x, y)) 41 42 evm.interpreter.intPool.put(x) 43 return nil, nil 44 } 45 46 func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 47 x, y := stack.pop(), stack.Peek() 48 math.U256(y.Sub(x, y)) 49 50 evm.interpreter.intPool.put(x) 51 return nil, nil 52 } 53 54 func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 55 x, y := stack.pop(), stack.pop() 56 stack.push(math.U256(x.Mul(x, y))) 57 58 evm.interpreter.intPool.put(y) 59 60 return nil, nil 61 } 62 63 func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 64 x, y := stack.pop(), stack.Peek() 65 if y.Sign() != 0 { 66 math.U256(y.Div(x, y)) 67 } else { 68 y.SetUint64(0) 69 } 70 evm.interpreter.intPool.put(x) 71 return nil, nil 72 } 73 74 func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 75 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 76 res := evm.interpreter.intPool.getZero() 77 78 if y.Sign() == 0 || x.Sign() == 0 { 79 stack.push(res) 80 } else { 81 if x.Sign() != y.Sign() { 82 res.Div(x.Abs(x), y.Abs(y)) 83 res.Neg(res) 84 } else { 85 res.Div(x.Abs(x), y.Abs(y)) 86 } 87 stack.push(math.U256(res)) 88 } 89 evm.interpreter.intPool.put(x, y) 90 return nil, nil 91 } 92 93 func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 94 x, y := stack.pop(), stack.pop() 95 if y.Sign() == 0 { 96 stack.push(x.SetUint64(0)) 97 } else { 98 stack.push(math.U256(x.Mod(x, y))) 99 } 100 evm.interpreter.intPool.put(y) 101 return nil, nil 102 } 103 104 func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 105 x, y := math.S256(stack.pop()), math.S256(stack.pop()) 106 res := evm.interpreter.intPool.getZero() 107 108 if y.Sign() == 0 { 109 stack.push(res) 110 } else { 111 if x.Sign() < 0 { 112 res.Mod(x.Abs(x), y.Abs(y)) 113 res.Neg(res) 114 } else { 115 res.Mod(x.Abs(x), y.Abs(y)) 116 } 117 stack.push(math.U256(res)) 118 } 119 evm.interpreter.intPool.put(x, y) 120 return nil, nil 121 } 122 123 func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 124 base, exponent := stack.pop(), stack.pop() 125 // some shortcuts 126 cmpToOne := exponent.Cmp(big1) 127 if cmpToOne < 0 { // Exponent is zero 128 // x ^ 0 == 1 129 stack.push(base.SetUint64(1)) 130 } else if base.Sign() == 0 { 131 // 0 ^ y, if y != 0, == 0 132 stack.push(base.SetUint64(0)) 133 } else if cmpToOne == 0 { // Exponent is one 134 // x ^ 1 == x 135 stack.push(base) 136 } else { 137 stack.push(math.Exp(base, exponent)) 138 evm.interpreter.intPool.put(base) 139 } 140 evm.interpreter.intPool.put(exponent) 141 142 return nil, nil 143 } 144 145 func opSignExtend(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(back) 162 return nil, nil 163 } 164 165 func opNot(pc *uint64, evm *EVM, 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, evm *EVM, 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 evm.interpreter.intPool.put(x) 179 return nil, nil 180 } 181 182 func opGt(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(x) 190 return nil, nil 191 } 192 193 func opSlt(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(x) 214 return nil, nil 215 } 216 217 func opSgt(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(x) 238 return nil, nil 239 } 240 241 func opEq(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(x) 249 return nil, nil 250 } 251 252 func opIszero(pc *uint64, evm *EVM, 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, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 263 x, y := stack.pop(), stack.pop() 264 stack.push(x.And(x, y)) 265 266 evm.interpreter.intPool.put(y) 267 return nil, nil 268 } 269 270 func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 271 x, y := stack.pop(), stack.Peek() 272 y.Or(x, y) 273 274 evm.interpreter.intPool.put(x) 275 return nil, nil 276 } 277 278 func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 279 x, y := stack.pop(), stack.Peek() 280 y.Xor(x, y) 281 282 evm.interpreter.intPool.put(x) 283 return nil, nil 284 } 285 286 func opByte(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(th) 295 return nil, nil 296 } 297 298 func opAddmod(pc *uint64, evm *EVM, 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 evm.interpreter.intPool.put(y, z) 308 return nil, nil 309 } 310 311 func opMulmod(pc *uint64, evm *EVM, 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 evm.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, evm *EVM, 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 evm.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, evm *EVM, 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 evm.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, evm *EVM, 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 evm.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, evm *EVM, 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 evm.interpreter.hasher == nil { 389 evm.interpreter.hasher = sha3.NewKeccak256().(keccakState) 390 } else { 391 evm.interpreter.hasher.Reset() 392 } 393 evm.interpreter.hasher.Write(data) 394 evm.interpreter.hasher.Read(evm.interpreter.hasherBuf[:]) 395 396 if evm.vmConfig.EnablePreimageRecording { 397 evm.StateDB.AddPreimage(evm.interpreter.hasherBuf, data) 398 } 399 stack.push(evm.interpreter.intPool.get().SetBytes(evm.interpreter.hasherBuf[:])) 400 401 evm.interpreter.intPool.put(offset, size) 402 return nil, nil 403 } 404 405 func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 406 stack.push(evm.interpreter.intPool.get().SetBytes(contract.Address().Bytes())) 407 return nil, nil 408 } 409 410 func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 411 slot := stack.Peek() 412 slot.Set(evm.StateDB.GetBalance(common.BigToAddress(slot))) 413 return nil, nil 414 } 415 416 func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 417 stack.push(evm.interpreter.intPool.get().SetBytes(evm.Origin.Bytes())) 418 return nil, nil 419 } 420 421 func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 422 stack.push(evm.interpreter.intPool.get().SetBytes(contract.Caller().Bytes())) 423 return nil, nil 424 } 425 426 func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 427 stack.push(evm.interpreter.intPool.get().Set(contract.value)) 428 return nil, nil 429 } 430 431 func opCallDataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 432 stack.push(evm.interpreter.intPool.get().SetBytes(getDataBig(contract.Input, stack.pop(), big32))) 433 return nil, nil 434 } 435 436 func opCallDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 437 stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input)))) 438 return nil, nil 439 } 440 441 func opCallDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 442 var ( 443 memOffset = stack.pop() 444 dataOffset = stack.pop() 445 length = stack.pop() 446 ) 447 memory.Set(memOffset.Uint64(), length.Uint64(), getDataBig(contract.Input, dataOffset, length)) 448 449 evm.interpreter.intPool.put(memOffset, dataOffset, length) 450 return nil, nil 451 } 452 453 func opReturnDataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 454 stack.push(evm.interpreter.intPool.get().SetUint64(uint64(len(evm.interpreter.returnData)))) 455 return nil, nil 456 } 457 458 func opReturnDataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 459 var ( 460 memOffset = stack.pop() 461 dataOffset = stack.pop() 462 length = stack.pop() 463 464 end = evm.interpreter.intPool.get().Add(dataOffset, length) 465 ) 466 defer evm.interpreter.intPool.put(memOffset, dataOffset, length, end) 467 468 if !end.IsUint64() || uint64(len(evm.interpreter.returnData)) < end.Uint64() { 469 return nil, ErrReturnDataOutOfBounds // TODO-Klaytn-Issue615 470 } 471 memory.Set(memOffset.Uint64(), length.Uint64(), evm.interpreter.returnData[dataOffset.Uint64():end.Uint64()]) 472 473 return nil, nil 474 } 475 476 func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 477 slot := stack.Peek() 478 slot.SetUint64(uint64(evm.StateDB.GetCodeSize(common.BigToAddress(slot)))) 479 480 return nil, nil 481 } 482 483 func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 484 l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code))) 485 stack.push(l) 486 487 return nil, nil 488 } 489 490 func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 491 var ( 492 memOffset = stack.pop() 493 codeOffset = stack.pop() 494 length = stack.pop() 495 ) 496 codeCopy := getDataBig(contract.Code, codeOffset, length) 497 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 498 499 evm.interpreter.intPool.put(memOffset, codeOffset, length) 500 return nil, nil 501 } 502 503 func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 504 var ( 505 addr = common.BigToAddress(stack.pop()) 506 memOffset = stack.pop() 507 codeOffset = stack.pop() 508 length = stack.pop() 509 ) 510 codeCopy := getDataBig(evm.StateDB.GetCode(addr), codeOffset, length) 511 memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) 512 513 evm.interpreter.intPool.put(memOffset, codeOffset, length) 514 return nil, nil 515 } 516 517 // opExtCodeHash returns the code hash of a specified account. 518 // There are several cases when the function is called, while we can relay everything 519 // to `state.GetCodeHash` function to ensure the correctness. 520 // (1) Caller tries to get the code hash of a normal contract account, state 521 // should return the relative code hash and set it as the result. 522 // 523 // (2) Caller tries to get the code hash of a non-existent account, state should 524 // return common.Hash{} and zero will be set as the result. 525 // 526 // (3) Caller tries to get the code hash for an account without contract code, 527 // state should return emptyCodeHash(0xc5d246...) as the result. 528 // 529 // (4) Caller tries to get the code hash of a precompiled account, the result 530 // should be zero or emptyCodeHash. 531 // 532 // It is worth noting that in order to avoid unnecessary create and clean, 533 // all precompile accounts on mainnet have been transferred 1 wei, so the return 534 // here should be emptyCodeHash. 535 // If the precompile account is not transferred any amount on a private or 536 // customized chain, the return value will be zero. 537 // 538 // (5) Caller tries to get the code hash for an account which is marked as suicided 539 // in the current transaction, the code hash of this account should be returned. 540 // 541 // (6) Caller tries to get the code hash for an account which is marked as deleted, 542 // this account should be regarded as a non-existent account and zero should be returned. 543 func opExtCodeHash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 544 slot := stack.Peek() 545 slot.SetBytes(evm.StateDB.GetCodeHash(common.BigToAddress(slot)).Bytes()) 546 return nil, nil 547 } 548 549 func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 550 stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice)) 551 return nil, nil 552 } 553 554 func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 555 num := stack.pop() 556 557 n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257) 558 if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 { 559 stack.push(evm.GetHash(num.Uint64()).Big()) 560 } else { 561 stack.push(evm.interpreter.intPool.getZero()) 562 } 563 evm.interpreter.intPool.put(num, n) 564 return nil, nil 565 } 566 567 func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 568 stack.push(evm.interpreter.intPool.get().SetBytes(evm.Coinbase.Bytes())) 569 return nil, nil 570 } 571 572 func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 573 stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.Time))) 574 return nil, nil 575 } 576 577 func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 578 stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockNumber))) 579 return nil, nil 580 } 581 582 func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 583 stack.push(math.U256(evm.interpreter.intPool.get().Set(evm.BlockScore))) 584 return nil, nil 585 } 586 587 func opRandom(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 588 // evm.BlockNumber.Uint64() is always greater than or equal to 1 589 // since evm will not run on the genesis block 590 stack.push(evm.GetHash(evm.BlockNumber.Uint64() - 1).Big()) 591 return nil, nil 592 } 593 594 func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 595 stack.push(math.U256(evm.interpreter.intPool.get().SetUint64(evm.GasLimit))) 596 return nil, nil 597 } 598 599 func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 600 evm.interpreter.intPool.put(stack.pop()) 601 return nil, nil 602 } 603 604 func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 605 v := stack.Peek() 606 offset := v.Int64() 607 v.SetBytes(memory.GetPtr(offset, 32)) 608 609 return nil, nil 610 } 611 612 func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 613 // pop value of the stack 614 mStart, val := stack.pop(), stack.pop() 615 memory.Set32(mStart.Uint64(), val) 616 617 evm.interpreter.intPool.put(mStart, val) 618 return nil, nil 619 } 620 621 func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 622 off, val := stack.pop().Int64(), stack.pop().Int64() 623 memory.store[off] = byte(val & 0xff) 624 625 return nil, nil 626 } 627 628 func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 629 loc := stack.Peek() 630 val := evm.StateDB.GetState(contract.Address(), common.BigToHash(loc)) 631 loc.SetBytes(val.Bytes()) 632 return nil, nil 633 } 634 635 func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 636 loc := common.BigToHash(stack.pop()) 637 val := stack.pop() 638 evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val)) 639 640 evm.interpreter.intPool.put(val) 641 return nil, nil 642 } 643 644 func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 645 pos := stack.pop() 646 if !contract.validJumpdest(pos) { 647 return nil, ErrInvalidJump 648 } 649 *pc = pos.Uint64() 650 651 evm.interpreter.intPool.put(pos) 652 return nil, nil 653 } 654 655 func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 656 pos, cond := stack.pop(), stack.pop() 657 if cond.Sign() != 0 { 658 if !contract.validJumpdest(pos) { 659 return nil, ErrInvalidJump 660 } 661 *pc = pos.Uint64() 662 } else { 663 *pc++ 664 } 665 666 evm.interpreter.intPool.put(pos, cond) 667 return nil, nil 668 } 669 670 func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 671 return nil, nil 672 } 673 674 func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 675 stack.push(evm.interpreter.intPool.get().SetUint64(*pc)) 676 return nil, nil 677 } 678 679 func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 680 stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len()))) 681 return nil, nil 682 } 683 684 func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 685 stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas)) 686 return nil, nil 687 } 688 689 func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 690 var ( 691 value = stack.pop() 692 offset, size = stack.pop(), stack.pop() 693 input = memory.GetCopy(offset.Int64(), size.Int64()) 694 gas = contract.Gas 695 ) 696 697 // This is from EIP150. 698 gas -= gas / 64 699 700 contract.UseGas(gas) 701 res, addr, returnGas, suberr := evm.Create(contract, input, gas, value, params.CodeFormatEVM) 702 // Push item on the stack based on the returned error. If the ruleset is 703 // homestead we must check for CodeStoreOutOfGasError (homestead only 704 // rule) and treat as an error, if the ruleset is frontier we must 705 // ignore this error and pretend the operation was successful. 706 if suberr != nil { 707 stack.push(evm.interpreter.intPool.getZero()) 708 } else { 709 stack.push(evm.interpreter.intPool.get().SetBytes(addr.Bytes())) 710 } 711 contract.Gas += returnGas 712 evm.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, evm *EVM, 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 := evm.Create2(contract, input, gas, endowment, salt, params.CodeFormatEVM) 733 // Push item on the stack based on the returned error. 734 if suberr != nil { 735 stack.push(evm.interpreter.intPool.getZero()) 736 } else { 737 stack.push(evm.interpreter.intPool.get().SetBytes(addr.Bytes())) 738 } 739 contract.Gas += returnGas 740 evm.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, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 749 // Pop gas. The actual gas in evm.callGasTemp. 750 evm.interpreter.intPool.put(stack.pop()) 751 gas := 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 := evm.Call(contract, toAddr, args, gas, value) 763 if err != nil { 764 stack.push(evm.interpreter.intPool.getZero()) 765 } else { 766 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 767 } 768 if err == nil || err == ErrExecutionReverted { 769 ret = common.CopyBytes(ret) 770 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 771 } 772 contract.Gas += returnGas 773 774 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 775 return ret, nil 776 } 777 778 func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 779 // Pop gas. The actual gas is in evm.callGasTemp. 780 evm.interpreter.intPool.put(stack.pop()) 781 gas := evm.callGasTemp 782 // Pop other call parameters. 783 addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 784 toAddr := common.BigToAddress(addr) 785 value = math.U256(value) 786 // Get arguments from the memory. 787 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 788 789 if value.Sign() != 0 { 790 gas += params.CallStipend 791 } 792 ret, returnGas, err := evm.CallCode(contract, toAddr, args, gas, value) 793 if err != nil { 794 stack.push(evm.interpreter.intPool.getZero()) 795 } else { 796 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 797 } 798 if err == nil || err == ErrExecutionReverted { 799 ret = common.CopyBytes(ret) 800 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 801 } 802 contract.Gas += returnGas 803 804 evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize) 805 return ret, nil 806 } 807 808 func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 809 // Pop gas. The actual gas is in evm.callGasTemp. 810 evm.interpreter.intPool.put(stack.pop()) 811 gas := evm.callGasTemp 812 // Pop other call parameters. 813 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 814 toAddr := common.BigToAddress(addr) 815 // Get arguments from the memory. 816 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 817 818 ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas) 819 if err != nil { 820 stack.push(evm.interpreter.intPool.getZero()) 821 } else { 822 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 823 } 824 if err == nil || err == ErrExecutionReverted { 825 ret = common.CopyBytes(ret) 826 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 827 } 828 contract.Gas += returnGas 829 830 evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 831 return ret, nil 832 } 833 834 func opStaticCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 835 // Pop gas. The actual gas is in evm.callGasTemp. 836 evm.interpreter.intPool.put(stack.pop()) 837 gas := evm.callGasTemp 838 // Pop other call parameters. 839 addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() 840 toAddr := common.BigToAddress(addr) 841 // Get arguments from the memory. 842 args := memory.GetPtr(inOffset.Int64(), inSize.Int64()) 843 844 ret, returnGas, err := evm.StaticCall(contract, toAddr, args, gas) 845 if err != nil { 846 stack.push(evm.interpreter.intPool.getZero()) 847 } else { 848 stack.push(evm.interpreter.intPool.get().SetUint64(1)) 849 } 850 if err == nil || err == ErrExecutionReverted { 851 ret = common.CopyBytes(ret) 852 memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) 853 } 854 contract.Gas += returnGas 855 856 evm.interpreter.intPool.put(addr, inOffset, inSize, retOffset, retSize) 857 return ret, nil 858 } 859 860 func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 861 offset, size := stack.pop(), stack.pop() 862 ret := memory.GetPtr(offset.Int64(), size.Int64()) 863 864 evm.interpreter.intPool.put(offset, size) 865 return ret, nil 866 } 867 868 func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 869 offset, size := stack.pop(), stack.pop() 870 ret := memory.GetPtr(offset.Int64(), size.Int64()) 871 872 evm.interpreter.intPool.put(offset, size) 873 return ret, nil 874 } 875 876 func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 877 return nil, nil 878 } 879 880 func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 881 balance := evm.StateDB.GetBalance(contract.Address()) 882 evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) 883 884 evm.StateDB.Suicide(contract.Address()) 885 return nil, nil 886 } 887 888 // opPush1 is a specialized version of pushN 889 func opPush1(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 890 var ( 891 codeLen = uint64(len(contract.Code)) 892 integer = evm.interpreter.intPool.get() 893 ) 894 *pc += 1 895 if *pc < codeLen { 896 stack.push(integer.SetUint64(uint64(contract.Code[*pc]))) 897 } else { 898 stack.push(integer.SetUint64(0)) 899 } 900 return nil, nil 901 } 902 903 // following functions are used by the instruction jump table 904 905 // make log instruction function 906 func makeLog(size int) executionFunc { 907 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 908 topics := make([]common.Hash, size) 909 mStart, mSize := stack.pop(), stack.pop() 910 for i := 0; i < size; i++ { 911 topics[i] = common.BigToHash(stack.pop()) 912 } 913 914 d := memory.GetCopy(mStart.Int64(), mSize.Int64()) 915 evm.StateDB.AddLog(&types.Log{ 916 Address: contract.Address(), 917 Topics: topics, 918 Data: d, 919 // This is a non-consensus field, but assigned here because 920 // blockchain/state doesn't know the current block number. 921 BlockNumber: evm.BlockNumber.Uint64(), 922 }) 923 924 evm.interpreter.intPool.put(mStart, mSize) 925 return nil, nil 926 } 927 } 928 929 // make push instruction function 930 func makePush(size uint64, pushByteSize int) executionFunc { 931 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 932 codeLen := len(contract.Code) 933 934 startMin := codeLen 935 if int(*pc+1) < startMin { 936 startMin = int(*pc + 1) 937 } 938 939 endMin := codeLen 940 if startMin+pushByteSize < endMin { 941 endMin = startMin + pushByteSize 942 } 943 944 integer := evm.interpreter.intPool.get() 945 stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize))) 946 947 *pc += size 948 return nil, nil 949 } 950 } 951 952 // make dup instruction function 953 func makeDup(size int64) executionFunc { 954 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 955 stack.dup(evm.interpreter.intPool, int(size)) 956 return nil, nil 957 } 958 } 959 960 // make swap instruction function 961 func makeSwap(size int64) executionFunc { 962 // switch n + 1 otherwise n would be swapped with n 963 size++ 964 return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { 965 stack.swap(int(size)) 966 return nil, nil 967 } 968 }