@@ -60,6 +60,8 @@ pub enum Error {
60
60
Bech32 ( bech32:: Error ) ,
61
61
/// The bech32 payload was empty
62
62
EmptyBech32Payload ,
63
+ /// The wrong checksum algorithm was used. See BIP-0350.
64
+ InvalidBech32Variant ,
63
65
/// Script version must be 0 to 16 inclusive
64
66
InvalidWitnessVersion ( u8 ) ,
65
67
/// Unable to parse witness version from string
@@ -82,6 +84,7 @@ impl fmt::Display for Error {
82
84
Error :: Base58 ( ref e) => write ! ( f, "base58: {}" , e) ,
83
85
Error :: Bech32 ( ref e) => write ! ( f, "bech32: {}" , e) ,
84
86
Error :: EmptyBech32Payload => write ! ( f, "the bech32 payload was empty" ) ,
87
+ Error :: InvalidBech32Variant => write ! ( f, "invalid bech32 checksum variant" ) ,
85
88
Error :: InvalidWitnessVersion ( v) => write ! ( f, "invalid witness script version: {}" , v) ,
86
89
Error :: UnparsableWitnessVersion ( ref e) => write ! ( f, "Incorrect format of a witness version byte: {}" , e) ,
87
90
Error :: MalformedWitnessVersion => f. write_str ( "bitcoin script opcode does not match any known witness version, the script is malformed" ) ,
@@ -319,6 +322,14 @@ impl WitnessVersion {
319
322
pub fn into_num ( self ) -> u8 {
320
323
self as u8
321
324
}
325
+
326
+ /// Determine the checksum variant. See BIP-0350 for specification.
327
+ pub fn bech32_variant ( & self ) -> bech32:: Variant {
328
+ match self {
329
+ WitnessVersion :: V0 => bech32:: Variant :: Bech32 ,
330
+ _ => bech32:: Variant :: Bech32m ,
331
+ }
332
+ }
322
333
}
323
334
324
335
impl From < WitnessVersion > for :: bech32:: u5 {
@@ -634,15 +645,14 @@ impl fmt::Display for Address {
634
645
Network :: Testnet | Network :: Signet => "tb" ,
635
646
Network :: Regtest => "bcrt" ,
636
647
} ;
637
- let bech_ver = if version. into_num ( ) > 0 { bech32:: Variant :: Bech32m } else { bech32:: Variant :: Bech32 } ;
638
648
let mut upper_writer;
639
649
let writer = if fmt. alternate ( ) {
640
650
upper_writer = UpperWriter ( fmt) ;
641
651
& mut upper_writer as & mut dyn fmt:: Write
642
652
} else {
643
653
fmt as & mut dyn fmt:: Write
644
654
} ;
645
- let mut bech32_writer = bech32:: Bech32Writer :: new ( hrp, bech_ver , writer) ?;
655
+ let mut bech32_writer = bech32:: Bech32Writer :: new ( hrp, version . bech32_variant ( ) , writer) ?;
646
656
bech32:: WriteBase32 :: write_u5 ( & mut bech32_writer, version. into ( ) ) ?;
647
657
bech32:: ToBase32 :: write_base32 ( & prog, & mut bech32_writer)
648
658
}
@@ -705,10 +715,9 @@ impl FromStr for Address {
705
715
return Err ( Error :: InvalidSegwitV0ProgramLength ( program. len ( ) ) ) ;
706
716
}
707
717
708
- // Bech32 encoding check
709
- if ( version. into_num ( ) > 0 && variant != bech32:: Variant :: Bech32m ) ||
710
- ( version. into_num ( ) == 0 && variant != bech32:: Variant :: Bech32 ) {
711
- return Err ( Error :: InvalidWitnessVersion ( version. into_num ( ) ) )
718
+ // Encoding check
719
+ if version. bech32_variant ( ) != variant {
720
+ return Err ( Error :: InvalidBech32Variant ) ;
712
721
}
713
722
714
723
return Ok ( Address {
0 commit comments