/
address.go
66 lines (61 loc) · 1.43 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
package util
import (
"encoding/base32"
"errors"
"golang.org/x/crypto/blake2b"
)
// AddressToPubkey converts address to a pubkey.
func AddressToPubkey(address string) (pubkey []byte, err error) {
err = errors.New("invalid address")
switch len(address) {
case 64:
if address[:4] != "xrb_" {
return
}
address = address[4:]
case 65:
if address[:5] != "nano_" {
return
}
address = address[5:]
default:
return
}
b32 := base32.NewEncoding("13456789abcdefghijkmnopqrstuwxyz")
if pubkey, err = b32.DecodeString("1111" + address[:52]); err != nil {
return
}
pubkey = pubkey[3:]
checksum, err := checksum(pubkey)
if err != nil {
return
}
if b32.EncodeToString(checksum) != address[52:] {
err = errors.New("checksum mismatch")
}
return
}
// PubkeyToAddress converts pubkey to an address.
func PubkeyToAddress(pubkey []byte) (address string, err error) {
if len(pubkey) != 32 {
return "", errors.New("invalid pubkey length")
}
checksum, err := checksum(pubkey)
if err != nil {
return
}
pubkey = append([]byte{0, 0, 0}, pubkey...)
b32 := base32.NewEncoding("13456789abcdefghijkmnopqrstuwxyz")
return "nano_" + b32.EncodeToString(pubkey)[4:] + b32.EncodeToString(checksum), nil
}
func checksum(pubkey []byte) (checksum []byte, err error) {
hash, err := blake2b.New(5, nil)
if err != nil {
return
}
hash.Write(pubkey)
for _, b := range hash.Sum(nil) {
checksum = append([]byte{b}, checksum...)
}
return
}