Skip to content

Commit fbb7073

Browse files
authored
Merge pull request #293 from blinklabs-io/feat/ledger-address
feat: properly handle addresses in ledger
2 parents 8d547f9 + 49c4bbf commit fbb7073

File tree

17 files changed

+1074
-12
lines changed

17 files changed

+1074
-12
lines changed

cmd/block-fetch/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func main() {
9696
}
9797
fmt.Printf(" Outputs:\n")
9898
for _, output := range tx.Outputs() {
99-
fmt.Printf(" Address: %x\n", output.Address())
99+
fmt.Printf(" Address: %s\n", output.Address())
100100
fmt.Printf(" Amount: %d\n", output.Amount())
101101
assets := output.Assets()
102102
if assets != nil {

internal/base58/alphabet.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2015 The btcsuite developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
// NOTE: this file was copied from:
6+
// https://github.com/btcsuite/btcd/tree/v0.23.4/btcutil/base58
7+
8+
// AUTOGENERATED by genalphabet.go; do not edit.
9+
10+
package base58
11+
12+
const (
13+
// alphabet is the modified base58 alphabet used by Bitcoin.
14+
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
15+
16+
alphabetIdx0 = '1'
17+
)
18+
19+
var b58 = [256]byte{
20+
255, 255, 255, 255, 255, 255, 255, 255,
21+
255, 255, 255, 255, 255, 255, 255, 255,
22+
255, 255, 255, 255, 255, 255, 255, 255,
23+
255, 255, 255, 255, 255, 255, 255, 255,
24+
255, 255, 255, 255, 255, 255, 255, 255,
25+
255, 255, 255, 255, 255, 255, 255, 255,
26+
255, 0, 1, 2, 3, 4, 5, 6,
27+
7, 8, 255, 255, 255, 255, 255, 255,
28+
255, 9, 10, 11, 12, 13, 14, 15,
29+
16, 255, 17, 18, 19, 20, 21, 255,
30+
22, 23, 24, 25, 26, 27, 28, 29,
31+
30, 31, 32, 255, 255, 255, 255, 255,
32+
255, 33, 34, 35, 36, 37, 38, 39,
33+
40, 41, 42, 43, 255, 44, 45, 46,
34+
47, 48, 49, 50, 51, 52, 53, 54,
35+
55, 56, 57, 255, 255, 255, 255, 255,
36+
255, 255, 255, 255, 255, 255, 255, 255,
37+
255, 255, 255, 255, 255, 255, 255, 255,
38+
255, 255, 255, 255, 255, 255, 255, 255,
39+
255, 255, 255, 255, 255, 255, 255, 255,
40+
255, 255, 255, 255, 255, 255, 255, 255,
41+
255, 255, 255, 255, 255, 255, 255, 255,
42+
255, 255, 255, 255, 255, 255, 255, 255,
43+
255, 255, 255, 255, 255, 255, 255, 255,
44+
255, 255, 255, 255, 255, 255, 255, 255,
45+
255, 255, 255, 255, 255, 255, 255, 255,
46+
255, 255, 255, 255, 255, 255, 255, 255,
47+
255, 255, 255, 255, 255, 255, 255, 255,
48+
255, 255, 255, 255, 255, 255, 255, 255,
49+
255, 255, 255, 255, 255, 255, 255, 255,
50+
255, 255, 255, 255, 255, 255, 255, 255,
51+
255, 255, 255, 255, 255, 255, 255, 255,
52+
}

internal/base58/base58.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright (c) 2013-2015 The btcsuite developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
// NOTE: this file was copied from:
6+
// https://github.com/btcsuite/btcd/tree/v0.23.4/btcutil/base58
7+
8+
package base58
9+
10+
import (
11+
"math/big"
12+
)
13+
14+
//go:generate go run genalphabet.go
15+
16+
var bigRadix = [...]*big.Int{
17+
big.NewInt(0),
18+
big.NewInt(58),
19+
big.NewInt(58 * 58),
20+
big.NewInt(58 * 58 * 58),
21+
big.NewInt(58 * 58 * 58 * 58),
22+
big.NewInt(58 * 58 * 58 * 58 * 58),
23+
big.NewInt(58 * 58 * 58 * 58 * 58 * 58),
24+
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58),
25+
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
26+
big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58),
27+
bigRadix10,
28+
}
29+
30+
var bigRadix10 = big.NewInt(58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58 * 58) // 58^10
31+
32+
// Decode decodes a modified base58 string to a byte slice.
33+
func Decode(b string) []byte {
34+
answer := big.NewInt(0)
35+
scratch := new(big.Int)
36+
37+
// Calculating with big.Int is slow for each iteration.
38+
// x += b58[b[i]] * j
39+
// j *= 58
40+
//
41+
// Instead we can try to do as much calculations on int64.
42+
// We can represent a 10 digit base58 number using an int64.
43+
//
44+
// Hence we'll try to convert 10, base58 digits at a time.
45+
// The rough idea is to calculate `t`, such that:
46+
//
47+
// t := b58[b[i+9]] * 58^9 ... + b58[b[i+1]] * 58^1 + b58[b[i]] * 58^0
48+
// x *= 58^10
49+
// x += t
50+
//
51+
// Of course, in addition, we'll need to handle boundary condition when `b` is not multiple of 58^10.
52+
// In that case we'll use the bigRadix[n] lookup for the appropriate power.
53+
for t := b; len(t) > 0; {
54+
n := len(t)
55+
if n > 10 {
56+
n = 10
57+
}
58+
59+
total := uint64(0)
60+
for _, v := range t[:n] {
61+
if v > 255 {
62+
return []byte("")
63+
}
64+
65+
tmp := b58[v]
66+
if tmp == 255 {
67+
return []byte("")
68+
}
69+
total = total*58 + uint64(tmp)
70+
}
71+
72+
answer.Mul(answer, bigRadix[n])
73+
scratch.SetUint64(total)
74+
answer.Add(answer, scratch)
75+
76+
t = t[n:]
77+
}
78+
79+
tmpval := answer.Bytes()
80+
81+
var numZeros int
82+
for numZeros = 0; numZeros < len(b); numZeros++ {
83+
if b[numZeros] != alphabetIdx0 {
84+
break
85+
}
86+
}
87+
flen := numZeros + len(tmpval)
88+
val := make([]byte, flen)
89+
copy(val[numZeros:], tmpval)
90+
91+
return val
92+
}
93+
94+
// Encode encodes a byte slice to a modified base58 string.
95+
func Encode(b []byte) string {
96+
x := new(big.Int)
97+
x.SetBytes(b)
98+
99+
// maximum length of output is log58(2^(8*len(b))) == len(b) * 8 / log(58)
100+
maxlen := int(float64(len(b))*1.365658237309761) + 1
101+
answer := make([]byte, 0, maxlen)
102+
mod := new(big.Int)
103+
for x.Sign() > 0 {
104+
// Calculating with big.Int is slow for each iteration.
105+
// x, mod = x / 58, x % 58
106+
//
107+
// Instead we can try to do as much calculations on int64.
108+
// x, mod = x / 58^10, x % 58^10
109+
//
110+
// Which will give us mod, which is 10 digit base58 number.
111+
// We'll loop that 10 times to convert to the answer.
112+
113+
x.DivMod(x, bigRadix10, mod)
114+
if x.Sign() == 0 {
115+
// When x = 0, we need to ensure we don't add any extra zeros.
116+
m := mod.Int64()
117+
for m > 0 {
118+
answer = append(answer, alphabet[m%58])
119+
m /= 58
120+
}
121+
} else {
122+
m := mod.Int64()
123+
for i := 0; i < 10; i++ {
124+
answer = append(answer, alphabet[m%58])
125+
m /= 58
126+
}
127+
}
128+
}
129+
130+
// leading zero bytes
131+
for _, i := range b {
132+
if i != 0 {
133+
break
134+
}
135+
answer = append(answer, alphabetIdx0)
136+
}
137+
138+
// reverse
139+
alen := len(answer)
140+
for i := 0; i < alen/2; i++ {
141+
answer[i], answer[alen-1-i] = answer[alen-1-i], answer[i]
142+
}
143+
144+
return string(answer)
145+
}

internal/base58/base58check.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2013-2014 The btcsuite developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
// NOTE: this file was copied from:
6+
// https://github.com/btcsuite/btcd/tree/v0.23.4/btcutil/base58
7+
8+
package base58
9+
10+
import (
11+
"crypto/sha256"
12+
"errors"
13+
)
14+
15+
// ErrChecksum indicates that the checksum of a check-encoded string does not verify against
16+
// the checksum.
17+
var ErrChecksum = errors.New("checksum error")
18+
19+
// ErrInvalidFormat indicates that the check-encoded string has an invalid format.
20+
var ErrInvalidFormat = errors.New("invalid format: version and/or checksum bytes missing")
21+
22+
// checksum: first four bytes of sha256^2
23+
func checksum(input []byte) (cksum [4]byte) {
24+
h := sha256.Sum256(input)
25+
h2 := sha256.Sum256(h[:])
26+
copy(cksum[:], h2[:4])
27+
return
28+
}
29+
30+
// CheckEncode prepends a version byte and appends a four byte checksum.
31+
func CheckEncode(input []byte, version byte) string {
32+
b := make([]byte, 0, 1+len(input)+4)
33+
b = append(b, version)
34+
b = append(b, input...)
35+
cksum := checksum(b)
36+
b = append(b, cksum[:]...)
37+
return Encode(b)
38+
}
39+
40+
// CheckDecode decodes a string that was encoded with CheckEncode and verifies the checksum.
41+
func CheckDecode(input string) (result []byte, version byte, err error) {
42+
decoded := Decode(input)
43+
if len(decoded) < 5 {
44+
return nil, 0, ErrInvalidFormat
45+
}
46+
version = decoded[0]
47+
var cksum [4]byte
48+
copy(cksum[:], decoded[len(decoded)-4:])
49+
if checksum(decoded[:len(decoded)-4]) != cksum {
50+
return nil, 0, ErrChecksum
51+
}
52+
payload := decoded[1 : len(decoded)-4]
53+
result = append(result, payload...)
54+
return
55+
}

internal/base58/doc.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2014 The btcsuite developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
// NOTE: this file was copied from:
6+
// https://github.com/btcsuite/btcd/tree/v0.23.4/btcutil/base58
7+
8+
/*
9+
Package base58 provides an API for working with modified base58 and Base58Check
10+
encodings.
11+
12+
Modified Base58 Encoding
13+
14+
Standard base58 encoding is similar to standard base64 encoding except, as the
15+
name implies, it uses a 58 character alphabet which results in an alphanumeric
16+
string and allows some characters which are problematic for humans to be
17+
excluded. Due to this, there can be various base58 alphabets.
18+
19+
The modified base58 alphabet used by Bitcoin, and hence this package, omits the
20+
0, O, I, and l characters that look the same in many fonts and are therefore
21+
hard to humans to distinguish.
22+
23+
Base58Check Encoding Scheme
24+
25+
The Base58Check encoding scheme is primarily used for Bitcoin addresses at the
26+
time of this writing, however it can be used to generically encode arbitrary
27+
byte arrays into human-readable strings along with a version byte that can be
28+
used to differentiate the same payload. For Bitcoin addresses, the extra
29+
version is used to differentiate the network of otherwise identical public keys
30+
which helps prevent using an address intended for one network on another.
31+
*/
32+
package base58

internal/base58/genalphabet.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) 2015 The btcsuite developers
2+
// Use of this source code is governed by an ISC
3+
// license that can be found in the LICENSE file.
4+
5+
// NOTE: this file was copied from:
6+
// https://github.com/btcsuite/btcd/tree/v0.23.4/btcutil/base58
7+
8+
//go:build ignore
9+
// +build ignore
10+
11+
package main
12+
13+
import (
14+
"bytes"
15+
"io"
16+
"log"
17+
"os"
18+
"strconv"
19+
)
20+
21+
var (
22+
start = []byte(`// Copyright (c) 2015 The btcsuite developers
23+
// Use of this source code is governed by an ISC
24+
// license that can be found in the LICENSE file.
25+
26+
// AUTOGENERATED by genalphabet.go; do not edit.
27+
28+
package base58
29+
30+
const (
31+
// alphabet is the modified base58 alphabet used by Bitcoin.
32+
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
33+
34+
alphabetIdx0 = '1'
35+
)
36+
37+
var b58 = [256]byte{`)
38+
39+
end = []byte(`}`)
40+
41+
alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
42+
tab = []byte("\t")
43+
invalid = []byte("255")
44+
comma = []byte(",")
45+
space = []byte(" ")
46+
nl = []byte("\n")
47+
)
48+
49+
func write(w io.Writer, b []byte) {
50+
_, err := w.Write(b)
51+
if err != nil {
52+
log.Fatal(err)
53+
}
54+
}
55+
56+
func main() {
57+
fi, err := os.Create("alphabet.go")
58+
if err != nil {
59+
log.Fatal(err)
60+
}
61+
defer fi.Close()
62+
63+
write(fi, start)
64+
write(fi, nl)
65+
for i := byte(0); i < 32; i++ {
66+
write(fi, tab)
67+
for j := byte(0); j < 8; j++ {
68+
idx := bytes.IndexByte(alphabet, i*8+j)
69+
if idx == -1 {
70+
write(fi, invalid)
71+
} else {
72+
write(fi, strconv.AppendInt(nil, int64(idx), 10))
73+
}
74+
write(fi, comma)
75+
if j != 7 {
76+
write(fi, space)
77+
}
78+
}
79+
write(fi, nl)
80+
}
81+
write(fi, end)
82+
write(fi, nl)
83+
}

0 commit comments

Comments
 (0)