github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/core/vm/opcodes.go (about) 1 // Copyright 2014 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum 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 Spectrum 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 Spectrum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "fmt" 21 ) 22 23 // OpCode is an EVM opcode 24 type OpCode byte 25 26 // IsPush specifies if an opcode is a PUSH opcode. 27 func (op OpCode) IsPush() bool { 28 switch op { 29 case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: 30 return true 31 } 32 return false 33 } 34 35 // 0x0 range - arithmetic ops. 36 const ( 37 STOP OpCode = 0x0 38 ADD OpCode = 0x1 39 MUL OpCode = 0x2 40 SUB OpCode = 0x3 41 DIV OpCode = 0x4 42 SDIV OpCode = 0x5 43 MOD OpCode = 0x6 44 SMOD OpCode = 0x7 45 ADDMOD OpCode = 0x8 46 MULMOD OpCode = 0x9 47 EXP OpCode = 0xa 48 SIGNEXTEND OpCode = 0xb 49 ) 50 51 // 0x10 range - comparison ops. 52 const ( 53 LT OpCode = 0x10 54 GT OpCode = 0x11 55 SLT OpCode = 0x12 56 SGT OpCode = 0x13 57 EQ OpCode = 0x14 58 ISZERO OpCode = 0x15 59 AND OpCode = 0x16 60 OR OpCode = 0x17 61 XOR OpCode = 0x18 62 NOT OpCode = 0x19 63 BYTE OpCode = 0x1a 64 SHL OpCode = 0x1b 65 SHR OpCode = 0x1c 66 SAR OpCode = 0x1d 67 68 KECCAK256 OpCode = 0x20 69 ) 70 71 // 0x30 range - closure state 72 const ( 73 ADDRESS OpCode = 0x30 74 BALANCE OpCode = 0x31 75 ORIGIN OpCode = 0x32 76 CALLER OpCode = 0x33 77 CALLVALUE OpCode = 0x34 78 CALLDATALOAD OpCode = 0x35 79 CALLDATASIZE OpCode = 0x36 80 CALLDATACOPY OpCode = 0x37 81 CODESIZE OpCode = 0x38 82 CODECOPY OpCode = 0x39 83 GASPRICE OpCode = 0x3a 84 EXTCODESIZE OpCode = 0x3b 85 EXTCODECOPY OpCode = 0x3c 86 RETURNDATASIZE OpCode = 0x3d 87 RETURNDATACOPY OpCode = 0x3e 88 EXTCODEHASH OpCode = 0x3f 89 ) 90 91 // 0x40 range - block operations. 92 const ( 93 BLOCKHASH OpCode = 0x40 94 COINBASE OpCode = 0x41 95 TIMESTAMP OpCode = 0x42 96 NUMBER OpCode = 0x43 97 DIFFICULTY OpCode = 0x44 98 RANDOM OpCode = 0x44 // Same as DIFFICULTY 99 GASLIMIT OpCode = 0x45 100 CHAINID OpCode = 0x46 101 SELFBALANCE OpCode = 0x47 102 //BASEFEE OpCode = 0x48 // todo 103 ) 104 105 // 0x50 range - 'storage' and execution. 106 const ( 107 POP OpCode = 0x50 108 MLOAD OpCode = 0x51 109 MSTORE OpCode = 0x52 110 MSTORE8 OpCode = 0x53 111 SLOAD OpCode = 0x54 112 SSTORE OpCode = 0x55 113 JUMP OpCode = 0x56 114 JUMPI OpCode = 0x57 115 PC OpCode = 0x58 116 MSIZE OpCode = 0x59 117 GAS OpCode = 0x5a 118 JUMPDEST OpCode = 0x5b 119 ) 120 121 const ( 122 // 0x60 range 123 PUSH1 OpCode = 0x60 + iota 124 PUSH2 125 PUSH3 126 PUSH4 127 PUSH5 128 PUSH6 129 PUSH7 130 PUSH8 131 PUSH9 132 PUSH10 133 PUSH11 134 PUSH12 135 PUSH13 136 PUSH14 137 PUSH15 138 PUSH16 139 PUSH17 140 PUSH18 141 PUSH19 142 PUSH20 143 PUSH21 144 PUSH22 145 PUSH23 146 PUSH24 147 PUSH25 148 PUSH26 149 PUSH27 150 PUSH28 151 PUSH29 152 PUSH30 153 PUSH31 154 PUSH32 155 DUP1 156 DUP2 157 DUP3 158 DUP4 159 DUP5 160 DUP6 161 DUP7 162 DUP8 163 DUP9 164 DUP10 165 DUP11 166 DUP12 167 DUP13 168 DUP14 169 DUP15 170 DUP16 171 SWAP1 172 SWAP2 173 SWAP3 174 SWAP4 175 SWAP5 176 SWAP6 177 SWAP7 178 SWAP8 179 SWAP9 180 SWAP10 181 SWAP11 182 SWAP12 183 SWAP13 184 SWAP14 185 SWAP15 186 SWAP16 187 ) 188 189 const ( 190 LOG0 OpCode = 0xa0 + iota 191 LOG1 192 LOG2 193 LOG3 194 LOG4 195 ) 196 197 // unofficial opcodes used for parsing 198 const ( 199 PUSH OpCode = 0xb0 + iota 200 DUP 201 SWAP 202 ) 203 204 // 0xf0 range - closures 205 const ( 206 CREATE OpCode = 0xf0 207 CALL OpCode = 0xf1 208 CALLCODE OpCode = 0xf2 209 RETURN OpCode = 0xf3 210 DELEGATECALL OpCode = 0xf4 211 CREATE2 OpCode = 0xf5 212 213 STATICCALL OpCode = 0xfa 214 REVERT OpCode = 0xfd 215 INVALID OpCode = 0xfe 216 SELFDESTRUCT OpCode = 0xff 217 ) 218 219 // Since the opcodes aren't all in order we can't use a regular slice 220 var opCodeToString = map[OpCode]string{ 221 // 0x0 range - arithmetic ops 222 STOP: "STOP", 223 ADD: "ADD", 224 MUL: "MUL", 225 SUB: "SUB", 226 DIV: "DIV", 227 SDIV: "SDIV", 228 MOD: "MOD", 229 SMOD: "SMOD", 230 EXP: "EXP", 231 NOT: "NOT", 232 LT: "LT", 233 GT: "GT", 234 SLT: "SLT", 235 SGT: "SGT", 236 EQ: "EQ", 237 ISZERO: "ISZERO", 238 SIGNEXTEND: "SIGNEXTEND", 239 240 // 0x10 range - bit ops 241 AND: "AND", 242 OR: "OR", 243 XOR: "XOR", 244 BYTE: "BYTE", 245 SHL: "SHL", 246 SHR: "SHR", 247 SAR: "SAR", 248 ADDMOD: "ADDMOD", 249 MULMOD: "MULMOD", 250 251 // 0x20 range - crypto 252 KECCAK256: "KECCAK256", 253 254 // 0x30 range - closure state 255 ADDRESS: "ADDRESS", 256 BALANCE: "BALANCE", 257 ORIGIN: "ORIGIN", 258 CALLER: "CALLER", 259 CALLVALUE: "CALLVALUE", 260 CALLDATALOAD: "CALLDATALOAD", 261 CALLDATASIZE: "CALLDATASIZE", 262 CALLDATACOPY: "CALLDATACOPY", 263 CODESIZE: "CODESIZE", 264 CODECOPY: "CODECOPY", 265 GASPRICE: "GASPRICE", 266 EXTCODESIZE: "EXTCODESIZE", 267 EXTCODECOPY: "EXTCODECOPY", 268 RETURNDATASIZE: "RETURNDATASIZE", 269 RETURNDATACOPY: "RETURNDATACOPY", 270 EXTCODEHASH: "EXTCODEHASH", 271 272 // 0x40 range - block operations 273 BLOCKHASH: "BLOCKHASH", 274 COINBASE: "COINBASE", 275 TIMESTAMP: "TIMESTAMP", 276 NUMBER: "NUMBER", 277 DIFFICULTY: "DIFFICULTY", 278 GASLIMIT: "GASLIMIT", 279 CHAINID: "CHAINID", 280 SELFBALANCE: "SELFBALANCE", 281 282 // 0x50 range - 'storage' and execution 283 POP: "POP", 284 //DUP: "DUP", 285 //SWAP: "SWAP", 286 MLOAD: "MLOAD", 287 MSTORE: "MSTORE", 288 MSTORE8: "MSTORE8", 289 SLOAD: "SLOAD", 290 SSTORE: "SSTORE", 291 JUMP: "JUMP", 292 JUMPI: "JUMPI", 293 PC: "PC", 294 MSIZE: "MSIZE", 295 GAS: "GAS", 296 JUMPDEST: "JUMPDEST", 297 298 // 0x60 range - push 299 PUSH1: "PUSH1", 300 PUSH2: "PUSH2", 301 PUSH3: "PUSH3", 302 PUSH4: "PUSH4", 303 PUSH5: "PUSH5", 304 PUSH6: "PUSH6", 305 PUSH7: "PUSH7", 306 PUSH8: "PUSH8", 307 PUSH9: "PUSH9", 308 PUSH10: "PUSH10", 309 PUSH11: "PUSH11", 310 PUSH12: "PUSH12", 311 PUSH13: "PUSH13", 312 PUSH14: "PUSH14", 313 PUSH15: "PUSH15", 314 PUSH16: "PUSH16", 315 PUSH17: "PUSH17", 316 PUSH18: "PUSH18", 317 PUSH19: "PUSH19", 318 PUSH20: "PUSH20", 319 PUSH21: "PUSH21", 320 PUSH22: "PUSH22", 321 PUSH23: "PUSH23", 322 PUSH24: "PUSH24", 323 PUSH25: "PUSH25", 324 PUSH26: "PUSH26", 325 PUSH27: "PUSH27", 326 PUSH28: "PUSH28", 327 PUSH29: "PUSH29", 328 PUSH30: "PUSH30", 329 PUSH31: "PUSH31", 330 PUSH32: "PUSH32", 331 332 DUP1: "DUP1", 333 DUP2: "DUP2", 334 DUP3: "DUP3", 335 DUP4: "DUP4", 336 DUP5: "DUP5", 337 DUP6: "DUP6", 338 DUP7: "DUP7", 339 DUP8: "DUP8", 340 DUP9: "DUP9", 341 DUP10: "DUP10", 342 DUP11: "DUP11", 343 DUP12: "DUP12", 344 DUP13: "DUP13", 345 DUP14: "DUP14", 346 DUP15: "DUP15", 347 DUP16: "DUP16", 348 349 SWAP1: "SWAP1", 350 SWAP2: "SWAP2", 351 SWAP3: "SWAP3", 352 SWAP4: "SWAP4", 353 SWAP5: "SWAP5", 354 SWAP6: "SWAP6", 355 SWAP7: "SWAP7", 356 SWAP8: "SWAP8", 357 SWAP9: "SWAP9", 358 SWAP10: "SWAP10", 359 SWAP11: "SWAP11", 360 SWAP12: "SWAP12", 361 SWAP13: "SWAP13", 362 SWAP14: "SWAP14", 363 SWAP15: "SWAP15", 364 SWAP16: "SWAP16", 365 LOG0: "LOG0", 366 LOG1: "LOG1", 367 LOG2: "LOG2", 368 LOG3: "LOG3", 369 LOG4: "LOG4", 370 371 // 0xf0 range 372 CREATE: "CREATE", 373 CALL: "CALL", 374 RETURN: "RETURN", 375 CALLCODE: "CALLCODE", 376 DELEGATECALL: "DELEGATECALL", 377 CREATE2: "CREATE2", 378 STATICCALL: "STATICCALL", 379 REVERT: "REVERT", 380 SELFDESTRUCT: "SELFDESTRUCT", 381 382 PUSH: "PUSH", 383 DUP: "DUP", 384 SWAP: "SWAP", 385 386 INVALID: "INVALID", 387 } 388 389 func (o OpCode) String() string { 390 str := opCodeToString[o] 391 if len(str) == 0 { 392 return fmt.Sprintf("Missing opcode 0x%x", int(o)) 393 } 394 395 return str 396 } 397 398 var stringToOp = map[string]OpCode{ 399 "STOP": STOP, 400 "ADD": ADD, 401 "MUL": MUL, 402 "SUB": SUB, 403 "DIV": DIV, 404 "SDIV": SDIV, 405 "MOD": MOD, 406 "SMOD": SMOD, 407 "EXP": EXP, 408 "NOT": NOT, 409 "LT": LT, 410 "GT": GT, 411 "SLT": SLT, 412 "SGT": SGT, 413 "EQ": EQ, 414 "ISZERO": ISZERO, 415 "SIGNEXTEND": SIGNEXTEND, 416 "AND": AND, 417 "OR": OR, 418 "XOR": XOR, 419 "BYTE": BYTE, 420 "ADDMOD": ADDMOD, 421 "MULMOD": MULMOD, 422 "KECCAK256": KECCAK256, 423 "ADDRESS": ADDRESS, 424 "BALANCE": BALANCE, 425 "ORIGIN": ORIGIN, 426 "CALLER": CALLER, 427 "CALLVALUE": CALLVALUE, 428 "CALLDATALOAD": CALLDATALOAD, 429 "CALLDATASIZE": CALLDATASIZE, 430 "CALLDATACOPY": CALLDATACOPY, 431 "DELEGATECALL": DELEGATECALL, 432 "STATICCALL": STATICCALL, 433 "CODESIZE": CODESIZE, 434 "CODECOPY": CODECOPY, 435 "GASPRICE": GASPRICE, 436 "EXTCODESIZE": EXTCODESIZE, 437 "EXTCODECOPY": EXTCODECOPY, 438 "RETURNDATASIZE": RETURNDATASIZE, 439 "RETURNDATACOPY": RETURNDATACOPY, 440 "BLOCKHASH": BLOCKHASH, 441 "COINBASE": COINBASE, 442 "TIMESTAMP": TIMESTAMP, 443 "NUMBER": NUMBER, 444 "DIFFICULTY": DIFFICULTY, 445 "GASLIMIT": GASLIMIT, 446 "POP": POP, 447 "MLOAD": MLOAD, 448 "MSTORE": MSTORE, 449 "MSTORE8": MSTORE8, 450 "SLOAD": SLOAD, 451 "SSTORE": SSTORE, 452 "JUMP": JUMP, 453 "JUMPI": JUMPI, 454 "PC": PC, 455 "MSIZE": MSIZE, 456 "GAS": GAS, 457 "JUMPDEST": JUMPDEST, 458 "PUSH1": PUSH1, 459 "PUSH2": PUSH2, 460 "PUSH3": PUSH3, 461 "PUSH4": PUSH4, 462 "PUSH5": PUSH5, 463 "PUSH6": PUSH6, 464 "PUSH7": PUSH7, 465 "PUSH8": PUSH8, 466 "PUSH9": PUSH9, 467 "PUSH10": PUSH10, 468 "PUSH11": PUSH11, 469 "PUSH12": PUSH12, 470 "PUSH13": PUSH13, 471 "PUSH14": PUSH14, 472 "PUSH15": PUSH15, 473 "PUSH16": PUSH16, 474 "PUSH17": PUSH17, 475 "PUSH18": PUSH18, 476 "PUSH19": PUSH19, 477 "PUSH20": PUSH20, 478 "PUSH21": PUSH21, 479 "PUSH22": PUSH22, 480 "PUSH23": PUSH23, 481 "PUSH24": PUSH24, 482 "PUSH25": PUSH25, 483 "PUSH26": PUSH26, 484 "PUSH27": PUSH27, 485 "PUSH28": PUSH28, 486 "PUSH29": PUSH29, 487 "PUSH30": PUSH30, 488 "PUSH31": PUSH31, 489 "PUSH32": PUSH32, 490 "DUP1": DUP1, 491 "DUP2": DUP2, 492 "DUP3": DUP3, 493 "DUP4": DUP4, 494 "DUP5": DUP5, 495 "DUP6": DUP6, 496 "DUP7": DUP7, 497 "DUP8": DUP8, 498 "DUP9": DUP9, 499 "DUP10": DUP10, 500 "DUP11": DUP11, 501 "DUP12": DUP12, 502 "DUP13": DUP13, 503 "DUP14": DUP14, 504 "DUP15": DUP15, 505 "DUP16": DUP16, 506 "SWAP1": SWAP1, 507 "SWAP2": SWAP2, 508 "SWAP3": SWAP3, 509 "SWAP4": SWAP4, 510 "SWAP5": SWAP5, 511 "SWAP6": SWAP6, 512 "SWAP7": SWAP7, 513 "SWAP8": SWAP8, 514 "SWAP9": SWAP9, 515 "SWAP10": SWAP10, 516 "SWAP11": SWAP11, 517 "SWAP12": SWAP12, 518 "SWAP13": SWAP13, 519 "SWAP14": SWAP14, 520 "SWAP15": SWAP15, 521 "SWAP16": SWAP16, 522 "LOG0": LOG0, 523 "LOG1": LOG1, 524 "LOG2": LOG2, 525 "LOG3": LOG3, 526 "LOG4": LOG4, 527 "CREATE": CREATE, 528 "CALL": CALL, 529 "RETURN": RETURN, 530 "CALLCODE": CALLCODE, 531 "REVERT": REVERT, 532 "SELFDESTRUCT": SELFDESTRUCT, 533 "INVALID": INVALID, 534 } 535 536 func StringToOp(str string) OpCode { 537 return stringToOp[str] 538 }