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