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  }