github.com/mavryk-network/mvgo@v1.19.9/micheline/opcodes.go (about) 1 // Copyright (c) 2020-2021 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package micheline 5 6 import ( 7 "fmt" 8 ) 9 10 type OpCode byte 11 12 func (o OpCode) Byte() byte { 13 return byte(o) 14 } 15 16 // Michelson V1 Primitives 17 const ( 18 // Keys 19 K_PARAMETER OpCode = iota // 00 20 K_STORAGE // 01 21 K_CODE // 02 22 23 // Data 24 D_FALSE // 03 25 D_ELT // 04 26 D_LEFT // 05 27 D_NONE // 06 28 D_PAIR // 07 29 D_RIGHT // 08 30 D_SOME // 09 31 D_TRUE // 0A 32 D_UNIT // 0B 33 34 // instructions 35 I_PACK // 0C 36 I_UNPACK // 0D 37 I_BLAKE2B // 0E 38 I_SHA256 // 0F 39 I_SHA512 // 10 40 I_ABS // 11 41 I_ADD // 12 42 I_AMOUNT // 13 43 I_AND // 14 44 I_BALANCE // 15 45 I_CAR // 16 46 I_CDR // 17 47 I_CHECK_SIGNATURE // 18 48 I_COMPARE // 19 49 I_CONCAT // 1A 50 I_CONS // 1B 51 I_CREATE_ACCOUNT // 1C 52 I_CREATE_CONTRACT // 1D 53 I_IMPLICIT_ACCOUNT // 1E 54 I_DIP // 1F 55 I_DROP // 20 56 I_DUP // 21 57 I_EDIV // 22 58 I_EMPTY_MAP // 23 59 I_EMPTY_SET // 24 60 I_EQ // 25 61 I_EXEC // 26 62 I_FAILWITH // 27 63 I_GE // 28 64 I_GET // 29 65 I_GT // 2A 66 I_HASH_KEY // 2B 67 I_IF // 2C 68 I_IF_CONS // 2D 69 I_IF_LEFT // 2E 70 I_IF_NONE // 2F 71 I_INT // 30 72 I_LAMBDA // 31 73 I_LE // 32 74 I_LEFT // 33 75 I_LOOP // 34 76 I_LSL // 35 77 I_LSR // 36 78 I_LT // 37 79 I_MAP // 38 80 I_MEM // 39 81 I_MUL // 3A 82 I_NEG // 3B 83 I_NEQ // 3C 84 I_NIL // 3D 85 I_NONE // 3E 86 I_NOT // 3F 87 I_NOW // 40 88 I_OR // 41 89 I_PAIR // 42 90 I_PUSH // 43 91 I_RIGHT // 44 92 I_SIZE // 45 93 I_SOME // 46 94 I_SOURCE // 47 95 I_SENDER // 48 96 I_SELF // 49 97 I_STEPS_TO_QUOTA // 4A 98 I_SUB // 4B 99 I_SWAP // 4C 100 I_TRANSFER_TOKENS // 4D 101 I_SET_DELEGATE // 4E 102 I_UNIT // 4F 103 I_UPDATE // 50 104 I_XOR // 51 105 I_ITER // 52 106 I_LOOP_LEFT // 53 107 I_ADDRESS // 54 108 I_CONTRACT // 55 109 I_ISNAT // 56 110 I_CAST // 57 111 I_RENAME // 58 112 113 // Types 114 T_BOOL // 59 115 T_CONTRACT // 5A 116 T_INT // 5B 117 T_KEY // 5C 118 T_KEY_HASH // 5D 119 T_LAMBDA // 5E 120 T_LIST // 5F 121 T_MAP // 60 122 T_BIG_MAP // 61 123 T_NAT // 62 124 T_OPTION // 63 125 T_OR // 64 126 T_PAIR // 65 127 T_SET // 66 128 T_SIGNATURE // 67 129 T_STRING // 68 130 T_BYTES // 69 131 T_MUMAV // 6A 132 T_TIMESTAMP // 6B 133 T_UNIT // 6C 134 T_OPERATION // 6D 135 T_ADDRESS // 6E 136 137 // v002 addition 138 I_SLICE // 6F 139 140 // v005 addition 141 // https://blog.nomadic-labs.com/michelson-updates-in-005.html 142 I_DIG // 70 143 I_DUG // 71 144 I_EMPTY_BIG_MAP // 72 145 I_APPLY // 73 146 T_CHAIN_ID // 74 147 I_CHAIN_ID // 75 148 149 // v008 additions 150 I_LEVEL // 76 151 I_SELF_ADDRESS // 77 152 T_NEVER // 78 153 I_NEVER // 79 154 I_UNPAIR // 7A 155 I_VOTING_POWER // 7B 156 I_TOTAL_VOTING_POWER // 7C 157 I_KECCAK // 7D 158 I_SHA3 // 7E 159 I_PAIRING_CHECK // 7F 160 T_BLS12_381_G1 // 80 161 T_BLS12_381_G2 // 81 162 T_BLS12_381_FR // 82 163 T_SAPLING_STATE // 83 164 _T_SAPLING_TRANSACTION // 84, deprecated in v013 165 I_SAPLING_EMPTY_STATE // 85 166 I_SAPLING_VERIFY_UPDATE // 86 167 T_TICKET // 87 168 _I_TICKET // 88, deprecated in v015 169 I_READ_TICKET // 89 170 I_SPLIT_TICKET // 8A 171 I_JOIN_TICKETS // 8B 172 I_GET_AND_UPDATE // 8C 173 174 // v011 additions 175 T_CHEST // 8D 176 T_CHEST_KEY // 8E 177 I_OPEN_CHEST // 8F 178 I_VIEW // 90 179 K_VIEW // 91 180 H_CONSTANT // 92 181 182 // v012 additions 183 I_SUB_MUMAV // 93 184 185 // v013 additions 186 T_TX_ROLLUP_L2_ADDRESS // 94 187 I_MIN_BLOCK_TIME // 95 188 T_SAPLING_TRANSACTION // 96 189 190 // v014 additions 191 I_EMIT // 97 192 193 // v015 additions 194 D_LAMBDA_REC // 98 195 I_LAMBDA_REC // 99 196 I_TICKET // 9A 197 198 // v016 additions 199 I_BYTES // 9B 200 I_NAT // 9C 201 202 // v19 additions 203 D_TICKET 204 ) 205 206 func (op OpCode) IsValid() bool { 207 return op <= I_NAT 208 } 209 210 var ( 211 opCodeToString = map[OpCode]string{ 212 K_PARAMETER: "parameter", 213 K_STORAGE: "storage", 214 K_CODE: "code", 215 D_FALSE: "False", 216 D_ELT: "Elt", 217 D_LEFT: "Left", 218 D_NONE: "None", 219 D_PAIR: "Pair", 220 D_RIGHT: "Right", 221 D_SOME: "Some", 222 D_TRUE: "True", 223 D_UNIT: "Unit", 224 I_PACK: "PACK", 225 I_UNPACK: "UNPACK", 226 I_BLAKE2B: "BLAKE2B", 227 I_SHA256: "SHA256", 228 I_SHA512: "SHA512", 229 I_ABS: "ABS", 230 I_ADD: "ADD", 231 I_AMOUNT: "AMOUNT", 232 I_AND: "AND", 233 I_BALANCE: "BALANCE", 234 I_CAR: "CAR", 235 I_CDR: "CDR", 236 I_CHECK_SIGNATURE: "CHECK_SIGNATURE", 237 I_COMPARE: "COMPARE", 238 I_CONCAT: "CONCAT", 239 I_CONS: "CONS", 240 I_CREATE_ACCOUNT: "CREATE_ACCOUNT", 241 I_CREATE_CONTRACT: "CREATE_CONTRACT", 242 I_IMPLICIT_ACCOUNT: "IMPLICIT_ACCOUNT", 243 I_DIP: "DIP", 244 I_DROP: "DROP", 245 I_DUP: "DUP", 246 I_EDIV: "EDIV", 247 I_EMPTY_MAP: "EMPTY_MAP", 248 I_EMPTY_SET: "EMPTY_SET", 249 I_EQ: "EQ", 250 I_EXEC: "EXEC", 251 I_FAILWITH: "FAILWITH", 252 I_GE: "GE", 253 I_GET: "GET", 254 I_GT: "GT", 255 I_HASH_KEY: "HASH_KEY", 256 I_IF: "IF", 257 I_IF_CONS: "IF_CONS", 258 I_IF_LEFT: "IF_LEFT", 259 I_IF_NONE: "IF_NONE", 260 I_INT: "INT", 261 I_LAMBDA: "LAMBDA", 262 I_LE: "LE", 263 I_LEFT: "LEFT", 264 I_LOOP: "LOOP", 265 I_LSL: "LSL", 266 I_LSR: "LSR", 267 I_LT: "LT", 268 I_MAP: "MAP", 269 I_MEM: "MEM", 270 I_MUL: "MUL", 271 I_NEG: "NEG", 272 I_NEQ: "NEQ", 273 I_NIL: "NIL", 274 I_NONE: "NONE", 275 I_NOT: "NOT", 276 I_NOW: "NOW", 277 I_OR: "OR", 278 I_PAIR: "PAIR", 279 I_PUSH: "PUSH", 280 I_RIGHT: "RIGHT", 281 I_SIZE: "SIZE", 282 I_SOME: "SOME", 283 I_SOURCE: "SOURCE", 284 I_SENDER: "SENDER", 285 I_SELF: "SELF", 286 I_STEPS_TO_QUOTA: "STEPS_TO_QUOTA", 287 I_SUB: "SUB", 288 I_SWAP: "SWAP", 289 I_TRANSFER_TOKENS: "TRANSFER_TOKENS", 290 I_SET_DELEGATE: "SET_DELEGATE", 291 I_UNIT: "UNIT", 292 I_UPDATE: "UPDATE", 293 I_XOR: "XOR", 294 I_ITER: "ITER", 295 I_LOOP_LEFT: "LOOP_LEFT", 296 I_ADDRESS: "ADDRESS", 297 I_CONTRACT: "CONTRACT", 298 I_ISNAT: "ISNAT", 299 I_CAST: "CAST", 300 I_RENAME: "RENAME", 301 T_BOOL: "bool", 302 T_CONTRACT: "contract", 303 T_INT: "int", 304 T_KEY: "key", 305 T_KEY_HASH: "key_hash", 306 T_LAMBDA: "lambda", 307 T_LIST: "list", 308 T_MAP: "map", 309 T_BIG_MAP: "big_map", 310 T_NAT: "nat", 311 T_OPTION: "option", 312 T_OR: "or", 313 T_PAIR: "pair", 314 T_SET: "set", 315 T_SIGNATURE: "signature", 316 T_STRING: "string", 317 T_BYTES: "bytes", 318 T_MUMAV: "mumav", 319 T_TIMESTAMP: "timestamp", 320 T_UNIT: "unit", 321 T_OPERATION: "operation", 322 T_ADDRESS: "address", 323 I_SLICE: "SLICE", 324 I_DIG: "DIG", 325 I_DUG: "DUG", 326 I_EMPTY_BIG_MAP: "EMPTY_BIG_MAP", 327 I_APPLY: "APPLY", 328 T_CHAIN_ID: "chain_id", 329 I_CHAIN_ID: "CHAIN_ID", 330 I_LEVEL: "LEVEL", 331 I_SELF_ADDRESS: "SELF_ADDRESS", 332 T_NEVER: "never", 333 I_NEVER: "NEVER", 334 I_UNPAIR: "UNPAIR", 335 I_VOTING_POWER: "VOTING_POWER", 336 I_TOTAL_VOTING_POWER: "TOTAL_VOTING_POWER", 337 I_KECCAK: "KECCAK", 338 I_SHA3: "SHA3", 339 I_PAIRING_CHECK: "PAIRING_CHECK", 340 T_BLS12_381_G1: "bls12_381_g1", 341 T_BLS12_381_G2: "bls12_381_g2", 342 T_BLS12_381_FR: "bls12_381_fr", 343 T_SAPLING_STATE: "sapling_state", 344 _T_SAPLING_TRANSACTION: "sapling_transaction_deprecated", 345 I_SAPLING_EMPTY_STATE: "SAPLING_EMPTY_STATE", 346 I_SAPLING_VERIFY_UPDATE: "SAPLING_VERIFY_UPDATE", 347 T_TICKET: "ticket", 348 _I_TICKET: "TICKET_DEPRECATED", 349 I_READ_TICKET: "READ_TICKET", 350 I_SPLIT_TICKET: "SPLIT_TICKET", 351 I_JOIN_TICKETS: "JOIN_TICKETS", 352 I_GET_AND_UPDATE: "GET_AND_UPDATE", 353 T_CHEST: "chest", 354 T_CHEST_KEY: "chest_key", 355 I_OPEN_CHEST: "OPEN_CHEST", 356 I_VIEW: "VIEW", 357 K_VIEW: "view", 358 H_CONSTANT: "constant", 359 I_SUB_MUMAV: "SUB_MUMAV", 360 T_TX_ROLLUP_L2_ADDRESS: "tx_rollup_l2_address", 361 I_MIN_BLOCK_TIME: "MIN_BLOCK_TIME", 362 T_SAPLING_TRANSACTION: "sapling_transaction", 363 I_EMIT: "EMIT", 364 D_LAMBDA_REC: "Lambda_rec", 365 I_LAMBDA_REC: "LAMBDA_REC", 366 I_TICKET: "TICKET", 367 I_BYTES: "BYTES", 368 I_NAT: "NAT", 369 D_TICKET: "Ticket", 370 } 371 stringToOp map[string]OpCode 372 ) 373 374 func init() { 375 stringToOp = make(map[string]OpCode) 376 for n, v := range opCodeToString { 377 stringToOp[v] = n 378 } 379 } 380 381 func (op OpCode) String() string { 382 str, ok := opCodeToString[op] 383 if !ok { 384 return fmt.Sprintf("Unknown michelson opcode 0x%x", int(op)) 385 } 386 return str 387 } 388 389 func (op OpCode) MarshalText() ([]byte, error) { 390 return []byte(op.String()), nil 391 } 392 393 func ParseOpCode(str string) (OpCode, error) { 394 op, ok := stringToOp[str] 395 if !ok { 396 return 255, fmt.Errorf("Unknown michelson primitive %s", str) 397 } 398 return op, nil 399 } 400 401 func (op OpCode) IsTypeCode() bool { 402 switch op { 403 case T_BOOL, 404 T_CONTRACT, 405 T_INT, 406 T_KEY, 407 T_KEY_HASH, 408 T_LAMBDA, 409 T_LIST, 410 T_MAP, 411 T_BIG_MAP, 412 T_NAT, 413 T_OPTION, 414 T_OR, 415 T_PAIR, 416 T_SET, 417 T_SIGNATURE, 418 T_STRING, 419 T_BYTES, 420 T_MUMAV, 421 T_TIMESTAMP, 422 T_UNIT, 423 T_OPERATION, 424 T_ADDRESS, 425 T_CHAIN_ID, 426 T_NEVER, 427 T_BLS12_381_G1, 428 T_BLS12_381_G2, 429 T_BLS12_381_FR, 430 T_SAPLING_STATE, 431 T_SAPLING_TRANSACTION, 432 T_TICKET, 433 T_CHEST, 434 T_CHEST_KEY, 435 T_TX_ROLLUP_L2_ADDRESS: 436 return true 437 default: 438 return false 439 } 440 } 441 442 func (op OpCode) IsKeyCode() bool { 443 switch op { 444 case K_PARAMETER, K_STORAGE, K_CODE: 445 return true 446 default: 447 return false 448 } 449 } 450 451 func (op OpCode) TypeCode() OpCode { 452 if op.IsTypeCode() { 453 return op 454 } 455 switch op { 456 case K_PARAMETER, K_STORAGE, K_CODE, K_VIEW, D_UNIT: 457 return T_UNIT 458 case D_FALSE, D_TRUE: 459 return T_BOOL 460 case D_LEFT, D_RIGHT: 461 return T_OR 462 case D_NONE, D_SOME: 463 return T_OPTION 464 case D_PAIR: 465 return T_PAIR 466 case D_ELT: 467 return T_MAP // may also be T_BIG_MAP 468 case D_LAMBDA_REC: 469 return T_LAMBDA 470 case D_TICKET: 471 return T_TICKET 472 default: 473 return T_LAMBDA 474 } 475 } 476 477 func (op OpCode) PrimType() PrimType { 478 switch op { 479 case T_INT, T_NAT, T_MUMAV, T_TIMESTAMP: 480 return PrimInt 481 case T_STRING: 482 return PrimString 483 default: 484 return PrimBytes 485 } 486 }