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