OSDN Git Service

Merge branch 'dev' into dev-verify
[bytom/bytom.git] / common / types.go
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 func StringToHash(s string) Hash { return BytesToHash([]byte(s)) }
31 func BigToHash(b *big.Int) Hash  { return BytesToHash(b.Bytes()) }
32 func HexToHash(s string) Hash    { return BytesToHash(FromHex(s)) }
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) Big() *big.Int { return Bytes2Big(h[:]) }
40 func (h Hash) Hex() string   { return "0x" + Bytes2Hex(h[:]) }
41
42 // UnmarshalJSON parses a hash in its hex from to a hash.
43 func (h *Hash) UnmarshalJSON(input []byte) error {
44         length := len(input)
45         if length >= 2 && input[0] == '"' && input[length-1] == '"' {
46                 input = input[1 : length-1]
47         }
48         // strip "0x" for length check
49         if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" {
50                 input = input[2:]
51         }
52
53         // validate the length of the input hash
54         if len(input) != HashLength*2 {
55                 return hashJsonLengthErr
56         }
57         h.SetBytes(FromHex(string(input)))
58         return nil
59 }
60
61 // Serialize given hash to JSON
62 func (h Hash) MarshalJSON() ([]byte, error) {
63         return json.Marshal(h.Hex())
64 }
65
66 // Sets the hash to the value of b. If b is larger than len(h) it will panic
67 func (h *Hash) SetBytes(b []byte) {
68         if len(b) > len(h) {
69                 b = b[len(b)-HashLength:]
70         }
71
72         copy(h[HashLength-len(b):], b)
73 }
74
75 // Set string `s` to h. If s is larger than len(h) it will panic
76 func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) }
77
78 // Sets h to other
79 func (h *Hash) Set(other Hash) {
80         for i, v := range other {
81                 h[i] = v
82         }
83 }
84
85 // Generate implements testing/quick.Generator.
86 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
87         m := rand.Intn(len(h))
88         for i := len(h) - 1; i > m; i-- {
89                 h[i] = byte(rand.Uint32())
90         }
91         return reflect.ValueOf(h)
92 }
93
94 func EmptyHash(h Hash) bool {
95         return h == Hash{}
96 }