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