/
keys.go
192 lines (167 loc) · 4.13 KB
/
keys.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package crypto
import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/hex"
"errors"
"github.com/btcsuite/btcutil/base58"
ethCommon "github.com/ethereum/go-ethereum/common"
eth "github.com/ethereum/go-ethereum/crypto"
ic "github.com/libp2p/go-libp2p-core/crypto"
)
const (
AddressLength = 21
AddressPrefix = "41"
)
type Address [AddressLength]byte
type Keys struct {
Base58Address string
HexAddress string
HexPrivateKey string
HexPubKey string
Base64PubKey string
}
func FromIcPrivateKey(privKey ic.PrivKey) (*Keys, error) {
keys := &Keys{}
pubKey := privKey.GetPublic()
var err error
keys.Base64PubKey, err = FromPubKey(pubKey)
if err != nil {
return nil, err
}
pubKeyRaw, err := ic.RawFull(pubKey)
if err != nil {
return nil, err
}
keys.HexPubKey = hex.EncodeToString(pubKeyRaw)
privKeyRaw, err := privKey.Raw()
if err != nil {
return nil, err
}
keys.HexPrivateKey = hex.EncodeToString(privKeyRaw)
// test for exchange address
privateKey, err := eth.HexToECDSA(keys.HexPrivateKey)
if err != nil {
return nil, err
}
if privateKey == nil {
return nil, err
}
addr, err := PublicKeyToAddress(privateKey.PublicKey)
if err != nil {
return nil, err
}
keys.HexAddress = hex.EncodeToString(addr.Bytes())
keys.Base58Address, err = Encode58Check(addr.Bytes())
if err != nil {
return nil, err
}
return keys, nil
}
func FromPrivateKey(key string) (*Keys, error) {
privKey, err := ToPrivKey(key)
if err != nil {
priv_key, err := Hex64ToBase64(key)
if err != nil {
return nil, err
}
privKey, err = ToPrivKey(priv_key)
if err != nil {
return nil, err
}
}
return FromIcPrivateKey(privKey)
}
// ecdsa key to Tron address
func PublicKeyToAddress(p ecdsa.PublicKey) (Address, error) {
addr := eth.PubkeyToAddress(p)
addressTron := make([]byte, AddressLength)
addressPrefix, err := FromHex(AddressPrefix)
if err != nil {
return Address{}, err
}
addressTron = append(addressTron, addressPrefix...)
addressTron = append(addressTron, addr.Bytes()...)
return BytesToAddress(addressTron), nil
}
func (a *Address) Bytes() []byte {
return a[:]
}
func BytesToAddress(b []byte) Address {
var a Address
a.SetBytes(b)
return a
}
// Convert byte to address.
func (a *Address) SetBytes(b []byte) {
if len(b) > len(a) {
b = b[len(b)-AddressLength:]
}
copy(a[AddressLength-len(b):], b)
}
// Decode hex string as bytes
func FromHex(input string) ([]byte, error) {
if len(input) == 0 {
return nil, errors.New("empty hex string")
}
return hex.DecodeString(input[:])
}
// Decode by base58 and check.
func Decode58Check(input string) ([]byte, error) {
decodeCheck := base58.Decode(input)
if len(decodeCheck) <= 4 {
return nil, errors.New("base58 encode length error")
}
decodeData := decodeCheck[:len(decodeCheck)-4]
hash0, err := Hash(decodeData)
if err != nil {
return nil, err
}
hash1, err := Hash(hash0)
if hash1 == nil {
return nil, err
}
if hash1[0] == decodeCheck[len(decodeData)] && hash1[1] == decodeCheck[len(decodeData)+1] &&
hash1[2] == decodeCheck[len(decodeData)+2] && hash1[3] == decodeCheck[len(decodeData)+3] {
return decodeData, nil
}
return nil, errors.New("base58 check failed")
}
// Encode by base58 and check.
func Encode58Check(input []byte) (string, error) {
h0, err := Hash(input)
if err != nil {
return "", err
}
h1, err := Hash(h0)
if err != nil {
return "", err
}
if len(h1) < 4 {
return "", errors.New("base58 encode length error")
}
inputCheck := append(input, h1[:4]...)
return base58.Encode(inputCheck), nil
}
//Package goLang sha256 hash algorithm.
func Hash(s []byte) ([]byte, error) {
h := sha256.New()
_, err := h.Write(s)
if err != nil {
return nil, err
}
bs := h.Sum(nil)
return bs, nil
}
// Get Tron address from ledger address
func AddressLedgerToTron(ledgerAddress []byte) (Address, error) {
addr := ethCommon.BytesToAddress(eth.Keccak256(ledgerAddress[1:])[12:])
addressTron := make([]byte, AddressLength)
addressPrefix, err := FromHex(AddressPrefix)
if err != nil {
return Address{}, err
}
addressTron = append(addressTron, addressPrefix...)
addressTron = append(addressTron, addr.Bytes()...)
return BytesToAddress(addressTron), nil
}