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