github.com/mavryk-network/mvgo@v1.19.9/mavryk/hash.go (about)

     1  // Copyright (c) 2020-2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package mavryk
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/binary"
     9  	"errors"
    10  	"fmt"
    11  
    12  	"github.com/mavryk-network/mvgo/base58"
    13  )
    14  
    15  var (
    16  	// ErrUnknownHashType describes an error where a hash can not
    17  	// decoded as a specific hash type because the string encoding
    18  	// starts with an unknown identifier.
    19  	ErrUnknownHashType = errors.New("tezos: unknown hash type")
    20  
    21  	// Zero hashes
    22  	ZeroChainIdHash           = NewChainIdHash(nil)
    23  	ZeroBlockHash             = NewBlockHash(nil)
    24  	ZeroProtocolHash          = NewProtocolHash(nil)
    25  	ZeroOpHash                = NewOpHash(nil)
    26  	ZeroOpListListHash        = NewOpListListHash(nil)
    27  	ZeroPayloadHash           = NewPayloadHash(nil)
    28  	ZeroExprHash              = NewExprHash(nil)
    29  	ZeroNonceHash             = NewNonceHash(nil)
    30  	ZeroContextHash           = NewContextHash(nil)
    31  	ZeroSmartRollupStateHash  = NewSmartRollupStateHash(nil)
    32  	ZeroSmartRollupCommitHash = NewSmartRollupCommitHash(nil)
    33  )
    34  
    35  type HashType struct {
    36  	Id        []byte
    37  	Len       int
    38  	B58Prefix string
    39  	B58Len    int
    40  }
    41  
    42  var (
    43  	HashTypeInvalid              = HashType{nil, 0, "", 0}
    44  	HashTypeChainId              = HashType{CHAIN_ID, 4, CHAIN_ID_PREFIX, 15}
    45  	HashTypeId                   = HashType{ID_HASH_ID, 16, ID_HASH_PREFIX, 36}
    46  	HashTypePkhEd25519           = HashType{ED25519_PUBLIC_KEY_HASH_ID, 20, ED25519_PUBLIC_KEY_HASH_PREFIX, 36}
    47  	HashTypePkhSecp256k1         = HashType{SECP256K1_PUBLIC_KEY_HASH_ID, 20, SECP256K1_PUBLIC_KEY_HASH_PREFIX, 36}
    48  	HashTypePkhP256              = HashType{P256_PUBLIC_KEY_HASH_ID, 20, P256_PUBLIC_KEY_HASH_PREFIX, 36}
    49  	HashTypePkhNocurve           = HashType{NOCURVE_PUBLIC_KEY_HASH_ID, 20, NOCURVE_PUBLIC_KEY_HASH_PREFIX, 36}
    50  	HashTypePkhBlinded           = HashType{BLINDED_PUBLIC_KEY_HASH_ID, 20, BLINDED_PUBLIC_KEY_HASH_PREFIX, 37}
    51  	HashTypeBlock                = HashType{BLOCK_HASH_ID, 32, BLOCK_HASH_PREFIX, 51}
    52  	HashTypeOperation            = HashType{OPERATION_HASH_ID, 32, OPERATION_HASH_PREFIX, 51}
    53  	HashTypeOperationList        = HashType{OPERATION_LIST_HASH_ID, 32, OPERATION_LIST_HASH_PREFIX, 52}
    54  	HashTypeOperationListList    = HashType{OPERATION_LIST_LIST_HASH_ID, 32, OPERATION_LIST_LIST_HASH_PREFIX, 53}
    55  	HashTypeProtocol             = HashType{PROTOCOL_HASH_ID, 32, PROTOCOL_HASH_PREFIX, 51}
    56  	HashTypeContext              = HashType{CONTEXT_HASH_ID, 32, CONTEXT_HASH_PREFIX, 52}
    57  	HashTypeNonce                = HashType{NONCE_HASH_ID, 32, NONCE_HASH_PREFIX, 53}
    58  	HashTypeSeedEd25519          = HashType{ED25519_SEED_ID, 32, ED25519_SEED_PREFIX, 54}
    59  	HashTypePkEd25519            = HashType{ED25519_PUBLIC_KEY_ID, 32, ED25519_PUBLIC_KEY_PREFIX, 54}
    60  	HashTypeSkEd25519            = HashType{ED25519_SECRET_KEY_ID, 64, ED25519_SECRET_KEY_PREFIX, 98}
    61  	HashTypePkSecp256k1          = HashType{SECP256K1_PUBLIC_KEY_ID, 33, SECP256K1_PUBLIC_KEY_PREFIX, 55}
    62  	HashTypeSkSecp256k1          = HashType{SECP256K1_SECRET_KEY_ID, 32, SECP256K1_SECRET_KEY_PREFIX, 54}
    63  	HashTypePkP256               = HashType{P256_PUBLIC_KEY_ID, 33, P256_PUBLIC_KEY_PREFIX, 55}
    64  	HashTypeSkP256               = HashType{P256_SECRET_KEY_ID, 32, P256_SECRET_KEY_PREFIX, 54}
    65  	HashTypeScalarSecp256k1      = HashType{SECP256K1_SCALAR_ID, 33, SECP256K1_SCALAR_PREFIX, 53}
    66  	HashTypeElementSecp256k1     = HashType{SECP256K1_ELEMENT_ID, 33, SECP256K1_ELEMENT_PREFIX, 54}
    67  	HashTypeScriptExpr           = HashType{SCRIPT_EXPR_HASH_ID, 32, SCRIPT_EXPR_HASH_PREFIX, 54}
    68  	HashTypeEncryptedSeedEd25519 = HashType{ED25519_ENCRYPTED_SEED_ID, 56, ED25519_ENCRYPTED_SEED_PREFIX, 88}
    69  	HashTypeEncryptedSkSecp256k1 = HashType{SECP256K1_ENCRYPTED_SECRET_KEY_ID, 56, SECP256K1_ENCRYPTED_SECRET_KEY_PREFIX, 88}
    70  	HashTypeEncryptedSkP256      = HashType{P256_ENCRYPTED_SECRET_KEY_ID, 56, P256_ENCRYPTED_SECRET_KEY_PREFIX, 88}
    71  	HashTypeSigEd25519           = HashType{ED25519_SIGNATURE_ID, 64, ED25519_SIGNATURE_PREFIX, 99}
    72  	HashTypeSigSecp256k1         = HashType{SECP256K1_SIGNATURE_ID, 64, SECP256K1_SIGNATURE_PREFIX, 99}
    73  	HashTypeSigP256              = HashType{P256_SIGNATURE_ID, 64, P256_SIGNATURE_PREFIX, 98}
    74  	HashTypeSigGeneric           = HashType{GENERIC_SIGNATURE_ID, 64, GENERIC_SIGNATURE_PREFIX, 96}
    75  
    76  	HashTypeBlockPayload              = HashType{BLOCK_PAYLOAD_HASH_ID, 32, BLOCK_PAYLOAD_HASH_PREFIX, 52}
    77  	HashTypeBlockMetadata             = HashType{BLOCK_METADATA_HASH_ID, 32, BLOCK_METADATA_HASH_PREFIX, 52}
    78  	HashTypeOperationMetadata         = HashType{OPERATION_METADATA_HASH_ID, 32, OPERATION_METADATA_HASH_PREFIX, 51}
    79  	HashTypeOperationMetadataList     = HashType{OPERATION_METADATA_LIST_HASH_ID, 32, OPERATION_METADATA_LIST_HASH_PREFIX, 52}
    80  	HashTypeOperationMetadataListList = HashType{OPERATION_METADATA_LIST_LIST_HASH_ID, 32, OPERATION_METADATA_LIST_LIST_HASH_PREFIX, 53}
    81  	HashTypeEncryptedSecp256k1Scalar  = HashType{SECP256K1_ENCRYPTED_SCALAR_ID, 60, SECP256K1_ENCRYPTED_SCALAR_PREFIX, 93}
    82  	HashTypeSaplingSpendingKey        = HashType{SAPLING_SPENDING_KEY_ID, 169, SAPLING_SPENDING_KEY_PREFIX, 241}
    83  	HashTypeSaplingAddress            = HashType{SAPLING_ADDRESS_ID, 43, SAPLING_ADDRESS_PREFIX, 69}
    84  
    85  	HashTypePkhBls12_381              = HashType{BLS12_381_PUBLIC_KEY_HASH_ID, 20, BLS12_381_PUBLIC_KEY_HASH_PREFIX, 36}
    86  	HashTypeSigGenericAggregate       = HashType{GENERIC_AGGREGATE_SIGNATURE_ID, 96, GENERIC_AGGREGATE_SIGNATURE_PREFIX, 141}
    87  	HashTypeSigBls12_381              = HashType{BLS12_381_SIGNATURE_ID, 96, BLS12_381_SIGNATURE_PREFIX, 142}
    88  	HashTypePkBls12_381               = HashType{BLS12_381_PUBLIC_KEY_ID, 48, BLS12_381_PUBLIC_KEY_PREFIX, 76}
    89  	HashTypeSkBls12_381               = HashType{BLS12_381_SECRET_KEY_ID, 32, BLS12_381_SECRET_KEY_PREFIX, 54}
    90  	HashTypeEncryptedSkBls12_381      = HashType{BLS12_381_ENCRYPTED_SECRET_KEY_ID, 58, BLS12_381_ENCRYPTED_SECRET_KEY_PREFIX, 88}
    91  	HashTypeTxRollupAddress           = HashType{TX_ROLLUP_ADDRESS_ID, 20, TX_ROLLUP_ADDRESS_PREFIX, 37}
    92  	HashTypeTxRollupInbox             = HashType{TX_ROLLUP_INBOX_HASH_ID, 32, TX_ROLLUP_INBOX_HASH_PREFIX, 53}
    93  	HashTypeTxRollupMessage           = HashType{TX_ROLLUP_MESSAGE_HASH_ID, 32, TX_ROLLUP_MESSAGE_HASH_PREFIX, 53}
    94  	HashTypeTxRollupCommitment        = HashType{TX_ROLLUP_COMMITMENT_HASH_ID, 32, TX_ROLLUP_COMMITMENT_HASH_PREFIX, 53}
    95  	HashTypeTxRollupMessageResult     = HashType{TX_ROLLUP_MESSAGE_RESULT_HASH_ID, 32, TX_ROLLUP_MESSAGE_RESULT_HASH_PREFIX, 54}
    96  	HashTypeTxRollupMessageResultList = HashType{TX_ROLLUP_MESSAGE_RESULT_LIST_HASH_ID, 32, TX_ROLLUP_MESSAGE_RESULT_LIST_HASH_PREFIX, 53}
    97  	HashTypeTxRollupWithdrawList      = HashType{TX_ROLLUP_WITHDRAW_LIST_HASH_ID, 32, TX_ROLLUP_WITHDRAW_LIST_HASH_PREFIX, 53}
    98  	HashTypeSmartRollupAddress        = HashType{SMART_ROLLUP_ADDRESS_ID, 20, SMART_ROLLUP_ADDRESS_PREFIX, 36}
    99  	HashTypeSmartRollupStateHash      = HashType{SMART_ROLLUP_STATE_HASH_ID, 32, SMART_ROLLUP_STATE_HASH_PREFIX, 54}
   100  	HashTypeSmartRollupCommitHash     = HashType{SMART_ROLLUP_COMMITMENT_HASH_ID, 32, SMART_ROLLUP_COMMITMENT_HASH_PREFIX, 54}
   101  	HashTypeSmartRollupRevealHash     = HashType{SMART_ROLLUP_REVEAL_HASH_ID, 32, SMART_ROLLUP_REVEAL_HASH_PREFIX, 56}
   102  )
   103  
   104  func (t HashType) IsValid() bool {
   105  	return len(t.Id) > 0
   106  }
   107  
   108  func (t HashType) String() string {
   109  	return t.B58Prefix
   110  }
   111  
   112  func (t HashType) Equal(x HashType) bool {
   113  	return t.B58Prefix == x.B58Prefix
   114  }
   115  
   116  // ChainIdHash
   117  type ChainIdHash [4]byte
   118  
   119  func NewChainIdHash(buf []byte) (h ChainIdHash) {
   120  	copy(h[:], buf)
   121  	return
   122  }
   123  
   124  func (h ChainIdHash) IsValid() bool {
   125  	return !h.Equal(ZeroChainIdHash)
   126  }
   127  
   128  func (h ChainIdHash) Equal(h2 ChainIdHash) bool {
   129  	return h == h2
   130  }
   131  
   132  func (h ChainIdHash) Clone() ChainIdHash {
   133  	return NewChainIdHash(h[:])
   134  }
   135  
   136  func (h ChainIdHash) String() string {
   137  	return base58.CheckEncode(h[:], HashTypeChainId.Id)
   138  }
   139  
   140  func (h ChainIdHash) Bytes() []byte {
   141  	return h[:]
   142  }
   143  
   144  func (h ChainIdHash) MarshalText() ([]byte, error) {
   145  	return []byte(h.String()), nil
   146  }
   147  
   148  func (h *ChainIdHash) UnmarshalText(buf []byte) error {
   149  	if len(buf) == 0 {
   150  		return nil
   151  	}
   152  	return decodeHash(buf, HashTypeChainId, h[:])
   153  }
   154  
   155  func (h ChainIdHash) MarshalBinary() ([]byte, error) {
   156  	return h[:], nil
   157  }
   158  
   159  func (h *ChainIdHash) UnmarshalBinary(buf []byte) error {
   160  	if l := len(buf); l > 0 && l != HashTypeChainId.Len {
   161  		return fmt.Errorf("tezos: short chain_id hash")
   162  	}
   163  	copy(h[:], buf)
   164  	return nil
   165  }
   166  
   167  func (h ChainIdHash) Uint32() uint32 {
   168  	return binary.BigEndian.Uint32(h[:])
   169  }
   170  
   171  func ParseChainIdHash(s string) (h ChainIdHash, err error) {
   172  	err = decodeHashString(s, HashTypeChainId, h[:])
   173  	return
   174  }
   175  
   176  func MustParseChainIdHash(s string) ChainIdHash {
   177  	h, err := ParseChainIdHash(s)
   178  	panicOnError(err)
   179  	return h
   180  }
   181  
   182  // Set implements the flags.Value interface for use in command line argument parsing.
   183  func (h *ChainIdHash) Set(s string) (err error) {
   184  	*h, err = ParseChainIdHash(s)
   185  	return
   186  }
   187  
   188  // BlockHash
   189  type BlockHash [32]byte
   190  
   191  func NewBlockHash(buf []byte) (h BlockHash) {
   192  	copy(h[:], buf)
   193  	return
   194  }
   195  
   196  func (h BlockHash) IsValid() bool {
   197  	return !h.Equal(ZeroBlockHash)
   198  }
   199  
   200  func (h BlockHash) Equal(h2 BlockHash) bool {
   201  	return h == h2
   202  }
   203  
   204  func (h BlockHash) Clone() BlockHash {
   205  	return NewBlockHash(h[:])
   206  }
   207  
   208  func (h BlockHash) String() string {
   209  	return base58.CheckEncode(h[:], HashTypeBlock.Id)
   210  }
   211  
   212  func (h BlockHash) Bytes() []byte {
   213  	return h[:]
   214  }
   215  
   216  func (h BlockHash) MarshalText() ([]byte, error) {
   217  	return []byte(h.String()), nil
   218  }
   219  
   220  func (h *BlockHash) UnmarshalText(buf []byte) error {
   221  	if len(buf) == 0 {
   222  		return nil
   223  	}
   224  	return decodeHash(buf, HashTypeBlock, h[:])
   225  }
   226  
   227  func (h BlockHash) MarshalBinary() ([]byte, error) {
   228  	return h[:], nil
   229  }
   230  
   231  func (h *BlockHash) UnmarshalBinary(buf []byte) error {
   232  	if l := len(buf); l > 0 && l != HashTypeBlock.Len {
   233  		return fmt.Errorf("tezos: short block hash")
   234  	}
   235  	copy(h[:], buf)
   236  	return nil
   237  }
   238  
   239  func ParseBlockHash(s string) (h BlockHash, err error) {
   240  	err = decodeHashString(s, HashTypeBlock, h[:])
   241  	return
   242  }
   243  
   244  func MustParseBlockHash(s string) BlockHash {
   245  	h, err := ParseBlockHash(s)
   246  	panicOnError(err)
   247  	return h
   248  }
   249  
   250  // Set implements the flags.Value interface for use in command line argument parsing.
   251  func (h *BlockHash) Set(s string) (err error) {
   252  	*h, err = ParseBlockHash(s)
   253  	return
   254  }
   255  
   256  // Int64 ensures interface compatibility with the RPC packages' BlockID type
   257  func (h BlockHash) Int64() int64 {
   258  	return -1
   259  }
   260  
   261  // ProtocolHash
   262  type ProtocolHash [32]byte
   263  
   264  func NewProtocolHash(buf []byte) (h ProtocolHash) {
   265  	copy(h[:], buf)
   266  	return
   267  }
   268  
   269  func (h ProtocolHash) IsValid() bool {
   270  	return !h.Equal(ZeroProtocolHash)
   271  }
   272  
   273  func (h ProtocolHash) Equal(h2 ProtocolHash) bool {
   274  	return h == h2
   275  }
   276  
   277  func (h ProtocolHash) Clone() ProtocolHash {
   278  	return NewProtocolHash(h[:])
   279  }
   280  
   281  func (h ProtocolHash) String() string {
   282  	return base58.CheckEncode(h[:], HashTypeProtocol.Id)
   283  }
   284  
   285  func (h ProtocolHash) Bytes() []byte {
   286  	return h[:]
   287  }
   288  
   289  func (h ProtocolHash) MarshalText() ([]byte, error) {
   290  	return []byte(h.String()), nil
   291  }
   292  
   293  func (h *ProtocolHash) UnmarshalText(buf []byte) error {
   294  	if len(buf) == 0 {
   295  		return nil
   296  	}
   297  	return decodeHash(buf, HashTypeProtocol, h[:])
   298  }
   299  
   300  func (h ProtocolHash) MarshalBinary() ([]byte, error) {
   301  	return h[:], nil
   302  }
   303  
   304  func (h *ProtocolHash) UnmarshalBinary(buf []byte) error {
   305  	if l := len(buf); l > 0 && l != HashTypeProtocol.Len {
   306  		return fmt.Errorf("tezos: short protocol hash")
   307  	}
   308  	copy(h[:], buf)
   309  	return nil
   310  }
   311  
   312  func ParseProtocolHash(s string) (h ProtocolHash, err error) {
   313  	err = decodeHashString(s, HashTypeProtocol, h[:])
   314  	return
   315  }
   316  
   317  func MustParseProtocolHash(s string) ProtocolHash {
   318  	h, err := ParseProtocolHash(s)
   319  	panicOnError(err)
   320  	return h
   321  }
   322  
   323  // Set implements the flags.Value interface for use in command line argument parsing.
   324  func (h *ProtocolHash) Set(s string) (err error) {
   325  	*h, err = ParseProtocolHash(s)
   326  	return
   327  }
   328  
   329  // OpHash
   330  type OpHash [32]byte
   331  
   332  func NewOpHash(buf []byte) (h OpHash) {
   333  	copy(h[:], buf)
   334  	return
   335  }
   336  
   337  func (h OpHash) IsValid() bool {
   338  	return !h.Equal(ZeroOpHash)
   339  }
   340  
   341  func (h OpHash) Equal(h2 OpHash) bool {
   342  	return h == h2
   343  }
   344  
   345  func (h OpHash) Clone() OpHash {
   346  	return NewOpHash(h[:])
   347  }
   348  
   349  func (h OpHash) String() string {
   350  	return base58.CheckEncode(h[:], HashTypeOperation.Id)
   351  }
   352  
   353  func (h OpHash) Bytes() []byte {
   354  	return h[:]
   355  }
   356  
   357  func (h OpHash) MarshalText() ([]byte, error) {
   358  	return []byte(h.String()), nil
   359  }
   360  
   361  func (h *OpHash) UnmarshalText(buf []byte) error {
   362  	if len(buf) == 0 {
   363  		return nil
   364  	}
   365  	return decodeHash(buf, HashTypeOperation, h[:])
   366  }
   367  
   368  func (h OpHash) MarshalBinary() ([]byte, error) {
   369  	return h[:], nil
   370  }
   371  
   372  func (h *OpHash) UnmarshalBinary(buf []byte) error {
   373  	if l := len(buf); l > 0 && l != HashTypeOperation.Len {
   374  		return fmt.Errorf("tezos: short operation hash")
   375  	}
   376  	copy(h[:], buf)
   377  	return nil
   378  }
   379  
   380  func ParseOpHash(s string) (h OpHash, err error) {
   381  	err = decodeHashString(s, HashTypeOperation, h[:])
   382  	return
   383  }
   384  
   385  func MustParseOpHash(s string) OpHash {
   386  	h, err := ParseOpHash(s)
   387  	panicOnError(err)
   388  	return h
   389  }
   390  
   391  // Set implements the flags.Value interface for use in command line argument parsing.
   392  func (h *OpHash) Set(s string) (err error) {
   393  	*h, err = ParseOpHash(s)
   394  	return
   395  }
   396  
   397  // OpListListHash
   398  type OpListListHash [32]byte
   399  
   400  func NewOpListListHash(buf []byte) (h OpListListHash) {
   401  	copy(h[:], buf)
   402  	return
   403  }
   404  
   405  func (h OpListListHash) IsValid() bool {
   406  	return !h.Equal(ZeroOpListListHash)
   407  }
   408  
   409  func (h OpListListHash) Equal(h2 OpListListHash) bool {
   410  	return h == h2
   411  }
   412  
   413  func (h OpListListHash) Clone() OpListListHash {
   414  	return NewOpListListHash(h[:])
   415  }
   416  
   417  func (h OpListListHash) String() string {
   418  	return base58.CheckEncode(h[:], HashTypeOperationListList.Id)
   419  }
   420  
   421  func (h OpListListHash) Bytes() []byte {
   422  	return h[:]
   423  }
   424  
   425  func (h OpListListHash) MarshalText() ([]byte, error) {
   426  	return []byte(h.String()), nil
   427  }
   428  
   429  func (h *OpListListHash) UnmarshalText(buf []byte) error {
   430  	if len(buf) == 0 {
   431  		return nil
   432  	}
   433  	return decodeHash(buf, HashTypeOperationListList, h[:])
   434  }
   435  
   436  func (h OpListListHash) MarshalBinary() ([]byte, error) {
   437  	return h[:], nil
   438  }
   439  
   440  func (h *OpListListHash) UnmarshalBinary(buf []byte) error {
   441  	if l := len(buf); l > 0 && l != HashTypeOperationListList.Len {
   442  		return fmt.Errorf("tezos: short operation list list hash")
   443  	}
   444  	copy(h[:], buf)
   445  	return nil
   446  }
   447  
   448  func ParseOpListListHash(s string) (h OpListListHash, err error) {
   449  	err = decodeHashString(s, HashTypeOperationListList, h[:])
   450  	return
   451  }
   452  
   453  func MustParseOpListListHash(s string) OpListListHash {
   454  	b, err := ParseOpListListHash(s)
   455  	panicOnError(err)
   456  	return b
   457  }
   458  
   459  // Set implements the flags.Value interface for use in command line argument parsing.
   460  func (h *OpListListHash) Set(s string) (err error) {
   461  	*h, err = ParseOpListListHash(s)
   462  	return
   463  }
   464  
   465  // PayloadHash
   466  type PayloadHash [32]byte
   467  
   468  func NewPayloadHash(buf []byte) (h PayloadHash) {
   469  	copy(h[:], buf)
   470  	return
   471  }
   472  
   473  func (h PayloadHash) IsValid() bool {
   474  	return !h.Equal(ZeroPayloadHash)
   475  }
   476  
   477  func (h PayloadHash) Equal(h2 PayloadHash) bool {
   478  	return h == h2
   479  }
   480  
   481  func (h PayloadHash) Clone() PayloadHash {
   482  	return NewPayloadHash(h[:])
   483  }
   484  
   485  func (h PayloadHash) String() string {
   486  	return base58.CheckEncode(h[:], HashTypeBlockPayload.Id)
   487  }
   488  
   489  func (h PayloadHash) Bytes() []byte {
   490  	return h[:]
   491  }
   492  
   493  func (h PayloadHash) MarshalText() ([]byte, error) {
   494  	return []byte(h.String()), nil
   495  }
   496  
   497  func (h *PayloadHash) UnmarshalText(buf []byte) error {
   498  	if len(buf) == 0 {
   499  		return nil
   500  	}
   501  	return decodeHash(buf, HashTypeBlockPayload, h[:])
   502  }
   503  
   504  func (h PayloadHash) MarshalBinary() ([]byte, error) {
   505  	return h[:], nil
   506  }
   507  
   508  func (h *PayloadHash) UnmarshalBinary(buf []byte) error {
   509  	if l := len(buf); l > 0 && l != HashTypeBlockPayload.Len {
   510  		return fmt.Errorf("teshortd for payload hash")
   511  	}
   512  	copy(h[:], buf)
   513  	return nil
   514  }
   515  
   516  func ParsePayloadHash(s string) (h PayloadHash, err error) {
   517  	err = decodeHashString(s, HashTypeBlockPayload, h[:])
   518  	return
   519  }
   520  
   521  func MustParsePayloadHash(s string) PayloadHash {
   522  	b, err := ParsePayloadHash(s)
   523  	panicOnError(err)
   524  	return b
   525  }
   526  
   527  // Set implements the flags.Value interface for use in command line argument parsing.
   528  func (h *PayloadHash) Set(hash string) (err error) {
   529  	*h, err = ParsePayloadHash(hash)
   530  	return
   531  }
   532  
   533  // ExprHash
   534  type ExprHash [32]byte
   535  
   536  func NewExprHash(buf []byte) (h ExprHash) {
   537  	copy(h[:], buf)
   538  	return
   539  }
   540  
   541  func (h ExprHash) IsValid() bool {
   542  	return !h.Equal(ZeroExprHash)
   543  }
   544  
   545  func (h ExprHash) Equal(h2 ExprHash) bool {
   546  	return h == h2
   547  }
   548  
   549  func (h ExprHash) Clone() ExprHash {
   550  	return NewExprHash(h[:])
   551  }
   552  
   553  func (h ExprHash) String() string {
   554  	return base58.CheckEncode(h[:], HashTypeScriptExpr.Id)
   555  }
   556  
   557  func (h ExprHash) Bytes() []byte {
   558  	return h[:]
   559  }
   560  
   561  func (h ExprHash) MarshalText() ([]byte, error) {
   562  	return []byte(h.String()), nil
   563  }
   564  
   565  func (h *ExprHash) UnmarshalText(buf []byte) error {
   566  	if len(buf) == 0 {
   567  		return nil
   568  	}
   569  	return decodeHash(buf, HashTypeScriptExpr, h[:])
   570  }
   571  
   572  func (h ExprHash) MarshalBinary() ([]byte, error) {
   573  	return h[:], nil
   574  }
   575  
   576  func (h *ExprHash) UnmarshalBinary(buf []byte) error {
   577  	if l := len(buf); l > 0 && l != HashTypeScriptExpr.Len {
   578  		return fmt.Errorf("tezoshortfor script expression hash")
   579  	}
   580  	copy(h[:], buf)
   581  	return nil
   582  }
   583  
   584  func ParseExprHash(s string) (h ExprHash, err error) {
   585  	err = decodeHashString(s, HashTypeScriptExpr, h[:])
   586  	return
   587  }
   588  
   589  func MustParseExprHash(s string) ExprHash {
   590  	b, err := ParseExprHash(s)
   591  	panicOnError(err)
   592  	return b
   593  }
   594  
   595  // Set implements the flags.Value interface for use in command line argument parsing.
   596  func (h *ExprHash) Set(hash string) (err error) {
   597  	*h, err = ParseExprHash(hash)
   598  	return
   599  }
   600  
   601  // NonceHash
   602  type NonceHash [32]byte
   603  
   604  func NewNonceHash(buf []byte) (h NonceHash) {
   605  	copy(h[:], buf)
   606  	return
   607  }
   608  
   609  func (h NonceHash) IsValid() bool {
   610  	return !h.Equal(ZeroNonceHash)
   611  }
   612  
   613  func (h NonceHash) Equal(h2 NonceHash) bool {
   614  	return h == h2
   615  }
   616  
   617  func (h NonceHash) Clone() NonceHash {
   618  	return NewNonceHash(h[:])
   619  }
   620  
   621  func (h NonceHash) String() string {
   622  	return base58.CheckEncode(h[:], HashTypeNonce.Id)
   623  }
   624  
   625  func (h NonceHash) Bytes() []byte {
   626  	return h[:]
   627  }
   628  
   629  func (h NonceHash) MarshalText() ([]byte, error) {
   630  	return []byte(h.String()), nil
   631  }
   632  
   633  func (h *NonceHash) UnmarshalText(buf []byte) error {
   634  	if len(buf) == 0 {
   635  		return nil
   636  	}
   637  	return decodeHash(buf, HashTypeNonce, h[:])
   638  }
   639  
   640  func (h NonceHash) MarshalBinary() ([]byte, error) {
   641  	return h[:], nil
   642  }
   643  
   644  func (h *NonceHash) UnmarshalBinary(buf []byte) error {
   645  	if l := len(buf); l > 0 && l != HashTypeNonce.Len {
   646  		return fmt.Errorf("tezos: short nonce")
   647  	}
   648  	copy(h[:], buf)
   649  	return nil
   650  }
   651  
   652  func ParseNonceHash(s string) (h NonceHash, err error) {
   653  	err = decodeHashString(s, HashTypeNonce, h[:])
   654  	return
   655  }
   656  
   657  func MustParseNonceHash(s string) NonceHash {
   658  	b, err := ParseNonceHash(s)
   659  	panicOnError(err)
   660  	return b
   661  }
   662  
   663  func ParseNonceHashSafe(s string) (h NonceHash) {
   664  	_ = decodeHashString(s, HashTypeNonce, h[:])
   665  	return
   666  }
   667  
   668  // Set implements the flags.Value interface for use in command line argument parsing.
   669  func (h *NonceHash) Set(hash string) (err error) {
   670  	*h, err = ParseNonceHash(hash)
   671  	return
   672  }
   673  
   674  // ContextHash
   675  type ContextHash [32]byte
   676  
   677  func NewContextHash(buf []byte) (h ContextHash) {
   678  	copy(h[:], buf)
   679  	return
   680  }
   681  
   682  func (h ContextHash) IsValid() bool {
   683  	return !h.Equal(ZeroContextHash)
   684  }
   685  
   686  func (h ContextHash) Equal(h2 ContextHash) bool {
   687  	return h == h2
   688  }
   689  
   690  func (h ContextHash) Clone() ContextHash {
   691  	return NewContextHash(h[:])
   692  }
   693  
   694  func (h ContextHash) String() string {
   695  	return base58.CheckEncode(h[:], HashTypeContext.Id)
   696  }
   697  
   698  func (h ContextHash) Bytes() []byte {
   699  	return h[:]
   700  }
   701  
   702  func (h ContextHash) MarshalText() ([]byte, error) {
   703  	return []byte(h.String()), nil
   704  }
   705  
   706  func (h *ContextHash) UnmarshalText(buf []byte) error {
   707  	if len(buf) == 0 {
   708  		return nil
   709  	}
   710  	return decodeHash(buf, HashTypeContext, h[:])
   711  }
   712  
   713  func (h ContextHash) MarshalBinary() ([]byte, error) {
   714  	return h[:], nil
   715  }
   716  
   717  func (h *ContextHash) UnmarshalBinary(buf []byte) error {
   718  	if l := len(buf); l > 0 && l != HashTypeContext.Len {
   719  		return fmt.Errorf("tezos: short context hash")
   720  	}
   721  	copy(h[:], buf)
   722  	return nil
   723  }
   724  
   725  func ParseContextHash(s string) (h ContextHash, err error) {
   726  	err = decodeHashString(s, HashTypeContext, h[:])
   727  	return
   728  }
   729  
   730  func MustParseContextHash(s string) ContextHash {
   731  	b, err := ParseContextHash(s)
   732  	panicOnError(err)
   733  	return b
   734  }
   735  
   736  // Set implements the flags.Value interface for use in command line argument parsing.
   737  func (h *ContextHash) Set(hash string) (err error) {
   738  	*h, err = ParseContextHash(hash)
   739  	return
   740  }
   741  
   742  // SmartRollupCommitHash
   743  type SmartRollupCommitHash [32]byte
   744  
   745  func NewSmartRollupCommitHash(buf []byte) (h SmartRollupCommitHash) {
   746  	copy(h[:], buf)
   747  	return
   748  }
   749  
   750  func (h SmartRollupCommitHash) IsValid() bool {
   751  	return !h.Equal(ZeroSmartRollupCommitHash)
   752  }
   753  
   754  func (h SmartRollupCommitHash) Equal(h2 SmartRollupCommitHash) bool {
   755  	return h == h2
   756  }
   757  
   758  func (h SmartRollupCommitHash) Clone() SmartRollupCommitHash {
   759  	return NewSmartRollupCommitHash(h[:])
   760  }
   761  
   762  func (h SmartRollupCommitHash) String() string {
   763  	return base58.CheckEncode(h[:], HashTypeSmartRollupCommitHash.Id)
   764  }
   765  
   766  func (h SmartRollupCommitHash) Bytes() []byte {
   767  	return h[:]
   768  }
   769  
   770  func (h SmartRollupCommitHash) MarshalText() ([]byte, error) {
   771  	return []byte(h.String()), nil
   772  }
   773  
   774  func (h *SmartRollupCommitHash) UnmarshalText(buf []byte) error {
   775  	if len(buf) == 0 {
   776  		return nil
   777  	}
   778  	return decodeHash(buf, HashTypeSmartRollupCommitHash, h[:])
   779  }
   780  
   781  func (h SmartRollupCommitHash) MarshalBinary() ([]byte, error) {
   782  	return h[:], nil
   783  }
   784  
   785  func (h *SmartRollupCommitHash) UnmarshalBinary(buf []byte) error {
   786  	if l := len(buf); l > 0 && l != HashTypeSmartRollupCommitHash.Len {
   787  		return fmt.Errorf("tezos: short smart rollup commit hash")
   788  	}
   789  	copy(h[:], buf)
   790  	return nil
   791  }
   792  
   793  func ParseSmartRollupCommitHash(s string) (h SmartRollupCommitHash, err error) {
   794  	err = decodeHashString(s, HashTypeSmartRollupCommitHash, h[:])
   795  	return
   796  }
   797  
   798  func MustParseSmartRollupCommitHash(s string) SmartRollupCommitHash {
   799  	b, err := ParseSmartRollupCommitHash(s)
   800  	panicOnError(err)
   801  	return b
   802  }
   803  
   804  // Set implements the flags.Value interface for use in command line argument parsing.
   805  func (h *SmartRollupCommitHash) Set(hash string) (err error) {
   806  	*h, err = ParseSmartRollupCommitHash(hash)
   807  	return
   808  }
   809  
   810  // SmartRollupStateHash
   811  type SmartRollupStateHash [32]byte
   812  
   813  func NewSmartRollupStateHash(buf []byte) (h SmartRollupStateHash) {
   814  	copy(h[:], buf)
   815  	return
   816  }
   817  
   818  func (h SmartRollupStateHash) IsValid() bool {
   819  	return !h.Equal(ZeroSmartRollupStateHash)
   820  }
   821  
   822  func (h SmartRollupStateHash) Equal(h2 SmartRollupStateHash) bool {
   823  	return h == h2
   824  }
   825  
   826  func (h SmartRollupStateHash) Clone() SmartRollupStateHash {
   827  	return NewSmartRollupStateHash(h[:])
   828  }
   829  
   830  func (h SmartRollupStateHash) String() string {
   831  	return base58.CheckEncode(h[:], HashTypeSmartRollupStateHash.Id)
   832  }
   833  
   834  func (h SmartRollupStateHash) Bytes() []byte {
   835  	return h[:]
   836  }
   837  
   838  func (h SmartRollupStateHash) MarshalText() ([]byte, error) {
   839  	return []byte(h.String()), nil
   840  }
   841  
   842  func (h *SmartRollupStateHash) UnmarshalText(buf []byte) error {
   843  	if len(buf) == 0 {
   844  		return nil
   845  	}
   846  	return decodeHash(buf, HashTypeSmartRollupStateHash, h[:])
   847  }
   848  
   849  func (h SmartRollupStateHash) MarshalBinary() ([]byte, error) {
   850  	return h[:], nil
   851  }
   852  
   853  func (h *SmartRollupStateHash) UnmarshalBinary(buf []byte) error {
   854  	if l := len(buf); l > 0 && l != HashTypeSmartRollupStateHash.Len {
   855  		return fmt.Errorf("tezos: short smart rollup commit hash")
   856  	}
   857  	copy(h[:], buf)
   858  	return nil
   859  }
   860  
   861  func ParseSmartRollupStateHash(s string) (h SmartRollupStateHash, err error) {
   862  	err = decodeHashString(s, HashTypeSmartRollupStateHash, h[:])
   863  	return
   864  }
   865  
   866  func MustParseSmartRollupStateHash(s string) SmartRollupStateHash {
   867  	b, err := ParseSmartRollupStateHash(s)
   868  	panicOnError(err)
   869  	return b
   870  }
   871  
   872  // Set implements the flags.Value interface for use in command line argument parsing.
   873  func (h *SmartRollupStateHash) Set(hash string) (err error) {
   874  	*h, err = ParseSmartRollupStateHash(hash)
   875  	return
   876  }
   877  
   878  // internal decoders
   879  func decodeHash(src []byte, typ HashType, dst []byte) error {
   880  	return decodeHashString(string(src), typ, dst)
   881  }
   882  
   883  func decodeHashString(src string, typ HashType, dst []byte) error {
   884  	if len(src) == 0 {
   885  		return nil
   886  	}
   887  	ibuf := bufPool32.Get()
   888  	dec, ver, err := base58.CheckDecode(src, len(typ.Id), ibuf.([]byte))
   889  	if err != nil {
   890  		bufPool32.Put(ibuf)
   891  		if err == base58.ErrChecksum {
   892  			return ErrChecksumMismatch
   893  		}
   894  		return fmt.Errorf("tezos: unknown hash format: %w", err)
   895  	}
   896  	if !bytes.Equal(ver, typ.Id) {
   897  		bufPool32.Put(ibuf)
   898  		return fmt.Errorf("tezos: invalid prefix '%x' for decoded hash type '%s'", ver, typ)
   899  	}
   900  	copy(dst, dec)
   901  	bufPool32.Put(ibuf)
   902  	return nil
   903  }