Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ab50d3d

Browse files
author
shadowy-pycoder
committed
Added creation of taproot addresses
1 parent f228c51 commit ab50d3d

File tree

2 files changed

+63
-15
lines changed

2 files changed

+63
-15
lines changed

‎bmt/main.go‎

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ func (k *PrivateKey) ToWif(uncompressed bool) (*string, error) {
622622
//
623623
// If both parameters are nil generates a random wallet
624624
func CreateNewWallet(raw *big.Int, wif *string) (*Wallet, error) {
625-
var nestedAddress, nativeAddress string
625+
var nestedAddress, nativeAddress, taprootAddress string
626626
privKey, err := NewPrivateKey(raw, wif)
627627
if err != nil {
628628
return nil, err
@@ -636,13 +636,15 @@ func CreateNewWallet(raw *big.Int, wif *string) (*Wallet, error) {
636636
if !privKey.Uncompressed {
637637
nestedAddress = createNestedSegwit(pubKey)
638638
nativeAddress = createNativeSegwit(pubKey)
639+
taprootAddress = createTaproot(createTweakedPubKey(rawPubKey))
639640
}
640641
return &Wallet{PrivKey: privKey,
641642
RawPubKey: rawPubKey,
642643
PubKey: hex.EncodeToString(pubKey),
643644
Legacy: legacyAddress,
644645
Nested: nestedAddress,
645-
Native: nativeAddress}, nil
646+
Native: nativeAddress,
647+
Taproot: taprootAddress}, nil
646648
}
647649

648650
type Wallet struct {
@@ -652,6 +654,7 @@ type Wallet struct {
652654
Legacy string
653655
Nested string
654656
Native string
657+
Taproot string
655658
}
656659

657660
// String returns a formatted string representation of the Wallet.
@@ -670,7 +673,8 @@ Public Key (HEX Compressed): %s
670673
Legacy Address: %s
671674
Nested SegWit Address: %s
672675
Native SegWit Address: %s
673-
`, w.PrivKey.Raw, *w.PrivKey.Wif, w.RawPubKey, w.PubKey, w.Legacy, w.Nested, w.Native)
676+
Taproot Address: %s
677+
`, w.PrivKey.Raw, *w.PrivKey.Wif, w.RawPubKey, w.PubKey, w.Legacy, w.Nested, w.Native, w.Taproot)
674678
}
675679

676680
// NewInt converts a hexadecimal string to a big.Int pointer.
@@ -832,6 +836,32 @@ func createPubKey(rawPubKey *Point, uncompressed bool) []byte {
832836
return buf[:33]
833837
}
834838

839+
func calculateTweak(rawPubKey *Point) *big.Int {
840+
var tweak big.Int
841+
buf := make([]byte, 32)
842+
h1 := sha256.New()
843+
h2 := sha256.New()
844+
h1.Write([]byte("TapTweak"))
845+
h2.Write(joinBytes([][]byte{h1.Sum(nil), h1.Sum(nil), rawPubKey.X.FillBytes(buf)}...))
846+
tweak.SetBytes(h2.Sum(nil))
847+
return &tweak
848+
}
849+
850+
func createTweakedPubKey(rawPubKey *Point) []byte {
851+
var q JacobianPoint
852+
tweak := calculateTweak(rawPubKey)
853+
p := &Point{X: new(big.Int).Set(rawPubKey.X), Y: new(big.Int).Set(rawPubKey.Y)}
854+
if IsOdd(p.Y) {
855+
p.Y.Sub(Secp256k1.PCurve, p.Y)
856+
}
857+
q.Add(p.ToJacobian(), q.Mul(tweak, nil))
858+
qa := q.ToAffine()
859+
if IsOdd(qa.Y) {
860+
qa.Y.Sub(Secp256k1.PCurve, qa.Y)
861+
}
862+
return createPubKey(qa, false)[1:]
863+
}
864+
835865
// checkSum calculates the checksum of the input byte slice using DoubleSHA256 and returns the first 4 bytes.
836866
//
837867
// Parameters:
@@ -893,6 +923,21 @@ func createNativeSegwit(pubKey []byte) string {
893923
return addr
894924
}
895925

926+
func createTaproot(pubKey []byte) string {
927+
converted, err := bech32.ConvertBits(pubKey, 8, 5, true)
928+
if err != nil {
929+
panic(err)
930+
}
931+
combined := make([]byte, len(converted)+1)
932+
combined[0] = byte(1)
933+
copy(combined[1:], converted)
934+
addr, err := bech32.EncodeM("bc", combined)
935+
if err != nil {
936+
panic(err)
937+
}
938+
return addr
939+
}
940+
896941
// varInt generates a variable-length integer in bytes based on the input length.
897942
//
898943
// Parameters:

‎bmt/main_test.go‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@ func TestCreateNewWalletFromRawPrivateKey(t *testing.T) {
7979
X: NewInt("e4ab48ce61667f57bb9ca0f31b9bca94981303004d3802b1c11faa9343a820ba"),
8080
Y: NewInt("17d5acd0ade3141bdccab4689a82151e638a70a56c1b4d38788e77c76e414dd3"),
8181
},
82-
PubKey: "03e4ab48ce61667f57bb9ca0f31b9bca94981303004d3802b1c11faa9343a820ba",
83-
Legacy: "1LBdJkrB4nkWkLLdKSBAD2CPRrpSaYQW51",
84-
Nested: "39RBCbgESnqjHpapfvqVPfLCPGrvGKxpbC",
85-
Native: "bc1q6fkdkwv5p6mxdhyj2gxhgu2tp5np53g6g8u0t0",
82+
PubKey: "03e4ab48ce61667f57bb9ca0f31b9bca94981303004d3802b1c11faa9343a820ba",
83+
Legacy: "1LBdJkrB4nkWkLLdKSBAD2CPRrpSaYQW51",
84+
Nested: "39RBCbgESnqjHpapfvqVPfLCPGrvGKxpbC",
85+
Native: "bc1q6fkdkwv5p6mxdhyj2gxhgu2tp5np53g6g8u0t0",
86+
Taproot: "bc1puzp40apyn38h3nqhzzxk6tmxxwvd0jcegnk4k88qvxntstsfhyvq5nr3us",
8687
},
8788
},
8889
{
@@ -97,10 +98,11 @@ func TestCreateNewWalletFromRawPrivateKey(t *testing.T) {
9798
X: NewInt("e483d1df60d0c9e16035672dfb92d7ddac6858b5233d33bb04996ae6a23f0149"),
9899
Y: NewInt("d0fb3cafc082957fdd8934a9fa2b5fbf2fee701ca595da7bb79a95f0063a13c5"),
99100
},
100-
PubKey: "03e483d1df60d0c9e16035672dfb92d7ddac6858b5233d33bb04996ae6a23f0149",
101-
Legacy: "13KXYTfq5FRQj6T3t6ds6FYqCDymYMwdmC",
102-
Nested: "34GeUW8iPUkWdfQSWFvumAt5RGtxhp3KCG",
103-
Native: "bc1qr9cncqd8v5j9uv86pfprqlkuh7htp5uwu6x56m",
101+
PubKey: "03e483d1df60d0c9e16035672dfb92d7ddac6858b5233d33bb04996ae6a23f0149",
102+
Legacy: "13KXYTfq5FRQj6T3t6ds6FYqCDymYMwdmC",
103+
Nested: "34GeUW8iPUkWdfQSWFvumAt5RGtxhp3KCG",
104+
Native: "bc1qr9cncqd8v5j9uv86pfprqlkuh7htp5uwu6x56m",
105+
Taproot: "bc1ph4zg3xz7z0kvmdp9nne6kpyc8yk9rsweepa3g5se40zkqa7rvwvslkl8fd",
104106
},
105107
},
106108
}
@@ -140,10 +142,11 @@ func TestCreateNewWalletFromWifPrivateKey(t *testing.T) {
140142
X: NewInt("66fde8efb47bfe53be63cccd068996f3a1c9172f1c2f6bc345dff6c589daefc5"),
141143
Y: NewInt("379ab4aa30d3247cb6b7c327067bd8199ff7bec32205ef043d3c9239ec6765b7"),
142144
},
143-
PubKey: "0366fde8efb47bfe53be63cccd068996f3a1c9172f1c2f6bc345dff6c589daefc5",
144-
Legacy: "14VXJudstcvqpx56BPQFSYJ1K39KGc3twM",
145-
Nested: "32vwEU1Esvp1AywrYgrnziHCaigLTn5AKN",
146-
Native: "bc1qyex4xghj4rldkysse2hdpt0arphh78xhp28ze2",
145+
PubKey: "0366fde8efb47bfe53be63cccd068996f3a1c9172f1c2f6bc345dff6c589daefc5",
146+
Legacy: "14VXJudstcvqpx56BPQFSYJ1K39KGc3twM",
147+
Nested: "32vwEU1Esvp1AywrYgrnziHCaigLTn5AKN",
148+
Native: "bc1qyex4xghj4rldkysse2hdpt0arphh78xhp28ze2",
149+
Taproot: "bc1pss2mar9sv2nktnx8ujqrjd9ld7n0zn9swl7zup5pcl8shq9es4kqlgx6g3",
147150
},
148151
},
149152
{

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /