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