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 }