github.com/carter-ya/go-ethereum@v0.0.0-20230628080049-d2309be3983b/core/vm/jump_table.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/ethereum/go-ethereum/params" 23 ) 24 25 type ( 26 executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) 27 gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 28 // memorySizeFunc returns the required size, and whether the operation overflowed a uint64 29 memorySizeFunc func(*Stack) (size uint64, overflow bool) 30 ) 31 32 type operation struct { 33 // execute is the operation function 34 execute executionFunc 35 constantGas uint64 36 dynamicGas gasFunc 37 // minStack tells how many stack items are required 38 minStack int 39 // maxStack specifies the max length the stack can have for this operation 40 // to not overflow the stack. 41 maxStack int 42 43 // memorySize returns the memory size required for the operation 44 memorySize memorySizeFunc 45 } 46 47 var ( 48 frontierInstructionSet = newFrontierInstructionSet() 49 homesteadInstructionSet = newHomesteadInstructionSet() 50 tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet() 51 spuriousDragonInstructionSet = newSpuriousDragonInstructionSet() 52 byzantiumInstructionSet = newByzantiumInstructionSet() 53 constantinopleInstructionSet = newConstantinopleInstructionSet() 54 istanbulInstructionSet = newIstanbulInstructionSet() 55 berlinInstructionSet = newBerlinInstructionSet() 56 londonInstructionSet = newLondonInstructionSet() 57 mergeInstructionSet = newMergeInstructionSet() 58 ) 59 60 // JumpTable contains the EVM opcodes supported at a given fork. 61 type JumpTable [256]*operation 62 63 func validate(jt JumpTable) JumpTable { 64 for i, op := range jt { 65 if op == nil { 66 panic(fmt.Sprintf("op %#x is not set", i)) 67 } 68 // The interpreter has an assumption that if the memorySize function is 69 // set, then the dynamicGas function is also set. This is a somewhat 70 // arbitrary assumption, and can be removed if we need to -- but it 71 // allows us to avoid a condition check. As long as we have that assumption 72 // in there, this little sanity check prevents us from merging in a 73 // change which violates it. 74 if op.memorySize != nil && op.dynamicGas == nil { 75 panic(fmt.Sprintf("op %v has dynamic memory but not dynamic gas", OpCode(i).String())) 76 } 77 } 78 return jt 79 } 80 81 func newMergeInstructionSet() JumpTable { 82 instructionSet := newLondonInstructionSet() 83 instructionSet[PREVRANDAO] = &operation{ 84 execute: opRandom, 85 constantGas: GasQuickStep, 86 minStack: minStack(0, 1), 87 maxStack: maxStack(0, 1), 88 } 89 return validate(instructionSet) 90 } 91 92 // newLondonInstructionSet returns the frontier, homestead, byzantium, 93 // contantinople, istanbul, petersburg, berlin and london instructions. 94 func newLondonInstructionSet() JumpTable { 95 instructionSet := newBerlinInstructionSet() 96 enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 97 enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 98 return validate(instructionSet) 99 } 100 101 // newBerlinInstructionSet returns the frontier, homestead, byzantium, 102 // contantinople, istanbul, petersburg and berlin instructions. 103 func newBerlinInstructionSet() JumpTable { 104 instructionSet := newIstanbulInstructionSet() 105 enable2929(&instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929 106 return validate(instructionSet) 107 } 108 109 // newIstanbulInstructionSet returns the frontier, homestead, byzantium, 110 // contantinople, istanbul and petersburg instructions. 111 func newIstanbulInstructionSet() JumpTable { 112 instructionSet := newConstantinopleInstructionSet() 113 114 enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344 115 enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 116 enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 117 118 return validate(instructionSet) 119 } 120 121 // newConstantinopleInstructionSet returns the frontier, homestead, 122 // byzantium and contantinople instructions. 123 func newConstantinopleInstructionSet() JumpTable { 124 instructionSet := newByzantiumInstructionSet() 125 instructionSet[SHL] = &operation{ 126 execute: opSHL, 127 constantGas: GasFastestStep, 128 minStack: minStack(2, 1), 129 maxStack: maxStack(2, 1), 130 } 131 instructionSet[SHR] = &operation{ 132 execute: opSHR, 133 constantGas: GasFastestStep, 134 minStack: minStack(2, 1), 135 maxStack: maxStack(2, 1), 136 } 137 instructionSet[SAR] = &operation{ 138 execute: opSAR, 139 constantGas: GasFastestStep, 140 minStack: minStack(2, 1), 141 maxStack: maxStack(2, 1), 142 } 143 instructionSet[EXTCODEHASH] = &operation{ 144 execute: opExtCodeHash, 145 constantGas: params.ExtcodeHashGasConstantinople, 146 minStack: minStack(1, 1), 147 maxStack: maxStack(1, 1), 148 } 149 instructionSet[CREATE2] = &operation{ 150 execute: opCreate2, 151 constantGas: params.Create2Gas, 152 dynamicGas: gasCreate2, 153 minStack: minStack(4, 1), 154 maxStack: maxStack(4, 1), 155 memorySize: memoryCreate2, 156 } 157 return validate(instructionSet) 158 } 159 160 // newByzantiumInstructionSet returns the frontier, homestead and 161 // byzantium instructions. 162 func newByzantiumInstructionSet() JumpTable { 163 instructionSet := newSpuriousDragonInstructionSet() 164 instructionSet[STATICCALL] = &operation{ 165 execute: opStaticCall, 166 constantGas: params.CallGasEIP150, 167 dynamicGas: gasStaticCall, 168 minStack: minStack(6, 1), 169 maxStack: maxStack(6, 1), 170 memorySize: memoryStaticCall, 171 } 172 instructionSet[RETURNDATASIZE] = &operation{ 173 execute: opReturnDataSize, 174 constantGas: GasQuickStep, 175 minStack: minStack(0, 1), 176 maxStack: maxStack(0, 1), 177 } 178 instructionSet[RETURNDATACOPY] = &operation{ 179 execute: opReturnDataCopy, 180 constantGas: GasFastestStep, 181 dynamicGas: gasReturnDataCopy, 182 minStack: minStack(3, 0), 183 maxStack: maxStack(3, 0), 184 memorySize: memoryReturnDataCopy, 185 } 186 instructionSet[REVERT] = &operation{ 187 execute: opRevert, 188 dynamicGas: gasRevert, 189 minStack: minStack(2, 0), 190 maxStack: maxStack(2, 0), 191 memorySize: memoryRevert, 192 } 193 return validate(instructionSet) 194 } 195 196 // EIP 158 a.k.a Spurious Dragon 197 func newSpuriousDragonInstructionSet() JumpTable { 198 instructionSet := newTangerineWhistleInstructionSet() 199 instructionSet[EXP].dynamicGas = gasExpEIP158 200 return validate(instructionSet) 201 } 202 203 // EIP 150 a.k.a Tangerine Whistle 204 func newTangerineWhistleInstructionSet() JumpTable { 205 instructionSet := newHomesteadInstructionSet() 206 instructionSet[BALANCE].constantGas = params.BalanceGasEIP150 207 instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150 208 instructionSet[SLOAD].constantGas = params.SloadGasEIP150 209 instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150 210 instructionSet[CALL].constantGas = params.CallGasEIP150 211 instructionSet[CALLCODE].constantGas = params.CallGasEIP150 212 instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150 213 return validate(instructionSet) 214 } 215 216 // newHomesteadInstructionSet returns the frontier and homestead 217 // instructions that can be executed during the homestead phase. 218 func newHomesteadInstructionSet() JumpTable { 219 instructionSet := newFrontierInstructionSet() 220 instructionSet[DELEGATECALL] = &operation{ 221 execute: opDelegateCall, 222 dynamicGas: gasDelegateCall, 223 constantGas: params.CallGasFrontier, 224 minStack: minStack(6, 1), 225 maxStack: maxStack(6, 1), 226 memorySize: memoryDelegateCall, 227 } 228 return validate(instructionSet) 229 } 230 231 // newFrontierInstructionSet returns the frontier instructions 232 // that can be executed during the frontier phase. 233 func newFrontierInstructionSet() JumpTable { 234 tbl := JumpTable{ 235 STOP: { 236 execute: opStop, 237 constantGas: 0, 238 minStack: minStack(0, 0), 239 maxStack: maxStack(0, 0), 240 }, 241 ADD: { 242 execute: opAdd, 243 constantGas: GasFastestStep, 244 minStack: minStack(2, 1), 245 maxStack: maxStack(2, 1), 246 }, 247 MUL: { 248 execute: opMul, 249 constantGas: GasFastStep, 250 minStack: minStack(2, 1), 251 maxStack: maxStack(2, 1), 252 }, 253 SUB: { 254 execute: opSub, 255 constantGas: GasFastestStep, 256 minStack: minStack(2, 1), 257 maxStack: maxStack(2, 1), 258 }, 259 DIV: { 260 execute: opDiv, 261 constantGas: GasFastStep, 262 minStack: minStack(2, 1), 263 maxStack: maxStack(2, 1), 264 }, 265 SDIV: { 266 execute: opSdiv, 267 constantGas: GasFastStep, 268 minStack: minStack(2, 1), 269 maxStack: maxStack(2, 1), 270 }, 271 MOD: { 272 execute: opMod, 273 constantGas: GasFastStep, 274 minStack: minStack(2, 1), 275 maxStack: maxStack(2, 1), 276 }, 277 SMOD: { 278 execute: opSmod, 279 constantGas: GasFastStep, 280 minStack: minStack(2, 1), 281 maxStack: maxStack(2, 1), 282 }, 283 ADDMOD: { 284 execute: opAddmod, 285 constantGas: GasMidStep, 286 minStack: minStack(3, 1), 287 maxStack: maxStack(3, 1), 288 }, 289 MULMOD: { 290 execute: opMulmod, 291 constantGas: GasMidStep, 292 minStack: minStack(3, 1), 293 maxStack: maxStack(3, 1), 294 }, 295 EXP: { 296 execute: opExp, 297 dynamicGas: gasExpFrontier, 298 minStack: minStack(2, 1), 299 maxStack: maxStack(2, 1), 300 }, 301 SIGNEXTEND: { 302 execute: opSignExtend, 303 constantGas: GasFastStep, 304 minStack: minStack(2, 1), 305 maxStack: maxStack(2, 1), 306 }, 307 LT: { 308 execute: opLt, 309 constantGas: GasFastestStep, 310 minStack: minStack(2, 1), 311 maxStack: maxStack(2, 1), 312 }, 313 GT: { 314 execute: opGt, 315 constantGas: GasFastestStep, 316 minStack: minStack(2, 1), 317 maxStack: maxStack(2, 1), 318 }, 319 SLT: { 320 execute: opSlt, 321 constantGas: GasFastestStep, 322 minStack: minStack(2, 1), 323 maxStack: maxStack(2, 1), 324 }, 325 SGT: { 326 execute: opSgt, 327 constantGas: GasFastestStep, 328 minStack: minStack(2, 1), 329 maxStack: maxStack(2, 1), 330 }, 331 EQ: { 332 execute: opEq, 333 constantGas: GasFastestStep, 334 minStack: minStack(2, 1), 335 maxStack: maxStack(2, 1), 336 }, 337 ISZERO: { 338 execute: opIszero, 339 constantGas: GasFastestStep, 340 minStack: minStack(1, 1), 341 maxStack: maxStack(1, 1), 342 }, 343 AND: { 344 execute: opAnd, 345 constantGas: GasFastestStep, 346 minStack: minStack(2, 1), 347 maxStack: maxStack(2, 1), 348 }, 349 XOR: { 350 execute: opXor, 351 constantGas: GasFastestStep, 352 minStack: minStack(2, 1), 353 maxStack: maxStack(2, 1), 354 }, 355 OR: { 356 execute: opOr, 357 constantGas: GasFastestStep, 358 minStack: minStack(2, 1), 359 maxStack: maxStack(2, 1), 360 }, 361 NOT: { 362 execute: opNot, 363 constantGas: GasFastestStep, 364 minStack: minStack(1, 1), 365 maxStack: maxStack(1, 1), 366 }, 367 BYTE: { 368 execute: opByte, 369 constantGas: GasFastestStep, 370 minStack: minStack(2, 1), 371 maxStack: maxStack(2, 1), 372 }, 373 KECCAK256: { 374 execute: opKeccak256, 375 constantGas: params.Keccak256Gas, 376 dynamicGas: gasKeccak256, 377 minStack: minStack(2, 1), 378 maxStack: maxStack(2, 1), 379 memorySize: memoryKeccak256, 380 }, 381 ADDRESS: { 382 execute: opAddress, 383 constantGas: GasQuickStep, 384 minStack: minStack(0, 1), 385 maxStack: maxStack(0, 1), 386 }, 387 BALANCE: { 388 execute: opBalance, 389 constantGas: params.BalanceGasFrontier, 390 minStack: minStack(1, 1), 391 maxStack: maxStack(1, 1), 392 }, 393 ORIGIN: { 394 execute: opOrigin, 395 constantGas: GasQuickStep, 396 minStack: minStack(0, 1), 397 maxStack: maxStack(0, 1), 398 }, 399 CALLER: { 400 execute: opCaller, 401 constantGas: GasQuickStep, 402 minStack: minStack(0, 1), 403 maxStack: maxStack(0, 1), 404 }, 405 CALLVALUE: { 406 execute: opCallValue, 407 constantGas: GasQuickStep, 408 minStack: minStack(0, 1), 409 maxStack: maxStack(0, 1), 410 }, 411 CALLDATALOAD: { 412 execute: opCallDataLoad, 413 constantGas: GasFastestStep, 414 minStack: minStack(1, 1), 415 maxStack: maxStack(1, 1), 416 }, 417 CALLDATASIZE: { 418 execute: opCallDataSize, 419 constantGas: GasQuickStep, 420 minStack: minStack(0, 1), 421 maxStack: maxStack(0, 1), 422 }, 423 CALLDATACOPY: { 424 execute: opCallDataCopy, 425 constantGas: GasFastestStep, 426 dynamicGas: gasCallDataCopy, 427 minStack: minStack(3, 0), 428 maxStack: maxStack(3, 0), 429 memorySize: memoryCallDataCopy, 430 }, 431 CODESIZE: { 432 execute: opCodeSize, 433 constantGas: GasQuickStep, 434 minStack: minStack(0, 1), 435 maxStack: maxStack(0, 1), 436 }, 437 CODECOPY: { 438 execute: opCodeCopy, 439 constantGas: GasFastestStep, 440 dynamicGas: gasCodeCopy, 441 minStack: minStack(3, 0), 442 maxStack: maxStack(3, 0), 443 memorySize: memoryCodeCopy, 444 }, 445 GASPRICE: { 446 execute: opGasprice, 447 constantGas: GasQuickStep, 448 minStack: minStack(0, 1), 449 maxStack: maxStack(0, 1), 450 }, 451 EXTCODESIZE: { 452 execute: opExtCodeSize, 453 constantGas: params.ExtcodeSizeGasFrontier, 454 minStack: minStack(1, 1), 455 maxStack: maxStack(1, 1), 456 }, 457 EXTCODECOPY: { 458 execute: opExtCodeCopy, 459 constantGas: params.ExtcodeCopyBaseFrontier, 460 dynamicGas: gasExtCodeCopy, 461 minStack: minStack(4, 0), 462 maxStack: maxStack(4, 0), 463 memorySize: memoryExtCodeCopy, 464 }, 465 BLOCKHASH: { 466 execute: opBlockhash, 467 constantGas: GasExtStep, 468 minStack: minStack(1, 1), 469 maxStack: maxStack(1, 1), 470 }, 471 COINBASE: { 472 execute: opCoinbase, 473 constantGas: GasQuickStep, 474 minStack: minStack(0, 1), 475 maxStack: maxStack(0, 1), 476 }, 477 TIMESTAMP: { 478 execute: opTimestamp, 479 constantGas: GasQuickStep, 480 minStack: minStack(0, 1), 481 maxStack: maxStack(0, 1), 482 }, 483 NUMBER: { 484 execute: opNumber, 485 constantGas: GasQuickStep, 486 minStack: minStack(0, 1), 487 maxStack: maxStack(0, 1), 488 }, 489 DIFFICULTY: { 490 execute: opDifficulty, 491 constantGas: GasQuickStep, 492 minStack: minStack(0, 1), 493 maxStack: maxStack(0, 1), 494 }, 495 GASLIMIT: { 496 execute: opGasLimit, 497 constantGas: GasQuickStep, 498 minStack: minStack(0, 1), 499 maxStack: maxStack(0, 1), 500 }, 501 POP: { 502 execute: opPop, 503 constantGas: GasQuickStep, 504 minStack: minStack(1, 0), 505 maxStack: maxStack(1, 0), 506 }, 507 MLOAD: { 508 execute: opMload, 509 constantGas: GasFastestStep, 510 dynamicGas: gasMLoad, 511 minStack: minStack(1, 1), 512 maxStack: maxStack(1, 1), 513 memorySize: memoryMLoad, 514 }, 515 MSTORE: { 516 execute: opMstore, 517 constantGas: GasFastestStep, 518 dynamicGas: gasMStore, 519 minStack: minStack(2, 0), 520 maxStack: maxStack(2, 0), 521 memorySize: memoryMStore, 522 }, 523 MSTORE8: { 524 execute: opMstore8, 525 constantGas: GasFastestStep, 526 dynamicGas: gasMStore8, 527 memorySize: memoryMStore8, 528 minStack: minStack(2, 0), 529 maxStack: maxStack(2, 0), 530 }, 531 SLOAD: { 532 execute: opSload, 533 constantGas: params.SloadGasFrontier, 534 minStack: minStack(1, 1), 535 maxStack: maxStack(1, 1), 536 }, 537 SSTORE: { 538 execute: opSstore, 539 dynamicGas: gasSStore, 540 minStack: minStack(2, 0), 541 maxStack: maxStack(2, 0), 542 }, 543 JUMP: { 544 execute: opJump, 545 constantGas: GasMidStep, 546 minStack: minStack(1, 0), 547 maxStack: maxStack(1, 0), 548 }, 549 JUMPI: { 550 execute: opJumpi, 551 constantGas: GasSlowStep, 552 minStack: minStack(2, 0), 553 maxStack: maxStack(2, 0), 554 }, 555 PC: { 556 execute: opPc, 557 constantGas: GasQuickStep, 558 minStack: minStack(0, 1), 559 maxStack: maxStack(0, 1), 560 }, 561 MSIZE: { 562 execute: opMsize, 563 constantGas: GasQuickStep, 564 minStack: minStack(0, 1), 565 maxStack: maxStack(0, 1), 566 }, 567 GAS: { 568 execute: opGas, 569 constantGas: GasQuickStep, 570 minStack: minStack(0, 1), 571 maxStack: maxStack(0, 1), 572 }, 573 JUMPDEST: { 574 execute: opJumpdest, 575 constantGas: params.JumpdestGas, 576 minStack: minStack(0, 0), 577 maxStack: maxStack(0, 0), 578 }, 579 PUSH1: { 580 execute: opPush1, 581 constantGas: GasFastestStep, 582 minStack: minStack(0, 1), 583 maxStack: maxStack(0, 1), 584 }, 585 PUSH2: { 586 execute: makePush(2, 2), 587 constantGas: GasFastestStep, 588 minStack: minStack(0, 1), 589 maxStack: maxStack(0, 1), 590 }, 591 PUSH3: { 592 execute: makePush(3, 3), 593 constantGas: GasFastestStep, 594 minStack: minStack(0, 1), 595 maxStack: maxStack(0, 1), 596 }, 597 PUSH4: { 598 execute: makePush(4, 4), 599 constantGas: GasFastestStep, 600 minStack: minStack(0, 1), 601 maxStack: maxStack(0, 1), 602 }, 603 PUSH5: { 604 execute: makePush(5, 5), 605 constantGas: GasFastestStep, 606 minStack: minStack(0, 1), 607 maxStack: maxStack(0, 1), 608 }, 609 PUSH6: { 610 execute: makePush(6, 6), 611 constantGas: GasFastestStep, 612 minStack: minStack(0, 1), 613 maxStack: maxStack(0, 1), 614 }, 615 PUSH7: { 616 execute: makePush(7, 7), 617 constantGas: GasFastestStep, 618 minStack: minStack(0, 1), 619 maxStack: maxStack(0, 1), 620 }, 621 PUSH8: { 622 execute: makePush(8, 8), 623 constantGas: GasFastestStep, 624 minStack: minStack(0, 1), 625 maxStack: maxStack(0, 1), 626 }, 627 PUSH9: { 628 execute: makePush(9, 9), 629 constantGas: GasFastestStep, 630 minStack: minStack(0, 1), 631 maxStack: maxStack(0, 1), 632 }, 633 PUSH10: { 634 execute: makePush(10, 10), 635 constantGas: GasFastestStep, 636 minStack: minStack(0, 1), 637 maxStack: maxStack(0, 1), 638 }, 639 PUSH11: { 640 execute: makePush(11, 11), 641 constantGas: GasFastestStep, 642 minStack: minStack(0, 1), 643 maxStack: maxStack(0, 1), 644 }, 645 PUSH12: { 646 execute: makePush(12, 12), 647 constantGas: GasFastestStep, 648 minStack: minStack(0, 1), 649 maxStack: maxStack(0, 1), 650 }, 651 PUSH13: { 652 execute: makePush(13, 13), 653 constantGas: GasFastestStep, 654 minStack: minStack(0, 1), 655 maxStack: maxStack(0, 1), 656 }, 657 PUSH14: { 658 execute: makePush(14, 14), 659 constantGas: GasFastestStep, 660 minStack: minStack(0, 1), 661 maxStack: maxStack(0, 1), 662 }, 663 PUSH15: { 664 execute: makePush(15, 15), 665 constantGas: GasFastestStep, 666 minStack: minStack(0, 1), 667 maxStack: maxStack(0, 1), 668 }, 669 PUSH16: { 670 execute: makePush(16, 16), 671 constantGas: GasFastestStep, 672 minStack: minStack(0, 1), 673 maxStack: maxStack(0, 1), 674 }, 675 PUSH17: { 676 execute: makePush(17, 17), 677 constantGas: GasFastestStep, 678 minStack: minStack(0, 1), 679 maxStack: maxStack(0, 1), 680 }, 681 PUSH18: { 682 execute: makePush(18, 18), 683 constantGas: GasFastestStep, 684 minStack: minStack(0, 1), 685 maxStack: maxStack(0, 1), 686 }, 687 PUSH19: { 688 execute: makePush(19, 19), 689 constantGas: GasFastestStep, 690 minStack: minStack(0, 1), 691 maxStack: maxStack(0, 1), 692 }, 693 PUSH20: { 694 execute: makePush(20, 20), 695 constantGas: GasFastestStep, 696 minStack: minStack(0, 1), 697 maxStack: maxStack(0, 1), 698 }, 699 PUSH21: { 700 execute: makePush(21, 21), 701 constantGas: GasFastestStep, 702 minStack: minStack(0, 1), 703 maxStack: maxStack(0, 1), 704 }, 705 PUSH22: { 706 execute: makePush(22, 22), 707 constantGas: GasFastestStep, 708 minStack: minStack(0, 1), 709 maxStack: maxStack(0, 1), 710 }, 711 PUSH23: { 712 execute: makePush(23, 23), 713 constantGas: GasFastestStep, 714 minStack: minStack(0, 1), 715 maxStack: maxStack(0, 1), 716 }, 717 PUSH24: { 718 execute: makePush(24, 24), 719 constantGas: GasFastestStep, 720 minStack: minStack(0, 1), 721 maxStack: maxStack(0, 1), 722 }, 723 PUSH25: { 724 execute: makePush(25, 25), 725 constantGas: GasFastestStep, 726 minStack: minStack(0, 1), 727 maxStack: maxStack(0, 1), 728 }, 729 PUSH26: { 730 execute: makePush(26, 26), 731 constantGas: GasFastestStep, 732 minStack: minStack(0, 1), 733 maxStack: maxStack(0, 1), 734 }, 735 PUSH27: { 736 execute: makePush(27, 27), 737 constantGas: GasFastestStep, 738 minStack: minStack(0, 1), 739 maxStack: maxStack(0, 1), 740 }, 741 PUSH28: { 742 execute: makePush(28, 28), 743 constantGas: GasFastestStep, 744 minStack: minStack(0, 1), 745 maxStack: maxStack(0, 1), 746 }, 747 PUSH29: { 748 execute: makePush(29, 29), 749 constantGas: GasFastestStep, 750 minStack: minStack(0, 1), 751 maxStack: maxStack(0, 1), 752 }, 753 PUSH30: { 754 execute: makePush(30, 30), 755 constantGas: GasFastestStep, 756 minStack: minStack(0, 1), 757 maxStack: maxStack(0, 1), 758 }, 759 PUSH31: { 760 execute: makePush(31, 31), 761 constantGas: GasFastestStep, 762 minStack: minStack(0, 1), 763 maxStack: maxStack(0, 1), 764 }, 765 PUSH32: { 766 execute: makePush(32, 32), 767 constantGas: GasFastestStep, 768 minStack: minStack(0, 1), 769 maxStack: maxStack(0, 1), 770 }, 771 DUP1: { 772 execute: makeDup(1), 773 constantGas: GasFastestStep, 774 minStack: minDupStack(1), 775 maxStack: maxDupStack(1), 776 }, 777 DUP2: { 778 execute: makeDup(2), 779 constantGas: GasFastestStep, 780 minStack: minDupStack(2), 781 maxStack: maxDupStack(2), 782 }, 783 DUP3: { 784 execute: makeDup(3), 785 constantGas: GasFastestStep, 786 minStack: minDupStack(3), 787 maxStack: maxDupStack(3), 788 }, 789 DUP4: { 790 execute: makeDup(4), 791 constantGas: GasFastestStep, 792 minStack: minDupStack(4), 793 maxStack: maxDupStack(4), 794 }, 795 DUP5: { 796 execute: makeDup(5), 797 constantGas: GasFastestStep, 798 minStack: minDupStack(5), 799 maxStack: maxDupStack(5), 800 }, 801 DUP6: { 802 execute: makeDup(6), 803 constantGas: GasFastestStep, 804 minStack: minDupStack(6), 805 maxStack: maxDupStack(6), 806 }, 807 DUP7: { 808 execute: makeDup(7), 809 constantGas: GasFastestStep, 810 minStack: minDupStack(7), 811 maxStack: maxDupStack(7), 812 }, 813 DUP8: { 814 execute: makeDup(8), 815 constantGas: GasFastestStep, 816 minStack: minDupStack(8), 817 maxStack: maxDupStack(8), 818 }, 819 DUP9: { 820 execute: makeDup(9), 821 constantGas: GasFastestStep, 822 minStack: minDupStack(9), 823 maxStack: maxDupStack(9), 824 }, 825 DUP10: { 826 execute: makeDup(10), 827 constantGas: GasFastestStep, 828 minStack: minDupStack(10), 829 maxStack: maxDupStack(10), 830 }, 831 DUP11: { 832 execute: makeDup(11), 833 constantGas: GasFastestStep, 834 minStack: minDupStack(11), 835 maxStack: maxDupStack(11), 836 }, 837 DUP12: { 838 execute: makeDup(12), 839 constantGas: GasFastestStep, 840 minStack: minDupStack(12), 841 maxStack: maxDupStack(12), 842 }, 843 DUP13: { 844 execute: makeDup(13), 845 constantGas: GasFastestStep, 846 minStack: minDupStack(13), 847 maxStack: maxDupStack(13), 848 }, 849 DUP14: { 850 execute: makeDup(14), 851 constantGas: GasFastestStep, 852 minStack: minDupStack(14), 853 maxStack: maxDupStack(14), 854 }, 855 DUP15: { 856 execute: makeDup(15), 857 constantGas: GasFastestStep, 858 minStack: minDupStack(15), 859 maxStack: maxDupStack(15), 860 }, 861 DUP16: { 862 execute: makeDup(16), 863 constantGas: GasFastestStep, 864 minStack: minDupStack(16), 865 maxStack: maxDupStack(16), 866 }, 867 SWAP1: { 868 execute: makeSwap(1), 869 constantGas: GasFastestStep, 870 minStack: minSwapStack(2), 871 maxStack: maxSwapStack(2), 872 }, 873 SWAP2: { 874 execute: makeSwap(2), 875 constantGas: GasFastestStep, 876 minStack: minSwapStack(3), 877 maxStack: maxSwapStack(3), 878 }, 879 SWAP3: { 880 execute: makeSwap(3), 881 constantGas: GasFastestStep, 882 minStack: minSwapStack(4), 883 maxStack: maxSwapStack(4), 884 }, 885 SWAP4: { 886 execute: makeSwap(4), 887 constantGas: GasFastestStep, 888 minStack: minSwapStack(5), 889 maxStack: maxSwapStack(5), 890 }, 891 SWAP5: { 892 execute: makeSwap(5), 893 constantGas: GasFastestStep, 894 minStack: minSwapStack(6), 895 maxStack: maxSwapStack(6), 896 }, 897 SWAP6: { 898 execute: makeSwap(6), 899 constantGas: GasFastestStep, 900 minStack: minSwapStack(7), 901 maxStack: maxSwapStack(7), 902 }, 903 SWAP7: { 904 execute: makeSwap(7), 905 constantGas: GasFastestStep, 906 minStack: minSwapStack(8), 907 maxStack: maxSwapStack(8), 908 }, 909 SWAP8: { 910 execute: makeSwap(8), 911 constantGas: GasFastestStep, 912 minStack: minSwapStack(9), 913 maxStack: maxSwapStack(9), 914 }, 915 SWAP9: { 916 execute: makeSwap(9), 917 constantGas: GasFastestStep, 918 minStack: minSwapStack(10), 919 maxStack: maxSwapStack(10), 920 }, 921 SWAP10: { 922 execute: makeSwap(10), 923 constantGas: GasFastestStep, 924 minStack: minSwapStack(11), 925 maxStack: maxSwapStack(11), 926 }, 927 SWAP11: { 928 execute: makeSwap(11), 929 constantGas: GasFastestStep, 930 minStack: minSwapStack(12), 931 maxStack: maxSwapStack(12), 932 }, 933 SWAP12: { 934 execute: makeSwap(12), 935 constantGas: GasFastestStep, 936 minStack: minSwapStack(13), 937 maxStack: maxSwapStack(13), 938 }, 939 SWAP13: { 940 execute: makeSwap(13), 941 constantGas: GasFastestStep, 942 minStack: minSwapStack(14), 943 maxStack: maxSwapStack(14), 944 }, 945 SWAP14: { 946 execute: makeSwap(14), 947 constantGas: GasFastestStep, 948 minStack: minSwapStack(15), 949 maxStack: maxSwapStack(15), 950 }, 951 SWAP15: { 952 execute: makeSwap(15), 953 constantGas: GasFastestStep, 954 minStack: minSwapStack(16), 955 maxStack: maxSwapStack(16), 956 }, 957 SWAP16: { 958 execute: makeSwap(16), 959 constantGas: GasFastestStep, 960 minStack: minSwapStack(17), 961 maxStack: maxSwapStack(17), 962 }, 963 LOG0: { 964 execute: makeLog(0), 965 dynamicGas: makeGasLog(0), 966 minStack: minStack(2, 0), 967 maxStack: maxStack(2, 0), 968 memorySize: memoryLog, 969 }, 970 LOG1: { 971 execute: makeLog(1), 972 dynamicGas: makeGasLog(1), 973 minStack: minStack(3, 0), 974 maxStack: maxStack(3, 0), 975 memorySize: memoryLog, 976 }, 977 LOG2: { 978 execute: makeLog(2), 979 dynamicGas: makeGasLog(2), 980 minStack: minStack(4, 0), 981 maxStack: maxStack(4, 0), 982 memorySize: memoryLog, 983 }, 984 LOG3: { 985 execute: makeLog(3), 986 dynamicGas: makeGasLog(3), 987 minStack: minStack(5, 0), 988 maxStack: maxStack(5, 0), 989 memorySize: memoryLog, 990 }, 991 LOG4: { 992 execute: makeLog(4), 993 dynamicGas: makeGasLog(4), 994 minStack: minStack(6, 0), 995 maxStack: maxStack(6, 0), 996 memorySize: memoryLog, 997 }, 998 CREATE: { 999 execute: opCreate, 1000 constantGas: params.CreateGas, 1001 dynamicGas: gasCreate, 1002 minStack: minStack(3, 1), 1003 maxStack: maxStack(3, 1), 1004 memorySize: memoryCreate, 1005 }, 1006 CALL: { 1007 execute: opCall, 1008 constantGas: params.CallGasFrontier, 1009 dynamicGas: gasCall, 1010 minStack: minStack(7, 1), 1011 maxStack: maxStack(7, 1), 1012 memorySize: memoryCall, 1013 }, 1014 CALLCODE: { 1015 execute: opCallCode, 1016 constantGas: params.CallGasFrontier, 1017 dynamicGas: gasCallCode, 1018 minStack: minStack(7, 1), 1019 maxStack: maxStack(7, 1), 1020 memorySize: memoryCall, 1021 }, 1022 RETURN: { 1023 execute: opReturn, 1024 dynamicGas: gasReturn, 1025 minStack: minStack(2, 0), 1026 maxStack: maxStack(2, 0), 1027 memorySize: memoryReturn, 1028 }, 1029 SELFDESTRUCT: { 1030 execute: opSelfdestruct, 1031 dynamicGas: gasSelfdestruct, 1032 minStack: minStack(1, 0), 1033 maxStack: maxStack(1, 0), 1034 }, 1035 } 1036 1037 // Fill all unassigned slots with opUndefined. 1038 for i, entry := range tbl { 1039 if entry == nil { 1040 tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0)} 1041 } 1042 } 1043 1044 return validate(tbl) 1045 }