github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/base/hash.go (about)

     1  package base
     2  
     3  import (
     4  	"encoding/hex"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/cache"
    10  	"github.com/ethereum/go-ethereum/common"
    11  )
    12  
    13  // Hash is a wrapper for go-ethereum's Hash type that always
    14  // return lower case hex.
    15  type Hash struct {
    16  	common.Hash `json:"hash"`
    17  }
    18  
    19  // Hex returns string representation of an hash. Unlike addresses, we do not shorten zero hashes.
    20  func (h *Hash) Hex() string {
    21  	// if h.IsZero() {
    22  	// 	return "0x0"
    23  	// }
    24  	return bytesToHashString(h.Hash.Bytes())
    25  }
    26  
    27  func (h *Hash) String() string {
    28  	return h.Hex()
    29  }
    30  
    31  // Format is used by Stringer don't remove
    32  func (h Hash) Format(s fmt.State, c rune) {
    33  	_, _ = s.Write([]byte(h.Hex()))
    34  }
    35  
    36  // MarshalText is used by Stringer don't remove
    37  func (h Hash) MarshalText() ([]byte, error) {
    38  	return []byte(h.Hex()), nil
    39  }
    40  
    41  func (h *Hash) UnmarshalJSON(data []byte) error {
    42  	if string(data) == "\"0x0\"" || string(data) == "\"\"" {
    43  		return nil
    44  	}
    45  	return h.Hash.UnmarshalJSON(data)
    46  }
    47  
    48  // SetHex sets the hash based on the provided string
    49  func (h *Hash) SetHex(hexStr string) {
    50  	h.Hash = common.HexToHash(hexStr)
    51  }
    52  
    53  // IsZero returns true if an hash is a zero value or 0x0.
    54  func (h *Hash) IsZero() bool {
    55  	v := bytesToHashString(h.Hash.Bytes())
    56  	return v == "0x0000000000000000000000000000000000000000000000000000000000000000"
    57  }
    58  
    59  func (h *Hash) UnmarshalCache(version uint64, reader io.Reader) error {
    60  	var value [32]byte
    61  	if err := cache.ReadValue(reader, &value, version); err != nil {
    62  		return err
    63  	}
    64  	h.SetBytes(value[:])
    65  	return nil
    66  }
    67  
    68  func (h *Hash) Common() common.Hash {
    69  	return common.BytesToHash(h.Bytes())
    70  }
    71  
    72  func (h *Hash) SetCommon(c *common.Hash) Hash {
    73  	return BytesToHash(c.Bytes())
    74  }
    75  
    76  // HexToHash returns new hash with the given string
    77  // as value.
    78  func HexToHash(hex string) (hash Hash) {
    79  	hash.SetHex(hex)
    80  	return
    81  }
    82  
    83  func BytesToHash(b []byte) (hash Hash) {
    84  	hash.SetBytes(b)
    85  	return
    86  }
    87  
    88  func bytesToHashString(hashBytes []byte) string {
    89  	return "0x" + hex.EncodeToString(hashBytes)
    90  }
    91  
    92  func IsValidHex(typ string, val string, nBytes int) (bool, error) {
    93  	if _, err := ValidHex(val, nBytes); err != nil {
    94  		if errors.Is(err, ErrInvalidLength) {
    95  			//lint:ignore ST1005 sorry
    96  			return false, fmt.Errorf("The %s option (%s) must be %d bytes long.", typ, val, nBytes)
    97  		} else if errors.Is(err, ErrInvalidHex) {
    98  			//lint:ignore ST1005 sorry
    99  			return false, fmt.Errorf("The %s option (%s) must be hex.", typ, val)
   100  		} else if errors.Is(err, ErrNoLeading0x) {
   101  			//lint:ignore ST1005 sorry
   102  			return false, fmt.Errorf("The %s option (%s) must start with '0x'.", typ, val)
   103  		}
   104  		return false, err
   105  	}
   106  	return true, nil
   107  }