@@ -64,8 +64,8 @@ func encodeAddress(hash160 []byte, netID byte) string {
64
64
return base58 .CheckEncode (hash160 [:ripemd160 .Size ], netID )
65
65
}
66
66
67
- // encodeSegWitAddress creates a bech32 encoded address string representation
68
- // from witness version and witness program.
67
+ // encodeSegWitAddress creates a bech32 (or bech32m for SegWit v1) encoded
68
+ // address string representation from witness version and witness program.
69
69
func encodeSegWitAddress (hrp string , witnessVersion byte , witnessProgram []byte ) (string , error ) {
70
70
// Group the address bytes into 5 bit groups, as this is what is used to
71
71
// encode each character in the address string.
@@ -79,7 +79,19 @@ func encodeSegWitAddress(hrp string, witnessVersion byte, witnessProgram []byte)
79
79
combined := make ([]byte , len (converted )+ 1 )
80
80
combined [0 ] = witnessVersion
81
81
copy (combined [1 :], converted )
82
- bech , err := bech32 .Encode (hrp , combined )
82
+
83
+ var bech string
84
+ switch witnessVersion {
85
+ case 0 :
86
+ bech , err = bech32 .Encode (hrp , combined )
87
+
88
+ case 1 :
89
+ bech , err = bech32 .EncodeM (hrp , combined )
90
+
91
+ default :
92
+ return "" , fmt .Errorf ("unsupported witness version %d" ,
93
+ witnessVersion )
94
+ }
83
95
if err != nil {
84
96
return "" , err
85
97
}
@@ -149,8 +161,9 @@ func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, error) {
149
161
}
150
162
151
163
// We currently only support P2WPKH and P2WSH, which is
152
- // witness version 0.
153
- if witnessVer != 0 {
164
+ // witness version 0 and P2TR which is witness version
165
+ // 1.
166
+ if witnessVer != 0 && witnessVer != 1 {
154
167
return nil , UnsupportedWitnessVerError (witnessVer )
155
168
}
156
169
@@ -161,6 +174,10 @@ func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, error) {
161
174
case 20 :
162
175
return newAddressWitnessPubKeyHash (hrp , witnessProg )
163
176
case 32 :
177
+ if witnessVer == 1 {
178
+ return newAddressTaproot (hrp , witnessProg )
179
+ }
180
+
164
181
return newAddressWitnessScriptHash (hrp , witnessProg )
165
182
default :
166
183
return nil , UnsupportedWitnessProgLenError (len (witnessProg ))
@@ -210,7 +227,7 @@ func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, error) {
210
227
// returns the witness version and witness program byte representation.
211
228
func decodeSegWitAddress (address string ) (byte , []byte , error ) {
212
229
// Decode the bech32 encoded address.
213
- _ , data , err := bech32 .Decode (address )
230
+ _ , data , bech32version , err := bech32 .DecodeGeneric (address )
214
231
if err != nil {
215
232
return 0 , nil , err
216
233
}
@@ -246,6 +263,18 @@ func decodeSegWitAddress(address string) (byte, []byte, error) {
246
263
"version 0: %v" , len (regrouped ))
247
264
}
248
265
266
+ // For witness version 0, the bech32 encoding must be used.
267
+ if version == 0 && bech32version != bech32 .Version0 {
268
+ return 0 , nil , fmt .Errorf ("invalid checksum expected bech32 " +
269
+ "encoding for address with witness version 0" )
270
+ }
271
+
272
+ // For witness version 1, the bech32m encoding must be used.
273
+ if version == 1 && bech32version != bech32 .VersionM {
274
+ return 0 , nil , fmt .Errorf ("invalid checksum expected bech32m " +
275
+ "encoding for address with witness version 1" )
276
+ }
277
+
249
278
return version , regrouped , nil
250
279
}
251
280
@@ -506,116 +535,135 @@ func (a *AddressPubKey) PubKey() *btcec.PublicKey {
506
535
return a .pubKey
507
536
}
508
537
509
- // AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
510
- // (P2WPKH) output. See BIP 173 for further details regarding native segregated
511
- // witness address encoding:
512
- // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
513
- type AddressWitnessPubKeyHash struct {
538
+ // AddressSegWit is the base address type for all SegWit addresses.
539
+ type AddressSegWit struct {
514
540
hrp string
515
541
witnessVersion byte
516
- witnessProgram [20 ]byte
517
- }
518
-
519
- // NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
520
- func NewAddressWitnessPubKeyHash (witnessProg []byte , net * chaincfg.Params ) (* AddressWitnessPubKeyHash , error ) {
521
- return newAddressWitnessPubKeyHash (net .Bech32HRPSegwit , witnessProg )
522
- }
523
-
524
- // newAddressWitnessPubKeyHash is an internal helper function to create an
525
- // AddressWitnessPubKeyHash with a known human-readable part, rather than
526
- // looking it up through its parameters.
527
- func newAddressWitnessPubKeyHash (hrp string , witnessProg []byte ) (* AddressWitnessPubKeyHash , error ) {
528
- // Check for valid program length for witness version 0, which is 20
529
- // for P2WPKH.
530
- if len (witnessProg ) != 20 {
531
- return nil , errors .New ("witness program must be 20 " +
532
- "bytes for p2wpkh" )
533
- }
534
-
535
- addr := & AddressWitnessPubKeyHash {
536
- hrp : strings .ToLower (hrp ),
537
- witnessVersion : 0x00 ,
538
- }
539
-
540
- copy (addr .witnessProgram [:], witnessProg )
541
-
542
- return addr , nil
542
+ witnessProgram []byte
543
543
}
544
544
545
- // EncodeAddress returns the bech32 string encoding of an
546
- // AddressWitnessPubKeyHash.
547
- // Part of the Address interface.
548
- func (a * AddressWitnessPubKeyHash ) EncodeAddress () string {
549
- str , err := encodeSegWitAddress (a .hrp , a .witnessVersion ,
550
- a .witnessProgram [:])
545
+ // EncodeAddress returns the bech32 (or bech32m for SegWit v1) string encoding
546
+ // of an AddressSegWit.
547
+ //
548
+ // NOTE: This method is part of the Address interface.
549
+ func (a * AddressSegWit ) EncodeAddress () string {
550
+ str , err := encodeSegWitAddress (
551
+ a .hrp , a .witnessVersion , a .witnessProgram [:],
552
+ )
551
553
if err != nil {
552
554
return ""
553
555
}
554
556
return str
555
557
}
556
558
557
559
// ScriptAddress returns the witness program for this address.
558
- // Part of the Address interface.
559
- func (a * AddressWitnessPubKeyHash ) ScriptAddress () []byte {
560
+ //
561
+ // NOTE: This method is part of the Address interface.
562
+ func (a * AddressSegWit ) ScriptAddress () []byte {
560
563
return a .witnessProgram [:]
561
564
}
562
565
563
- // IsForNet returns whether or not the AddressWitnessPubKeyHash is associated
564
- // with the passed bitcoin network.
565
- // Part of the Address interface.
566
- func (a * AddressWitnessPubKeyHash ) IsForNet (net * chaincfg.Params ) bool {
566
+ // IsForNet returns whether the AddressSegWit is associated with the passed
567
+ // bitcoin network.
568
+ //
569
+ // NOTE: This method is part of the Address interface.
570
+ func (a * AddressSegWit ) IsForNet (net * chaincfg.Params ) bool {
567
571
return a .hrp == net .Bech32HRPSegwit
568
572
}
569
573
570
574
// String returns a human-readable string for the AddressWitnessPubKeyHash.
571
575
// This is equivalent to calling EncodeAddress, but is provided so the type
572
576
// can be used as a fmt.Stringer.
573
- // Part of the Address interface.
574
- func (a * AddressWitnessPubKeyHash ) String () string {
577
+ //
578
+ // NOTE: This method is part of the Address interface.
579
+ func (a * AddressSegWit ) String () string {
575
580
return a .EncodeAddress ()
576
581
}
577
582
578
- // Hrp returns the human-readable part of the bech32 encoded
579
- // AddressWitnessPubKeyHash .
580
- func (a * AddressWitnessPubKeyHash ) Hrp () string {
583
+ // Hrp returns the human-readable part of the bech32 (or bech32m for SegWit v1)
584
+ // encoded AddressSegWit .
585
+ func (a * AddressSegWit ) Hrp () string {
581
586
return a .hrp
582
587
}
583
588
584
- // WitnessVersion returns the witness version of the AddressWitnessPubKeyHash .
585
- func (a * AddressWitnessPubKeyHash ) WitnessVersion () byte {
589
+ // WitnessVersion returns the witness version of the AddressSegWit .
590
+ func (a * AddressSegWit ) WitnessVersion () byte {
586
591
return a .witnessVersion
587
592
}
588
593
589
- // WitnessProgram returns the witness program of the AddressWitnessPubKeyHash .
590
- func (a * AddressWitnessPubKeyHash ) WitnessProgram () []byte {
594
+ // WitnessProgram returns the witness program of the AddressSegWit .
595
+ func (a * AddressSegWit ) WitnessProgram () []byte {
591
596
return a .witnessProgram [:]
592
597
}
593
598
599
+ // AddressWitnessPubKeyHash is an Address for a pay-to-witness-pubkey-hash
600
+ // (P2WPKH) output. See BIP 173 for further details regarding native segregated
601
+ // witness address encoding:
602
+ // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
603
+ type AddressWitnessPubKeyHash struct {
604
+ AddressSegWit
605
+ }
606
+
607
+ // NewAddressWitnessPubKeyHash returns a new AddressWitnessPubKeyHash.
608
+ func NewAddressWitnessPubKeyHash (witnessProg []byte ,
609
+ net * chaincfg.Params ) (* AddressWitnessPubKeyHash , error ) {
610
+
611
+ return newAddressWitnessPubKeyHash (net .Bech32HRPSegwit , witnessProg )
612
+ }
613
+
614
+ // newAddressWitnessPubKeyHash is an internal helper function to create an
615
+ // AddressWitnessPubKeyHash with a known human-readable part, rather than
616
+ // looking it up through its parameters.
617
+ func newAddressWitnessPubKeyHash (hrp string ,
618
+ witnessProg []byte ) (* AddressWitnessPubKeyHash , error ) {
619
+
620
+ // Check for valid program length for witness version 0, which is 20
621
+ // for P2WPKH.
622
+ if len (witnessProg ) != 20 {
623
+ return nil , errors .New ("witness program must be 20 " +
624
+ "bytes for p2wpkh" )
625
+ }
626
+
627
+ addr := & AddressWitnessPubKeyHash {
628
+ AddressSegWit {
629
+ hrp : strings .ToLower (hrp ),
630
+ witnessVersion : 0x00 ,
631
+ witnessProgram : witnessProg ,
632
+ },
633
+ }
634
+
635
+ return addr , nil
636
+ }
637
+
594
638
// Hash160 returns the witness program of the AddressWitnessPubKeyHash as a
595
639
// byte array.
596
640
func (a * AddressWitnessPubKeyHash ) Hash160 () * [20 ]byte {
597
- return & a .witnessProgram
641
+ var pubKeyHashWitnessProgram [20 ]byte
642
+ copy (pubKeyHashWitnessProgram [:], a .witnessProgram )
643
+ return & pubKeyHashWitnessProgram
598
644
}
599
645
600
646
// AddressWitnessScriptHash is an Address for a pay-to-witness-script-hash
601
647
// (P2WSH) output. See BIP 173 for further details regarding native segregated
602
648
// witness address encoding:
603
649
// https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
604
650
type AddressWitnessScriptHash struct {
605
- hrp string
606
- witnessVersion byte
607
- witnessProgram [32 ]byte
651
+ AddressSegWit
608
652
}
609
653
610
654
// NewAddressWitnessScriptHash returns a new AddressWitnessPubKeyHash.
611
- func NewAddressWitnessScriptHash (witnessProg []byte , net * chaincfg.Params ) (* AddressWitnessScriptHash , error ) {
655
+ func NewAddressWitnessScriptHash (witnessProg []byte ,
656
+ net * chaincfg.Params ) (* AddressWitnessScriptHash , error ) {
657
+
612
658
return newAddressWitnessScriptHash (net .Bech32HRPSegwit , witnessProg )
613
659
}
614
660
615
661
// newAddressWitnessScriptHash is an internal helper function to create an
616
662
// AddressWitnessScriptHash with a known human-readable part, rather than
617
663
// looking it up through its parameters.
618
- func newAddressWitnessScriptHash (hrp string , witnessProg []byte ) (* AddressWitnessScriptHash , error ) {
664
+ func newAddressWitnessScriptHash (hrp string ,
665
+ witnessProg []byte ) (* AddressWitnessScriptHash , error ) {
666
+
619
667
// Check for valid program length for witness version 0, which is 32
620
668
// for P2WSH.
621
669
if len (witnessProg ) != 32 {
@@ -624,60 +672,49 @@ func newAddressWitnessScriptHash(hrp string, witnessProg []byte) (*AddressWitnes
624
672
}
625
673
626
674
addr := & AddressWitnessScriptHash {
627
- hrp : strings .ToLower (hrp ),
628
- witnessVersion : 0x00 ,
675
+ AddressSegWit {
676
+ hrp : strings .ToLower (hrp ),
677
+ witnessVersion : 0x00 ,
678
+ witnessProgram : witnessProg ,
679
+ },
629
680
}
630
681
631
- copy (addr .witnessProgram [:], witnessProg )
632
-
633
682
return addr , nil
634
683
}
635
684
636
- // EncodeAddress returns the bech32 string encoding of an
637
- // AddressWitnessScriptHash.
638
- // Part of the Address interface.
639
- func (a * AddressWitnessScriptHash ) EncodeAddress () string {
640
- str , err := encodeSegWitAddress (a .hrp , a .witnessVersion ,
641
- a .witnessProgram [:])
642
- if err != nil {
643
- return ""
644
- }
645
- return str
685
+ // AddressTaproot is an Address for a pay-to-taproot (P2TR) output. See BIP 341
686
+ // for further details.
687
+ type AddressTaproot struct {
688
+ AddressSegWit
646
689
}
647
690
648
- // ScriptAddress returns the witness program for this address.
649
- // Part of the Address interface.
650
- func (a * AddressWitnessScriptHash ) ScriptAddress () []byte {
651
- return a .witnessProgram [:]
652
- }
691
+ // NewAddressTaproot returns a new AddressTaproot.
692
+ func NewAddressTaproot (witnessProg []byte ,
693
+ net * chaincfg.Params ) (* AddressTaproot , error ) {
653
694
654
- // IsForNet returns whether or not the AddressWitnessScriptHash is associated
655
- // with the passed bitcoin network.
656
- // Part of the Address interface.
657
- func (a * AddressWitnessScriptHash ) IsForNet (net * chaincfg.Params ) bool {
658
- return a .hrp == net .Bech32HRPSegwit
695
+ return newAddressTaproot (net .Bech32HRPSegwit , witnessProg )
659
696
}
660
697
661
- // String returns a human-readable string for the AddressWitnessScriptHash.
662
- // This is equivalent to calling EncodeAddress, but is provided so the type
663
- // can be used as a fmt.Stringer.
664
- // Part of the Address interface.
665
- func (a * AddressWitnessScriptHash ) String () string {
666
- return a .EncodeAddress ()
667
- }
698
+ // newAddressWitnessScriptHash is an internal helper function to create an
699
+ // AddressWitnessScriptHash with a known human-readable part, rather than
700
+ // looking it up through its parameters.
701
+ func newAddressTaproot (hrp string ,
702
+ witnessProg []byte ) (* AddressTaproot , error ) {
668
703
669
- // Hrp returns the human-readable part of the bech32 encoded
670
- // AddressWitnessScriptHash.
671
- func (a * AddressWitnessScriptHash ) Hrp () string {
672
- return a .hrp
673
- }
704
+ // Check for valid program length for witness version 1, which is 32
705
+ // for P2TR.
706
+ if len (witnessProg ) != 32 {
707
+ return nil , errors .New ("witness program must be 32 bytes for " +
708
+ "p2tr" )
709
+ }
674
710
675
- // WitnessVersion returns the witness version of the AddressWitnessScriptHash.
676
- func (a * AddressWitnessScriptHash ) WitnessVersion () byte {
677
- return a .witnessVersion
678
- }
711
+ addr := & AddressTaproot {
712
+ AddressSegWit {
713
+ hrp : strings .ToLower (hrp ),
714
+ witnessVersion : 0x01 ,
715
+ witnessProgram : witnessProg ,
716
+ },
717
+ }
679
718
680
- // WitnessProgram returns the witness program of the AddressWitnessScriptHash.
681
- func (a * AddressWitnessScriptHash ) WitnessProgram () []byte {
682
- return a .witnessProgram [:]
719
+ return addr , nil
683
720
}
0 commit comments