github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/common/types.go (about) 1 package common 2 3 import ( 4 _ "encoding/hex" 5 "encoding/json" 6 "errors" 7 "math/big" 8 "math/rand" 9 "reflect" 10 "strings" 11 ) 12 13 const ( 14 HashLength = 32 15 AddressLength = 42 16 PubkeyHashLength = 20 17 ) 18 19 var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes") 20 21 type ( 22 Hash [HashLength]byte 23 ) 24 25 func BytesToHash(b []byte) Hash { 26 var h Hash 27 h.SetBytes(b) 28 return h 29 } 30 31 func StringToHash(s string) Hash { return BytesToHash([]byte(s)) } 32 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } 33 34 // Don't use the default 'String' method in case we want to overwrite 35 36 // Get the string representation of the underlying hash 37 func (h Hash) Str() string { return string(h[:]) } 38 func (h Hash) Bytes() []byte { return h[:] } 39 func (h Hash) Hex() string { return "0x" + Bytes2Hex(h[:]) } 40 41 // UnmarshalJSON parses a hash in its hex from to a hash. 42 func (h *Hash) UnmarshalJSON(input []byte) error { 43 length := len(input) 44 if length >= 2 && input[0] == '"' && input[length-1] == '"' { 45 input = input[1 : length-1] 46 } 47 // strip "0x" for length check 48 if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" { 49 input = input[2:] 50 } 51 52 // validate the length of the input hash 53 if len(input) != HashLength*2 { 54 return hashJsonLengthErr 55 } 56 h.SetBytes(FromHex(string(input))) 57 return nil 58 } 59 60 // Serialize given hash to JSON 61 func (h Hash) MarshalJSON() ([]byte, error) { 62 return json.Marshal(h.Hex()) 63 } 64 65 // Sets the hash to the value of b. If b is larger than len(h) it will panic 66 func (h *Hash) SetBytes(b []byte) { 67 if len(b) > len(h) { 68 b = b[len(b)-HashLength:] 69 } 70 71 copy(h[HashLength-len(b):], b) 72 } 73 74 // Sets h to other 75 func (h *Hash) Set(other Hash) { 76 for i, v := range other { 77 h[i] = v 78 } 79 } 80 81 // Generate implements testing/quick.Generator. 82 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { 83 m := rand.Intn(len(h)) 84 for i := len(h) - 1; i > m; i-- { 85 h[i] = byte(rand.Uint32()) 86 } 87 return reflect.ValueOf(h) 88 } 89 90 func EmptyHash(h Hash) bool { 91 return h == Hash{} 92 }