Skip to content

Commit 95d015d

Browse files
committed
Added two new WIF methods
1 parent dee6335 commit 95d015d

File tree

5 files changed

+292
-5
lines changed

5 files changed

+292
-5
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ View the generated [documentation](https://pkg.go.dev/github.com/bitcoinschema/g
7474
- [PubKey from String](pubkey.go)
7575
- **Private Keys**
7676
- [Create PrivateKey](private_key.go)
77+
- [Create WIF](private_key.go)
7778
- [PrivateKey (string) to Address (string)](address.go)
7879
- [PrivateKey from string](private_key.go)
7980
- [Generate Shared Keypair](private_key.go)

examples/create_wif/create_wif.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package main
2+
3+
import (
4+
"log"
5+
6+
"github.com/bitcoinschema/go-bitcoin/v2"
7+
)
8+
9+
func main() {
10+
11+
// Create a wif
12+
wifString, err := bitcoin.CreateWifString()
13+
if err != nil {
14+
log.Fatalf("error occurred: %s", err.Error())
15+
}
16+
17+
// Success!
18+
log.Printf("wif key: %s", wifString)
19+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import (
4+
"log"
5+
6+
"github.com/libsv/go-bk/wif"
7+
8+
"github.com/bitcoinschema/go-bitcoin/v2"
9+
)
10+
11+
func main() {
12+
13+
// Create a wif
14+
wifString, err := bitcoin.CreateWifString()
15+
if err != nil {
16+
log.Fatalf("error occurred: %s", err.Error())
17+
}
18+
19+
// Create a wif from a string
20+
var wifKey *wif.WIF
21+
wifKey, err = bitcoin.WifFromString(wifString)
22+
if err != nil {
23+
log.Fatalf("error occurred: %s", err.Error())
24+
}
25+
26+
// Success!
27+
log.Printf("wif key: %s is also: %s", wifString, wifKey.String())
28+
}

private_key.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package bitcoin
33
import (
44
"crypto/ecdsa"
55
"encoding/hex"
6-
"errors"
76
"math/big"
87

98
"github.com/libsv/go-bk/bec"
@@ -24,7 +23,7 @@ func GenerateSharedKeyPair(privateKey *bec.PrivateKey,
2423
// PrivateKeyFromString turns a private key (hex encoded string) into an bec.PrivateKey
2524
func PrivateKeyFromString(privateKey string) (*bec.PrivateKey, error) {
2625
if len(privateKey) == 0 {
27-
return nil, errors.New("privateKey is missing")
26+
return nil, ErrPrivateKeyMissing
2827
}
2928
privateKeyBytes, err := hex.DecodeString(privateKey)
3029
if err != nil {
@@ -54,13 +53,33 @@ func CreatePrivateKeyString() (string, error) {
5453
return hex.EncodeToString(privateKey.Serialise()), nil
5554
}
5655

56+
// CreateWif will create a new WIF (*wif.WIF)
57+
func CreateWif() (*wif.WIF, error) {
58+
privateKey, err := CreatePrivateKey()
59+
if err != nil {
60+
return nil, err
61+
}
62+
63+
return wif.NewWIF(privateKey, &chaincfg.MainNet, false)
64+
}
65+
66+
// CreateWifString will create a new WIF (string)
67+
func CreateWifString() (string, error) {
68+
wifKey, err := CreateWif()
69+
if err != nil {
70+
return "", err
71+
}
72+
73+
return wifKey.String(), nil
74+
}
75+
5776
// PrivateAndPublicKeys will return both the private and public key in one method
5877
// Expects a hex encoded privateKey
5978
func PrivateAndPublicKeys(privateKey string) (*bec.PrivateKey, *bec.PublicKey, error) {
6079

6180
// No key?
6281
if len(privateKey) == 0 {
63-
return nil, nil, errors.New("missing privateKey")
82+
return nil, nil, ErrPrivateKeyMissing
6483
}
6584

6685
// Decode the private key into bytes
@@ -79,7 +98,7 @@ func PrivateKeyToWif(privateKey string) (*wif.WIF, error) {
7998

8099
// Missing private key
81100
if len(privateKey) == 0 {
82-
return nil, errors.New("missing privateKey")
101+
return nil, ErrPrivateKeyMissing
83102
}
84103

85104
// Decode the private key
@@ -110,7 +129,7 @@ func WifToPrivateKey(wifKey string) (*bec.PrivateKey, error) {
110129

111130
// Missing wif?
112131
if len(wifKey) == 0 {
113-
return nil, errors.New("missing wif")
132+
return nil, ErrWifMissing
114133
}
115134

116135
// Decode the wif
@@ -135,3 +154,20 @@ func WifToPrivateKeyString(wif string) (string, error) {
135154
// Return the hex (string) version of the private key
136155
return hex.EncodeToString(privateKey.Serialise()), nil
137156
}
157+
158+
// WifFromString will convert a WIF (string) to a WIF (*wif.WIF)
159+
func WifFromString(wifKey string) (*wif.WIF, error) {
160+
161+
// Missing wif?
162+
if len(wifKey) == 0 {
163+
return nil, ErrWifMissing
164+
}
165+
166+
// Decode the WIF
167+
decodedWif, err := wif.DecodeWIF(wifKey)
168+
if err != nil {
169+
return nil, err
170+
}
171+
172+
return decodedWif, nil
173+
}

private_key_test.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55
"fmt"
66
"testing"
77

8+
"github.com/libsv/go-bk/bec"
9+
"github.com/libsv/go-bk/wif"
810
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
912
)
1013

1114
// TestCreatePrivateKey will test the method CreatePrivateKey()
@@ -371,3 +374,203 @@ func BenchmarkWifToPrivateKeyString(b *testing.B) {
371374
_, _ = WifToPrivateKeyString("5JTHas7yTFMBLqgFogxZFf8Vc5uKEbkE7yQAQ2g3xPHo2sNG1Ei")
372375
}
373376
}
377+
378+
// TestCreateWif will test the method CreateWif()
379+
func TestCreateWif(t *testing.T) {
380+
t.Run("TestCreateWif", func(t *testing.T) {
381+
t.Parallel()
382+
383+
// Create a WIF
384+
wifKey, err := CreateWif()
385+
require.NoError(t, err)
386+
require.NotNil(t, wifKey)
387+
// t.Log("WIF:", wifKey.String())
388+
require.Equalf(t, 51, len(wifKey.String()), "WIF should be 51 characters long, got: %d", len(wifKey.String()))
389+
})
390+
391+
t.Run("TestWifToPrivateKey", func(t *testing.T) {
392+
t.Parallel()
393+
394+
// Create a WIF
395+
wifKey, err := CreateWif()
396+
require.NoError(t, err)
397+
require.NotNil(t, wifKey)
398+
// t.Log("WIF:", wifKey.String())
399+
require.Equalf(t, 51, len(wifKey.String()), "WIF should be 51 characters long, got: %d", len(wifKey.String()))
400+
401+
// Convert WIF to Private Key
402+
var privateKey *bec.PrivateKey
403+
privateKey, err = WifToPrivateKey(wifKey.String())
404+
require.NoError(t, err)
405+
require.NotNil(t, privateKey)
406+
privateKeyString := hex.EncodeToString(privateKey.Serialise())
407+
// t.Log("Private Key:", privateKeyString)
408+
require.Equalf(t, 64, len(privateKeyString), "Private Key should be 64 characters long, got: %d", len(privateKeyString))
409+
})
410+
}
411+
412+
// ExampleCreateWif example using CreateWif()
413+
func ExampleCreateWif() {
414+
wifKey, err := CreateWif()
415+
if err != nil {
416+
fmt.Println(err)
417+
return
418+
}
419+
fmt.Println("WIF Key Generated Length:", len(wifKey.String()))
420+
// Output: WIF Key Generated Length: 51
421+
}
422+
423+
// BenchmarkCreateWif benchmarks the method CreateWif()
424+
func BenchmarkCreateWif(b *testing.B) {
425+
for i := 0; i < b.N; i++ {
426+
_, _ = CreateWif()
427+
}
428+
}
429+
430+
// TestCreateWifString will test the method CreateWifString()
431+
func TestCreateWifString(t *testing.T) {
432+
t.Run("TestCreateWifString", func(t *testing.T) {
433+
t.Parallel()
434+
435+
// Create a WIF
436+
wifKey, err := CreateWifString()
437+
require.NoError(t, err)
438+
require.NotNil(t, wifKey)
439+
// t.Log("WIF:", wifKey)
440+
require.Equalf(t, 51, len(wifKey), "WIF should be 51 characters long, got: %d", len(wifKey))
441+
})
442+
443+
t.Run("TestWifToPrivateKeyString", func(t *testing.T) {
444+
t.Parallel()
445+
446+
// Create a WIF
447+
wifKey, err := CreateWifString()
448+
require.NoError(t, err)
449+
require.NotNil(t, wifKey)
450+
// t.Log("WIF:", wifKey)
451+
require.Equalf(t, 51, len(wifKey), "WIF should be 51 characters long, got: %d", len(wifKey))
452+
453+
// Convert WIF to Private Key
454+
var privateKeyString string
455+
privateKeyString, err = WifToPrivateKeyString(wifKey)
456+
require.NoError(t, err)
457+
require.NotNil(t, privateKeyString)
458+
// t.Log("Private Key:", privateKeyString)
459+
require.Equalf(t, 64, len(privateKeyString), "Private Key should be 64 characters long, got: %d", len(privateKeyString))
460+
461+
})
462+
}
463+
464+
// ExampleCreateWifString example using CreateWifString()
465+
func ExampleCreateWifString() {
466+
wifKey, err := CreateWifString()
467+
if err != nil {
468+
fmt.Println(err)
469+
return
470+
}
471+
fmt.Println("WIF Key Generated Length:", len(wifKey))
472+
// Output: WIF Key Generated Length: 51
473+
}
474+
475+
// BenchmarkCreateWifString benchmarks the method CreateWifString()
476+
func BenchmarkCreateWifString(b *testing.B) {
477+
for i := 0; i < b.N; i++ {
478+
_, _ = CreateWifString()
479+
}
480+
}
481+
482+
// TestWifFromString will test the method WifFromString()
483+
func TestWifFromString(t *testing.T) {
484+
t.Run("TestCreateWifFromPrivateKey", func(t *testing.T) {
485+
t.Parallel()
486+
487+
// Create a Private Key
488+
privateKey, err := CreatePrivateKeyString()
489+
require.NoError(t, err)
490+
require.NotNil(t, privateKey)
491+
492+
// Create a WIF
493+
var wifKey *wif.WIF
494+
wifKey, err = PrivateKeyToWif(privateKey)
495+
require.NoError(t, err)
496+
require.NotNil(t, wifKey)
497+
wifKeyString := wifKey.String()
498+
t.Log("WIF:", wifKeyString)
499+
require.Equalf(t, 51, len(wifKeyString), "WIF should be 51 characters long, got: %d", len(wifKeyString))
500+
501+
// Convert WIF to Private Key
502+
var privateKeyString string
503+
privateKeyString, err = WifToPrivateKeyString(wifKeyString)
504+
require.NoError(t, err)
505+
require.NotNil(t, privateKeyString)
506+
t.Log("Private Key:", privateKeyString)
507+
require.Equalf(t, 64, len(privateKeyString), "Private Key should be 64 characters long, got: %d", len(privateKeyString))
508+
509+
// Compare Private Keys
510+
require.Equalf(t, privateKey, privateKeyString, "Private Key should be equal, got: %s", privateKeyString)
511+
512+
// Decode WIF
513+
var decodedWif *wif.WIF
514+
decodedWif, err = WifFromString(wifKeyString)
515+
require.NoError(t, err)
516+
require.NotNil(t, decodedWif)
517+
require.Equalf(t, wifKeyString, decodedWif.String(), "WIF should be equal, got: %s", decodedWif.String())
518+
})
519+
520+
t.Run("TestWifFromStringMissingWIF", func(t *testing.T) {
521+
t.Parallel()
522+
523+
_, err := WifFromString("")
524+
require.Error(t, err)
525+
require.Equal(t, ErrWifMissing, err)
526+
})
527+
528+
t.Run("TestWifFromStringInvalidWIF", func(t *testing.T) {
529+
t.Parallel()
530+
531+
_, err := WifFromString("invalid")
532+
require.Error(t, err)
533+
require.Equal(t, "malformed private key", err.Error())
534+
})
535+
}
536+
537+
// ExampleWifFromString example using WifFromString()
538+
func ExampleWifFromString() {
539+
// Create a Private Key
540+
privateKey, err := CreatePrivateKeyString()
541+
if err != nil {
542+
fmt.Println(err)
543+
return
544+
}
545+
fmt.Println("Private Key Generated Length:", len(privateKey))
546+
547+
// Create a WIF
548+
var wifKey *wif.WIF
549+
wifKey, err = PrivateKeyToWif(privateKey)
550+
if err != nil {
551+
fmt.Println(err)
552+
return
553+
}
554+
fmt.Println("WIF Key Generated Length:", len(wifKey.String()))
555+
556+
// Decode WIF
557+
var decodedWif *wif.WIF
558+
decodedWif, err = WifFromString(wifKey.String())
559+
if err != nil {
560+
fmt.Println(err)
561+
return
562+
}
563+
fmt.Println("WIF Key Decoded Length:", len(decodedWif.String()))
564+
// Output: Private Key Generated Length: 64
565+
// WIF Key Generated Length: 51
566+
// WIF Key Decoded Length: 51
567+
}
568+
569+
// BenchmarkWifFromString benchmarks the method WifFromString()
570+
func BenchmarkWifFromString(b *testing.B) {
571+
wifKey, _ := CreateWif()
572+
wifString := wifKey.String()
573+
for i := 0; i < b.N; i++ {
574+
_, _ = WifFromString(wifString)
575+
}
576+
}

0 commit comments

Comments
 (0)