-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
hash.go
60 lines (50 loc) · 1.46 KB
/
hash.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package utils
import (
"encoding/hex"
"fmt"
"strings"
"github.com/pkg/errors"
)
const HashLength = 32
// Hash is a simplified version of go-ethereum's common.Hash to avoid
// go-ethereum dependency
// It represents a 32 byte fixed size array that marshals/unmarshals assuming a
// 0x prefix
type Hash [32]byte
// BytesToHash sets b to hash.
// If b is larger than len(h), b will be cropped from the left.
func BytesToHash(b []byte) Hash {
var h Hash
h.SetBytes(b)
return h
}
// SetBytes sets the hash to the value of b.
// If b is larger than len(h), b will be cropped from the left.
func (h *Hash) SetBytes(b []byte) {
if len(b) > len(h) {
b = b[len(b)-HashLength:]
}
copy(h[HashLength-len(b):], b)
}
// Hex converts a hash to a hex string.
func (h Hash) Hex() string { return fmt.Sprintf("0x%s", hex.EncodeToString(h[:])) }
// String implements the stringer interface and is used also by the logger when
// doing full logging into a file.
func (h Hash) String() string {
return h.Hex()
}
// UnmarshalText parses a hash in hex syntax.
func (h *Hash) UnmarshalText(input []byte) error {
if !strings.HasPrefix(string(input), "0x") {
return errors.New("hash: expected a hex string starting with '0x'")
}
phex := new(PlainHexBytes)
if err := phex.UnmarshalText(input[2:]); err != nil {
return fmt.Errorf("hash: %w", err)
}
if len(*phex) != 32 {
return fmt.Errorf("hash: expected 32-byte sequence, got %d bytes", len(*phex))
}
copy((*h)[:], (*phex))
return nil
}