-
Notifications
You must be signed in to change notification settings - Fork 77
/
uint160.go
133 lines (111 loc) · 3.21 KB
/
uint160.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package util
import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"
)
// Uint160Size is the size of Uint160 in bytes.
const Uint160Size = 20
// Uint160 is a 20 byte long unsigned integer.
type Uint160 [Uint160Size]uint8
// Uint160DecodeStringBE attempts to decode the given string into an Uint160.
func Uint160DecodeStringBE(s string) (Uint160, error) {
var u Uint160
if len(s) != Uint160Size*2 {
return u, fmt.Errorf("expected string size of %d got %d", Uint160Size*2, len(s))
}
b, err := hex.DecodeString(s)
if err != nil {
return u, err
}
return Uint160DecodeBytesBE(b)
}
// Uint160DecodeStringLE attempts to decode the given string
// in little-endian hex encoding into an Uint160.
func Uint160DecodeStringLE(s string) (Uint160, error) {
var u Uint160
if len(s) != Uint160Size*2 {
return u, fmt.Errorf("expected string size of %d got %d", Uint160Size*2, len(s))
}
b, err := hex.DecodeString(s)
if err != nil {
return u, err
}
return Uint160DecodeBytesLE(b)
}
// Uint160DecodeBytesBE attempts to decode the given bytes into an Uint160.
func Uint160DecodeBytesBE(b []byte) (u Uint160, err error) {
if len(b) != Uint160Size {
return u, fmt.Errorf("expected byte size of %d got %d", Uint160Size, len(b))
}
copy(u[:], b)
return
}
// Uint160DecodeBytesLE attempts to decode the given bytes in little-endian
// into an Uint160.
func Uint160DecodeBytesLE(b []byte) (u Uint160, err error) {
if len(b) != Uint160Size {
return u, fmt.Errorf("expected byte size of %d got %d", Uint160Size, len(b))
}
for i := range b {
u[Uint160Size-i-1] = b[i]
}
return
}
// BytesBE returns a big-endian byte representation of u.
func (u Uint160) BytesBE() []byte {
return u[:]
}
// BytesLE returns a little-endian byte representation of u.
func (u Uint160) BytesLE() []byte {
return ArrayReverse(u.BytesBE())
}
// String implements the stringer interface.
func (u Uint160) String() string {
return u.StringBE()
}
// StringBE returns string representations of u with big-endian byte order.
func (u Uint160) StringBE() string {
return hex.EncodeToString(u.BytesBE())
}
// StringLE returns string representations of u with little-endian byte order.
func (u Uint160) StringLE() string {
return hex.EncodeToString(u.BytesLE())
}
// Reverse returns reversed representation of u.
func (u Uint160) Reverse() (r Uint160) {
for i := 0; i < Uint160Size; i++ {
r[i] = u[Uint160Size-i-1]
}
return
}
// Equals returns true if both Uint256 values are the same.
func (u Uint160) Equals(other Uint160) bool {
return u == other
}
// Less returns true if this value is less than given Uint160 value. It's
// primarily intended to be used for sorting purposes.
func (u Uint160) Less(other Uint160) bool {
for k := range u {
if u[k] == other[k] {
continue
}
return u[k] < other[k]
}
return false
}
// UnmarshalJSON implements the json unmarshaller interface.
func (u *Uint160) UnmarshalJSON(data []byte) (err error) {
var js string
if err = json.Unmarshal(data, &js); err != nil {
return err
}
js = strings.TrimPrefix(js, "0x")
*u, err = Uint160DecodeStringLE(js)
return err
}
// MarshalJSON implements the json marshaller interface.
func (u Uint160) MarshalJSON() ([]byte, error) {
return []byte(`"0x` + u.StringLE() + `"`), nil
}