/
address.go
144 lines (119 loc) · 3.13 KB
/
address.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
134
135
136
137
138
139
140
141
142
143
144
package types
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/Robbin-Liu/go-binance-sdk/common/bech32"
"github.com/tendermint/tendermint/crypto"
)
// AccAddress a wrapper around bytes meant to represent an account address.
// When marshaled to a string or JSON, it uses Bech32.
type AccAddress []byte
type ChainNetwork uint8
const (
TestNetwork ChainNetwork = iota
ProdNetwork
)
const (
AddrLen = 20
bech32PrefixConsPub = "bcap"
bech32PrefixConsAddr = "bca"
)
var Network = ProdNetwork
func (this ChainNetwork) Bech32Prefixes() string {
switch this {
case TestNetwork:
return "tbnb"
case ProdNetwork:
return "bnb"
default:
panic("Unknown network type")
}
}
func (this ChainNetwork) Bech32ValidatorAddrPrefix() string {
return "bva"
}
// Marshal needed for protobuf compatibility
func (bz AccAddress) Marshal() ([]byte, error) {
return bz, nil
}
// Unmarshal needed for protobuf compatibility
func (bz *AccAddress) Unmarshal(data []byte) error {
*bz = data
return nil
}
// MarshalJSON to Marshals to JSON using Bech32
func (bz AccAddress) MarshalJSON() ([]byte, error) {
return json.Marshal(bz.String())
}
// UnmarshalJSON to Unmarshal from JSON assuming Bech32 encoding
func (bz *AccAddress) UnmarshalJSON(data []byte) error {
var s string
err := json.Unmarshal(data, &s)
if err != nil {
return nil
}
bz2, err := AccAddressFromBech32(s)
if err != nil {
return err
}
*bz = bz2
return nil
}
// AccAddressFromHex to create an AccAddress from a hex string
func AccAddressFromHex(address string) (addr AccAddress, err error) {
if len(address) == 0 {
return addr, errors.New("decoding bech32 address failed: must provide an address")
}
bz, err := hex.DecodeString(address)
if err != nil {
return nil, err
}
return AccAddress(bz), nil
}
// AccAddressFromBech32 to create an AccAddress from a bech32 string
func AccAddressFromBech32(address string) (addr AccAddress, err error) {
bz, err := GetFromBech32(address, Network.Bech32Prefixes())
if err != nil {
return nil, err
}
return AccAddress(bz), nil
}
// GetFromBech32 to decode a bytestring from a bech32-encoded string
func GetFromBech32(bech32str, prefix string) ([]byte, error) {
if len(bech32str) == 0 {
return nil, errors.New("decoding bech32 address failed: must provide an address")
}
hrp, bz, err := bech32.DecodeAndConvert(bech32str)
if err != nil {
return nil, err
}
if hrp != prefix {
return nil, fmt.Errorf("invalid bech32 prefix. Expected %s, Got %s", prefix, hrp)
}
return bz, nil
}
func (bz AccAddress) Bytes() []byte {
return bz
}
// String representation
func (bz AccAddress) String() string {
bech32Addr, err := bech32.ConvertAndEncode(Network.Bech32Prefixes(), bz.Bytes())
if err != nil {
panic(err)
}
return bech32Addr
}
func MustBech32ifyConsPub(pub crypto.PubKey) string {
enc, err := Bech32ifyConsPub(pub)
if err != nil {
panic(err)
}
return enc
}
// Bech32ifyConsPub returns a Bech32 encoded string containing the
// Bech32PrefixConsPub prefixfor a given consensus node's PubKey.
func Bech32ifyConsPub(pub crypto.PubKey) (string, error) {
return bech32.ConvertAndEncode(bech32PrefixConsPub, pub.Bytes())
}