Skip to content

Commit 964201c

Browse files
Merge pull request #14 from tokenized/develop
Technical Standards Committee Specifications Implement Miner ID, Merchant API, SPV Channels, and TSC merkle proofs. Update bitcoin scripts. Update logger fields including timestamps.
2 parents 6e2d59c + 627e5ee commit 964201c

File tree

135 files changed

+7897
-738
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+7897
-738
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
*.prof
55
*.log
66
tmp
7+
*.env

bitcoin/address.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ const (
3030
AddressTypeTestRPH = 0x7d // RPH (starts with s) - Experimental value. Not standard
3131
AddressTypeTestPK = 0x07 // Public Key - Experimental value. Not standard
3232
AddressTypeTestNonStandard = 0x09 // Unknown, but possibly spendable locking script
33-
3433
)
3534

3635
type Address struct {

bitcoin/extended_key.go

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"crypto/rand"
77
"crypto/sha512"
88
"encoding/binary"
9-
"encoding/hex"
109
"fmt"
1110
"io"
1211
"strconv"
@@ -133,7 +132,7 @@ func ExtendedKeyFromStr(s string) (ExtendedKey, error) {
133132
// Fall back to BIP-0032 format
134133
bip32Key, b32err := bip32.B58Deserialize(s)
135134
if b32err != nil {
136-
return ExtendedKey{}, errors.Wrap(err, "decode xkey hex string")
135+
return ExtendedKey{}, errors.Wrap(err, "base58 deserialize")
137136
}
138137

139138
return fromBIP32(bip32Key)
@@ -218,7 +217,9 @@ func (k ExtendedKey) String() string {
218217

219218
// String58 returns the key formatted as base 58 text.
220219
func (k ExtendedKey) String58() string {
221-
return BIP0276Encode58(k.Network, ExtendedKeyURLPrefix, k.Bytes())
220+
// return BIP0276Encode58(k.Network, ExtendedKeyURLPrefix, k.Bytes())
221+
bip32 := k.ToBIP32()
222+
return bip32.String()
222223
}
223224

224225
// SetString decodes a key from hex text.
@@ -460,22 +461,14 @@ func (k *ExtendedKey) UnmarshalJSON(data []byte) error {
460461
// MarshalText returns the text encoding of the extended key.
461462
// Implements encoding.TextMarshaler interface.
462463
func (k ExtendedKey) MarshalText() ([]byte, error) {
463-
b := k.Bytes()
464-
result := make([]byte, hex.EncodedLen(len(b)))
465-
hex.Encode(result, b)
466-
return result, nil
464+
s := k.String58()
465+
return []byte(s), nil
467466
}
468467

469468
// UnmarshalText parses a text encoded extended key and sets the value of this object.
470469
// Implements encoding.TextUnmarshaler interface.
471470
func (k *ExtendedKey) UnmarshalText(text []byte) error {
472-
b := make([]byte, hex.DecodedLen(len(text)))
473-
_, err := hex.Decode(b, text)
474-
if err != nil {
475-
return err
476-
}
477-
478-
return k.SetBytes(b)
471+
return k.SetString58(string(text))
479472
}
480473

481474
// MarshalBinary returns the binary encoding of the extended key.
@@ -526,6 +519,30 @@ func (k *ExtendedKey) setFromBIP32(old *bip32.Key) error {
526519
return nil
527520
}
528521

522+
func (k ExtendedKey) ToBIP32() bip32.Key {
523+
var result bip32.Key
524+
525+
result.FingerPrint = make([]byte, 4)
526+
copy(result.FingerPrint, k.FingerPrint[:])
527+
result.ChildNumber = make([]byte, 4)
528+
binary.BigEndian.PutUint32(result.ChildNumber, k.Index)
529+
result.ChainCode = make([]byte, 32)
530+
copy(result.ChainCode, k.ChainCode[:])
531+
result.Depth = k.Depth
532+
if k.KeyValue[0] == 0 {
533+
result.IsPrivate = true
534+
result.Version = bip32.PrivateWalletVersion
535+
result.Key = make([]byte, 32)
536+
copy(result.Key, k.KeyValue[1:])
537+
} else {
538+
result.Version = bip32.PublicWalletVersion
539+
result.Key = make([]byte, 33)
540+
copy(result.Key, k.KeyValue[:])
541+
}
542+
543+
return result
544+
}
545+
529546
// read reads just the basic data of the extended key.
530547
func (k *ExtendedKey) read(r io.Reader) error {
531548
var b [1]byte

bitcoin/extended_key_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ func TestExtendedKeyVsBIP0032(t *testing.T) {
143143
}
144144

145145
func TestExtendedKey(t *testing.T) {
146+
t.Skip() // This tests the new encoding format which is currently disabled --ce
147+
146148
tests := []struct {
147149
name string
148150
key string
@@ -376,6 +378,10 @@ func TestOldExtendedKey(t *testing.T) {
376378
t.Fatalf("Failed to deserialize new key : %s", err)
377379
}
378380

381+
if newKey.String58() != bip32Key.String() {
382+
t.Fatalf("Wrong string 58 : got %s, want %s", newKey.String58(), bip32Key.String())
383+
}
384+
379385
if !bytes.Equal(newKey.KeyValue[:], bip32Key.Key) {
380386
t.Fatalf("Imported keys not equal :\n got : %x\n want : %x", newKey.KeyValue[:],
381387
bip32Key.Key)

bitcoin/extended_keys.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,11 @@ func (k ExtendedKeys) String() string {
168168

169169
// String58 returns the list of keys formatted as base58 text.
170170
func (k ExtendedKeys) String58() string {
171+
if len(k) == 1 {
172+
// Temporarily use singular BIP32 encoding --ce
173+
return k[0].String58()
174+
}
175+
171176
var net Network
172177
if len(k) > 0 {
173178
net = k[0].Network

bitcoin/hash20.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"fmt"
77
"io"
8+
"math/big"
89

910
"github.com/pkg/errors"
1011
)
@@ -54,6 +55,19 @@ func (h Hash20) Bytes() []byte {
5455
return h[:]
5556
}
5657

58+
// Bytes returns the bytes in reverse order (big endian).
59+
func (h Hash20) ReverseBytes() []byte {
60+
b := make([]byte, Hash20Size)
61+
reverse20(b, h[:])
62+
return b
63+
}
64+
65+
func (h Hash20) Value() *big.Int {
66+
value := &big.Int{}
67+
value.SetBytes(h.ReverseBytes())
68+
return value
69+
}
70+
5771
// SetBytes sets the value of the hash.
5872
func (h *Hash20) SetBytes(b []byte) error {
5973
if len(b) != Hash20Size {
@@ -119,15 +133,20 @@ func (h Hash20) MarshalJSON() ([]byte, error) {
119133

120134
// UnmarshalJSON converts from json.
121135
func (h *Hash20) UnmarshalJSON(data []byte) error {
122-
if len(data) != (2*Hash20Size)+2 {
123-
return fmt.Errorf("Wrong size hex for Hash20 : %d", len(data)-2)
136+
b, err := ConvertJSONHexToBytes(data)
137+
if err != nil {
138+
return errors.Wrap(err, "hex")
124139
}
125140

126-
b := make([]byte, Hash20Size)
127-
_, err := hex.Decode(b, data[1:len(data)-1])
128-
if err != nil {
129-
return err
141+
if len(b) == 0 {
142+
h = nil
143+
return nil
144+
}
145+
146+
if len(b) != Hash20Size {
147+
return fmt.Errorf("Wrong size hex for Hash20 : %d", len(b)*2)
130148
}
149+
131150
reverse20(h[:], b)
132151
return nil
133152
}

bitcoin/hash32.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"fmt"
77
"io"
8+
"math/big"
89

910
"github.com/pkg/errors"
1011
)
@@ -57,6 +58,19 @@ func (h Hash32) Bytes() []byte {
5758
return h[:]
5859
}
5960

61+
// Bytes returns the bytes in reverse order (big endian).
62+
func (h Hash32) ReverseBytes() []byte {
63+
b := make([]byte, Hash32Size)
64+
reverse32(b, h[:])
65+
return b
66+
}
67+
68+
func (h Hash32) Value() *big.Int {
69+
value := &big.Int{}
70+
value.SetBytes(h.ReverseBytes())
71+
return value
72+
}
73+
6074
// SetBytes sets the value of the hash.
6175
func (h *Hash32) SetBytes(b []byte) error {
6276
if len(b) != Hash32Size {
@@ -122,15 +136,20 @@ func (h Hash32) MarshalJSON() ([]byte, error) {
122136

123137
// UnmarshalJSON converts from json.
124138
func (h *Hash32) UnmarshalJSON(data []byte) error {
125-
if len(data) != (2*Hash32Size)+2 {
126-
return fmt.Errorf("Wrong size hex for Hash32 : %d", len(data)-2)
139+
b, err := ConvertJSONHexToBytes(data)
140+
if err != nil {
141+
return errors.Wrap(err, "hex")
127142
}
128143

129-
b := make([]byte, Hash32Size)
130-
_, err := hex.Decode(b, data[1:len(data)-1])
131-
if err != nil {
132-
return err
144+
if len(b) == 0 {
145+
h = nil
146+
return nil
147+
}
148+
149+
if len(b) != Hash32Size {
150+
return fmt.Errorf("Wrong size hex for Hash32 : %d", len(b)*2)
133151
}
152+
134153
reverse32(h[:], b)
135154
return nil
136155
}

bitcoin/hex.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package bitcoin
2+
3+
import (
4+
"encoding/hex"
5+
"errors"
6+
)
7+
8+
var (
9+
ErrMissingQuotes = errors.New("Must be contained in quotes")
10+
)
11+
12+
// Hex is used in structures as a byte slice that will marshal as hex instead of base64 like is
13+
// default for json.
14+
type Hex []byte
15+
16+
func (b Hex) MarshalJSON() ([]byte, error) {
17+
return ConvertBytesToJSONHex(b)
18+
}
19+
20+
func (b *Hex) UnmarshalJSON(data []byte) error {
21+
d, err := ConvertJSONHexToBytes(data)
22+
if err != nil {
23+
return err
24+
}
25+
26+
*b = d
27+
return nil
28+
}
29+
30+
func (b Hex) MarshalText() ([]byte, error) {
31+
result := make([]byte, hex.EncodedLen(len(b)))
32+
hex.Encode(result, b)
33+
return result, nil
34+
}
35+
36+
func (b *Hex) UnmarshalText(text []byte) error {
37+
d := make([]byte, hex.DecodedLen(len(text)))
38+
_, err := hex.Decode(d, text)
39+
if err != nil {
40+
return err
41+
}
42+
43+
*b = d
44+
return nil
45+
}
46+
47+
func (b Hex) MarshalBinary() ([]byte, error) {
48+
return b, nil
49+
}
50+
51+
func (b *Hex) UnmarshalBinary(data []byte) error {
52+
*b = data
53+
return nil
54+
}
55+
56+
func ConvertBytesToJSONHex(b []byte) ([]byte, error) {
57+
hexLen := hex.EncodedLen(len(b))
58+
59+
result := make([]byte, hexLen+2)
60+
result[0] = '"'
61+
hex.Encode(result[1:], b)
62+
result[hexLen+1] = '"'
63+
64+
return result, nil
65+
}
66+
67+
func ConvertJSONHexToBytes(js []byte) ([]byte, error) {
68+
l := len(js)
69+
if l < 2 {
70+
return nil, ErrMissingQuotes
71+
}
72+
if js[0] != '"' || js[l-1] != '"' {
73+
return nil, ErrMissingQuotes
74+
}
75+
76+
byteLen := hex.DecodedLen(l - 2)
77+
b := make([]byte, byteLen)
78+
_, err := hex.Decode(b, js[1:l-1])
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
return b, nil
84+
}

0 commit comments

Comments
 (0)