elements/
address.rs

1// Rust Elements Library
2// Written by
3//   The Elements developers
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! # Addresses
16//!
17
18use std::convert::TryFrom as _;
19use std::error;
20use std::fmt;
21use std::fmt::Write as _;
22use std::str::FromStr;
23
24use bech32::{Bech32, Bech32m, ByteIterExt, Fe32, Fe32IterExt, Hrp};
25use crate::blech32::{Blech32, Blech32m};
26use crate::hashes::Hash;
27use bitcoin::base58;
28use bitcoin::PublicKey;
29use secp256k1_zkp;
30use secp256k1_zkp::Secp256k1;
31use secp256k1_zkp::Verification;
32#[cfg(feature = "serde")]
33use serde;
34
35use crate::schnorr::{TapTweak, TweakedPublicKey, UntweakedPublicKey};
36use crate::taproot::TapNodeHash;
37
38use crate::{opcodes, script};
39use crate::{PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash};
40
41/// Encoding error
42#[derive(Debug, PartialEq)]
43pub enum AddressError {
44    /// Base58 encoding error
45    Base58(base58::Error),
46    /// Bech32 encoding error
47    Bech32(bech32::primitives::decode::SegwitHrpstringError),
48    /// Blech32 encoding error
49    Blech32(crate::blech32::decode::SegwitHrpstringError),
50    /// Was unable to parse the address.
51    InvalidAddress(String),
52    /// Script version must be 0 to 16 inclusive
53    InvalidWitnessVersion(u8),
54    /// The witness program must be between 2 and 40 bytes in length.
55    InvalidWitnessProgramLength(usize),
56    /// A v0 witness program must be either of length 20 or 32.
57    InvalidSegwitV0ProgramLength(usize),
58    /// A v1+ witness program must use b(l)ech32m not b(l)ech32
59    InvalidWitnessEncoding,
60    /// A v0 witness program must use b(l)ech32 not b(l)ech32m
61    InvalidSegwitV0Encoding,
62
63    /// An invalid blinding pubkey was encountered.
64    InvalidBlindingPubKey(secp256k1_zkp::UpstreamError),
65
66    /// The length (in bytes) of the object was not correct.
67    InvalidLength(usize),
68
69    /// Address version byte were not recognized.
70    InvalidAddressVersion(u8),
71}
72
73impl From<bech32::primitives::decode::SegwitHrpstringError> for AddressError {
74    fn from(e: bech32::primitives::decode::SegwitHrpstringError) -> Self {
75        AddressError::Bech32(e)
76    }
77}
78
79impl From<crate::blech32::decode::SegwitHrpstringError> for AddressError {
80    fn from(e: crate::blech32::decode::SegwitHrpstringError) -> Self {
81        AddressError::Blech32(e)
82    }
83}
84
85impl fmt::Display for AddressError {
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        match *self {
88            AddressError::Base58(ref e) => write!(f, "base58 error: {}", e),
89            AddressError::Bech32(ref e) => write!(f, "bech32 error: {}", e),
90            AddressError::Blech32(ref e) => write!(f, "blech32 error: {}", e),
91            AddressError::InvalidAddress(ref a) => {
92                write!(f, "was unable to parse the address: {}", a)
93            }
94            AddressError::InvalidWitnessVersion(ref wver) => {
95                write!(f, "invalid witness script version: {}", wver)
96            }
97            AddressError::InvalidWitnessProgramLength(ref len) => {
98                write!(
99                    f,
100                    "the witness program must be between 2 and 40 bytes in length, not {}",
101                    len
102                )
103            }
104            AddressError::InvalidSegwitV0ProgramLength(ref len) => {
105                write!(
106                    f,
107                    "a v0 witness program must be length 20 or 32, not {}",
108                    len
109                )
110            }
111            AddressError::InvalidBlindingPubKey(ref e) => {
112                write!(f, "an invalid blinding pubkey was encountered: {}", e)
113            }
114            AddressError::InvalidWitnessEncoding => {
115                write!(f, "v1+ witness program must use b(l)ech32m not b(l)ech32")
116            }
117            AddressError::InvalidSegwitV0Encoding => {
118                write!(f, "v0 witness program must use b(l)ech32 not b(l)ech32m")
119            }
120            AddressError::InvalidLength(len) => {
121                write!(f, "Address data has invalid length {}", len)
122            }
123            AddressError::InvalidAddressVersion(v) => {
124                write!(f, "address version {} is invalid for this type", v)
125            }
126        }
127    }
128}
129
130impl error::Error for AddressError {
131    fn cause(&self) -> Option<&dyn error::Error> {
132        match *self {
133            AddressError::Base58(ref e) => Some(e),
134            AddressError::Bech32(ref e) => Some(e),
135            AddressError::Blech32(ref e) => Some(e),
136            AddressError::InvalidBlindingPubKey(ref e) => Some(e),
137            _ => None,
138        }
139    }
140}
141
142#[doc(hidden)]
143impl From<base58::Error> for AddressError {
144    fn from(e: base58::Error) -> AddressError {
145        AddressError::Base58(e)
146    }
147}
148
149/// The parameters to derive addresses.
150#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
151pub struct AddressParams {
152    /// The base58 prefix for p2pkh addresses.
153    pub p2pkh_prefix: u8,
154    /// The base58 prefix for p2sh addresses.
155    pub p2sh_prefix: u8,
156    /// The base58 prefix for blinded addresses.
157    pub blinded_prefix: u8,
158    /// The bech32 HRP for unblinded segwit addresses.
159    pub bech_hrp: Hrp,
160    /// The bech32 HRP for blinded segwit addresses.
161    pub blech_hrp: Hrp,
162}
163
164impl AddressParams {
165    /// The Liquid network address parameters.
166    pub const LIQUID: AddressParams = AddressParams {
167        p2pkh_prefix: 57,
168        p2sh_prefix: 39,
169        blinded_prefix: 12,
170        bech_hrp: Hrp::parse_unchecked("ex"),
171        blech_hrp: Hrp::parse_unchecked("lq"),
172    };
173
174    /// The default Elements network address parameters.
175    pub const ELEMENTS: AddressParams = AddressParams {
176        p2pkh_prefix: 235,
177        p2sh_prefix: 75,
178        blinded_prefix: 4,
179        bech_hrp: Hrp::parse_unchecked("ert"),
180        blech_hrp: Hrp::parse_unchecked("el"),
181    };
182
183    /// The default liquid testnet network address parameters.
184    pub const LIQUID_TESTNET: AddressParams = AddressParams {
185        p2pkh_prefix: 36,
186        p2sh_prefix: 19,
187        blinded_prefix: 23,
188        bech_hrp: Hrp::parse_unchecked("tex"),
189        blech_hrp: Hrp::parse_unchecked("tlq"),
190    };
191}
192
193/// The method used to produce an address
194#[derive(Debug, Clone, PartialEq, Eq, Hash)]
195pub enum Payload {
196    /// pay-to-pkhash address
197    PubkeyHash(PubkeyHash),
198    /// P2SH address
199    ScriptHash(ScriptHash),
200    /// Segwit address
201    WitnessProgram {
202        /// The segwit version.
203        version: Fe32,
204        /// The segwit program.
205        program: Vec<u8>,
206    },
207}
208
209/// An Elements address.
210#[derive(Clone, PartialEq, Eq, Hash)]
211pub struct Address {
212    /// the network
213    pub params: &'static AddressParams,
214    /// the traditional non-confidential payload
215    pub payload: Payload,
216    /// the blinding pubkey
217    pub blinding_pubkey: Option<secp256k1_zkp::PublicKey>,
218}
219
220impl Address {
221    /// Inspect if the address is a blinded address.
222    pub fn is_blinded(&self) -> bool {
223        self.blinding_pubkey.is_some()
224    }
225
226    /// Return if the address is for the Liquid network
227    pub fn is_liquid(&self) -> bool {
228        self.params == &AddressParams::LIQUID
229    }
230
231    /// Creates a pay to (compressed) public key hash address from a public key
232    /// This is the preferred non-witness type address
233    #[inline]
234    pub fn p2pkh(
235        pk: &PublicKey,
236        blinder: Option<secp256k1_zkp::PublicKey>,
237        params: &'static AddressParams,
238    ) -> Address {
239        let mut hash_engine = PubkeyHash::engine();
240        pk.write_into(&mut hash_engine)
241            .expect("engines don't error");
242
243        Address {
244            params,
245            payload: Payload::PubkeyHash(PubkeyHash::from_engine(hash_engine)),
246            blinding_pubkey: blinder,
247        }
248    }
249
250    /// Creates a pay to script hash P2SH address from a script
251    /// This address type was introduced with BIP16 and is the popular type to implement multi-sig these days.
252    #[inline]
253    pub fn p2sh(
254        script: &script::Script,
255        blinder: Option<secp256k1_zkp::PublicKey>,
256        params: &'static AddressParams,
257    ) -> Address {
258        Address {
259            params,
260            payload: Payload::ScriptHash(ScriptHash::hash(&script[..])),
261            blinding_pubkey: blinder,
262        }
263    }
264
265    /// Create a witness pay to public key address from a public key
266    /// This is the native segwit address type for an output redeemable with a single signature
267    pub fn p2wpkh(
268        pk: &PublicKey,
269        blinder: Option<secp256k1_zkp::PublicKey>,
270        params: &'static AddressParams,
271    ) -> Address {
272        let mut hash_engine = WPubkeyHash::engine();
273        pk.write_into(&mut hash_engine)
274            .expect("engines don't error");
275
276        Address {
277            params,
278            payload: Payload::WitnessProgram {
279                version: Fe32::Q,
280                program: WPubkeyHash::from_engine(hash_engine)[..].to_vec(),
281            },
282            blinding_pubkey: blinder,
283        }
284    }
285
286    /// Create a pay to script address that embeds a witness pay to public key
287    /// This is a segwit address type that looks familiar (as p2sh) to legacy clients
288    pub fn p2shwpkh(
289        pk: &PublicKey,
290        blinder: Option<secp256k1_zkp::PublicKey>,
291        params: &'static AddressParams,
292    ) -> Address {
293        let mut hash_engine = ScriptHash::engine();
294        pk.write_into(&mut hash_engine)
295            .expect("engines don't error");
296
297        let builder = script::Builder::new()
298            .push_int(0)
299            .push_slice(&ScriptHash::from_engine(hash_engine)[..]);
300
301        Address {
302            params,
303            payload: Payload::ScriptHash(ScriptHash::hash(builder.into_script().as_bytes())),
304            blinding_pubkey: blinder,
305        }
306    }
307
308    /// Create a witness pay to script hash address
309    pub fn p2wsh(
310        script: &script::Script,
311        blinder: Option<secp256k1_zkp::PublicKey>,
312        params: &'static AddressParams,
313    ) -> Address {
314        Address {
315            params,
316            payload: Payload::WitnessProgram {
317                version: Fe32::Q,
318                program: WScriptHash::hash(&script[..])[..].to_vec(),
319            },
320            blinding_pubkey: blinder,
321        }
322    }
323
324    /// Create a pay to script address that embeds a witness pay to script hash address
325    /// This is a segwit address type that looks familiar (as p2sh) to legacy clients
326    pub fn p2shwsh(
327        script: &script::Script,
328        blinder: Option<secp256k1_zkp::PublicKey>,
329        params: &'static AddressParams,
330    ) -> Address {
331        let ws = script::Builder::new()
332            .push_int(0)
333            .push_slice(&WScriptHash::hash(&script[..])[..])
334            .into_script();
335
336        Address {
337            params,
338            payload: Payload::ScriptHash(ScriptHash::hash(&ws[..])),
339            blinding_pubkey: blinder,
340        }
341    }
342
343    /// Creates a pay to taproot address from an untweaked key.
344    pub fn p2tr<C: Verification>(
345        secp: &Secp256k1<C>,
346        internal_key: UntweakedPublicKey,
347        merkle_root: Option<TapNodeHash>,
348        blinder: Option<secp256k1_zkp::PublicKey>,
349        params: &'static AddressParams,
350    ) -> Address {
351        Address {
352            params,
353            payload: {
354                let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
355                Payload::WitnessProgram {
356                    version: Fe32::P,
357                    program: output_key.into_inner().serialize().to_vec(),
358                }
359            },
360            blinding_pubkey: blinder,
361        }
362    }
363
364    /// Creates a pay to taproot address from a pre-tweaked output key.
365    ///
366    /// This method is not recommended for use, [`Address::p2tr()`] should be used where possible.
367    pub fn p2tr_tweaked(
368        output_key: TweakedPublicKey,
369        blinder: Option<secp256k1_zkp::PublicKey>,
370        params: &'static AddressParams,
371    ) -> Address {
372        Address {
373            params,
374            payload: Payload::WitnessProgram {
375                version: Fe32::P,
376                program: output_key.into_inner().serialize().to_vec(),
377            },
378            blinding_pubkey: blinder,
379        }
380    }
381
382    /// Get an [Address] from an output script.
383    pub fn from_script(
384        script: &script::Script,
385        blinder: Option<secp256k1_zkp::PublicKey>,
386        params: &'static AddressParams,
387    ) -> Option<Address> {
388        Some(Address {
389            payload: if script.is_p2pkh() {
390                Payload::PubkeyHash(Hash::from_slice(&script.as_bytes()[3..23]).unwrap())
391            } else if script.is_p2sh() {
392                Payload::ScriptHash(Hash::from_slice(&script.as_bytes()[2..22]).unwrap())
393            } else if script.is_v0_p2wpkh() {
394                Payload::WitnessProgram {
395                    version: Fe32::Q,
396                    program: script.as_bytes()[2..22].to_vec(),
397                }
398            } else if script.is_v0_p2wsh() {
399                Payload::WitnessProgram {
400                    version: Fe32::Q,
401                    program: script.as_bytes()[2..34].to_vec(),
402                }
403            } else if script.is_v1plus_p2witprog() {
404                Payload::WitnessProgram {
405                    version: Fe32::try_from(script.as_bytes()[0] - 0x50).expect("0<32"),
406                    program: script.as_bytes()[2..].to_vec(),
407                }
408            } else {
409                return None;
410            },
411            blinding_pubkey: blinder,
412            params,
413        })
414    }
415
416    /// Generates a script pubkey spending to this address
417    pub fn script_pubkey(&self) -> script::Script {
418        match self.payload {
419            Payload::PubkeyHash(ref hash) => script::Builder::new()
420                .push_opcode(opcodes::all::OP_DUP)
421                .push_opcode(opcodes::all::OP_HASH160)
422                .push_slice(&hash[..])
423                .push_opcode(opcodes::all::OP_EQUALVERIFY)
424                .push_opcode(opcodes::all::OP_CHECKSIG),
425            Payload::ScriptHash(ref hash) => script::Builder::new()
426                .push_opcode(opcodes::all::OP_HASH160)
427                .push_slice(&hash[..])
428                .push_opcode(opcodes::all::OP_EQUAL),
429            Payload::WitnessProgram {
430                version: witver,
431                program: ref witprog,
432            } => script::Builder::new()
433                .push_int(i64::from(witver.to_u8()))
434                .push_slice(witprog),
435        }
436        .into_script()
437    }
438
439    /// Convert this address to an unconfidential address.
440    #[must_use]
441    pub fn to_unconfidential(&self) -> Address {
442        Address {
443            params: self.params,
444            payload: self.payload.clone(),
445            blinding_pubkey: None,
446        }
447    }
448
449    /// Convert this address to a confidential address with the given blinding pubkey.
450    #[must_use]
451    pub fn to_confidential(&self, blinding_pubkey: secp256k1_zkp::PublicKey) -> Address {
452        Address {
453            params: self.params,
454            payload: self.payload.clone(),
455            blinding_pubkey: Some(blinding_pubkey),
456        }
457    }
458
459    fn from_bech32(
460        s: &str,
461        blinded: bool,
462        params: &'static AddressParams,
463    ) -> Result<Address, AddressError> {
464        let (version, data): (Fe32, Vec<u8>) = if blinded {
465            let hs = crate::blech32::decode::SegwitHrpstring::new(s)?;
466            (hs.witness_version(), hs.byte_iter().collect())
467        } else {
468            let hs = bech32::primitives::decode::SegwitHrpstring::new(s)?;
469            (hs.witness_version(), hs.byte_iter().collect())
470        };
471
472        let (blinding_pubkey, program) = match blinded {
473            true => (
474                Some(
475                    secp256k1_zkp::PublicKey::from_slice(&data[..33])
476                        .map_err(AddressError::InvalidBlindingPubKey)?,
477                ),
478                data[33..].to_vec(),
479            ),
480            false => (None, data),
481        };
482
483        Ok(Address {
484            params,
485            payload: Payload::WitnessProgram { version, program },
486            blinding_pubkey,
487        })
488    }
489
490    // data.len() should be >= 1 when this method is called
491    fn from_base58(data: &[u8], params: &'static AddressParams) -> Result<Address, AddressError> {
492        // When unblinded, the structure is:
493        // <1: regular prefix> <20: hash160>
494        // When blinded, the structure is:
495        // <1: blinding prefix> <1: regular prefix> <33: blinding pubkey> <20: hash160>
496
497        let blinded = data[0] == params.blinded_prefix;
498        let prefix = match (blinded, data.len()) {
499            (true, 55) => data[1],
500            (false, 21) => data[0],
501            (_, len) => return Err(AddressError::InvalidLength(len)),
502        };
503
504        let (blinding_pubkey, payload_data) = match blinded {
505            true => (
506                Some(
507                    secp256k1_zkp::PublicKey::from_slice(&data[2..35])
508                        .map_err(AddressError::InvalidBlindingPubKey)?,
509                ),
510                &data[35..],
511            ),
512            false => (None, &data[1..]),
513        };
514
515        let payload = if prefix == params.p2pkh_prefix {
516            Payload::PubkeyHash(PubkeyHash::from_slice(payload_data).unwrap())
517        } else if prefix == params.p2sh_prefix {
518            Payload::ScriptHash(ScriptHash::from_slice(payload_data).unwrap())
519        } else {
520            return Err(AddressError::InvalidAddressVersion(prefix));
521        };
522
523        Ok(Address {
524            params,
525            payload,
526            blinding_pubkey,
527        })
528    }
529
530    /// Parse the address using the given parameters.
531    /// When using the built-in parameters, you can use [`FromStr`].
532    pub fn parse_with_params(
533        s: &str,
534        params: &'static AddressParams,
535    ) -> Result<Address, AddressError> {
536        // Bech32.
537        let prefix = find_prefix(s);
538        let b32_ex = match_prefix(prefix, params.bech_hrp);
539        let b32_bl = match_prefix(prefix, params.blech_hrp);
540        if b32_ex || b32_bl {
541            return Address::from_bech32(s, b32_bl, params);
542        }
543
544        // Base58.
545        if s.len() > 150 {
546            return Err(AddressError::InvalidLength(s.len() * 11 / 15));
547        }
548        let data = base58::decode_check(s)?;
549        Address::from_base58(&data, params)
550    }
551}
552
553impl fmt::Display for Address {
554    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
555        match self.payload {
556            Payload::PubkeyHash(ref hash) => {
557                if let Some(ref blinder) = self.blinding_pubkey {
558                    let mut prefixed = [0; 55]; // 1 + 1 + 33 + 20
559                    prefixed[0] = self.params.blinded_prefix;
560                    prefixed[1] = self.params.p2pkh_prefix;
561                    prefixed[2..35].copy_from_slice(&blinder.serialize());
562                    prefixed[35..].copy_from_slice(&hash[..]);
563                    base58::encode_check_to_fmt(fmt, &prefixed[..])
564                } else {
565                    let mut prefixed = [0; 21];
566                    prefixed[0] = self.params.p2pkh_prefix;
567                    prefixed[1..].copy_from_slice(&hash[..]);
568                    base58::encode_check_to_fmt(fmt, &prefixed[..])
569                }
570            }
571            Payload::ScriptHash(ref hash) => {
572                if let Some(ref blinder) = self.blinding_pubkey {
573                    let mut prefixed = [0; 55]; // 1 + 1 + 33 + 20
574                    prefixed[0] = self.params.blinded_prefix;
575                    prefixed[1] = self.params.p2sh_prefix;
576                    prefixed[2..35].copy_from_slice(&blinder.serialize());
577                    prefixed[35..].copy_from_slice(&hash[..]);
578                    base58::encode_check_to_fmt(fmt, &prefixed[..])
579                } else {
580                    let mut prefixed = [0; 21];
581                    prefixed[0] = self.params.p2sh_prefix;
582                    prefixed[1..].copy_from_slice(&hash[..]);
583                    base58::encode_check_to_fmt(fmt, &prefixed[..])
584                }
585            }
586            Payload::WitnessProgram {
587                version: witver,
588                program: ref witprog,
589            } => {
590                let hrp = match self.blinding_pubkey.is_some() {
591                    true => self.params.blech_hrp,
592                    false => self.params.bech_hrp,
593                };
594
595                // FIXME: surely we can fix this logic to not be so repetitive.
596                if self.is_blinded() {
597                    if let Some(ref blinder) = self.blinding_pubkey {
598                        let byte_iter = IntoIterator::into_iter(blinder.serialize())
599                            .chain(witprog.iter().copied());
600                        let fe_iter = byte_iter.bytes_to_fes();
601                        if witver.to_u8() == 0 {
602                            for c in fe_iter
603                                .with_checksum::<Blech32>(&hrp)
604                                .with_witness_version(witver)
605                                .chars()
606                            {
607                                fmt.write_char(c)?;
608                            }
609                        } else {
610                            for c in fe_iter
611                                .with_checksum::<Blech32m>(&hrp)
612                                .with_witness_version(witver)
613                                .chars()
614                            {
615                                fmt.write_char(c)?;
616                            }
617                        }
618                        return Ok(());
619                    }
620                }
621
622                let byte_iter = witprog.iter().copied();
623                let fe_iter = byte_iter.bytes_to_fes();
624                if witver.to_u8() == 0 {
625                    for c in fe_iter
626                        .with_checksum::<Bech32>(&hrp)
627                        .with_witness_version(witver)
628                        .chars()
629                    {
630                        fmt.write_char(c)?;
631                    }
632                } else {
633                    for c in fe_iter
634                        .with_checksum::<Bech32m>(&hrp)
635                        .with_witness_version(witver)
636                        .chars()
637                    {
638                        fmt.write_char(c)?;
639                    }
640                }
641                Ok(())
642            }
643        }
644    }
645}
646
647impl fmt::Debug for Address {
648    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
649        fmt::Display::fmt(self, fmt)
650    }
651}
652
653/// Extract the bech32 prefix.
654/// Returns the same slice when no prefix is found.
655fn find_prefix(bech32: &str) -> &str {
656    // Split at the last occurrence of the separator character '1'.
657    match bech32.rfind('1') {
658        None => bech32,
659        Some(sep) => bech32.split_at(sep).0,
660    }
661}
662
663/// Checks if both prefixes match, regardless of case.
664/// The first prefix can be mixed case, but the second one is expected in
665/// lower case.
666fn match_prefix(prefix_mixed: &str, target: Hrp) -> bool {
667    target.len() == prefix_mixed.len() && target
668        .lowercase_char_iter()
669        .zip(prefix_mixed.chars())
670        .all(|(char_lower, char_mixed)| char_lower == char_mixed.to_ascii_lowercase())
671}
672
673impl FromStr for Address {
674    type Err = AddressError;
675
676    fn from_str(s: &str) -> Result<Address, AddressError> {
677        // shorthands
678        let liq = &AddressParams::LIQUID;
679        let ele = &AddressParams::ELEMENTS;
680        let liq_test = &AddressParams::LIQUID_TESTNET;
681
682        let net_arr = [liq, ele, liq_test];
683
684        let prefix = find_prefix(s);
685        for net in &net_arr {
686            // Bech32.
687            if match_prefix(prefix, net.bech_hrp) {
688                return Address::from_bech32(s, false, net);
689            }
690            if match_prefix(prefix, net.blech_hrp) {
691                return Address::from_bech32(s, true, net);
692            }
693        }
694
695        // Base58.
696        if s.len() > 150 {
697            return Err(AddressError::InvalidLength(s.len() * 11 / 15));
698        }
699        let data = base58::decode_check(s)?;
700        if data.is_empty() {
701            return Err(AddressError::InvalidLength(data.len()));
702        }
703
704        let p = data[0];
705        for net in &net_arr {
706            if p == net.p2pkh_prefix || p == net.p2sh_prefix || p == net.blinded_prefix {
707                return Address::from_base58(&data, net);
708            }
709        }
710
711        Err(AddressError::InvalidAddress(s.to_owned()))
712    }
713}
714
715#[cfg(feature = "serde")]
716impl<'de> serde::Deserialize<'de> for Address {
717    #[inline]
718    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
719    where
720        D: serde::Deserializer<'de>,
721    {
722        use std::fmt::Formatter;
723
724        struct Visitor;
725        impl<'de> serde::de::Visitor<'de> for Visitor {
726            type Value = Address;
727
728            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
729                formatter.write_str("a Bitcoin address")
730            }
731
732            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
733            where
734                E: serde::de::Error,
735            {
736                Address::from_str(v).map_err(E::custom)
737            }
738
739            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
740            where
741                E: serde::de::Error,
742            {
743                self.visit_str(v)
744            }
745
746            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
747            where
748                E: serde::de::Error,
749            {
750                self.visit_str(&v)
751            }
752        }
753
754        deserializer.deserialize_str(Visitor)
755    }
756}
757
758#[cfg(feature = "serde")]
759impl serde::Serialize for Address {
760    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
761    where
762        S: serde::Serializer,
763    {
764        serializer.serialize_str(&self.to_string())
765    }
766}
767
768#[cfg(test)]
769mod test {
770    use super::*;
771    use crate::Script;
772    use bitcoin::key;
773    use secp256k1_zkp::{PublicKey, Secp256k1};
774    #[cfg(feature = "serde")]
775    use serde_json;
776
777    fn roundtrips(addr: &Address) {
778        assert_eq!(
779            Address::from_str(&addr.to_string()).ok().as_ref(),
780            Some(addr),
781            "string round-trip failed for {}",
782            addr,
783        );
784        assert_eq!(
785            Address::from_script(&addr.script_pubkey(), addr.blinding_pubkey, addr.params).as_ref(),
786            Some(addr),
787            "script round-trip failed for {}",
788            addr,
789        );
790        #[cfg(feature = "serde")]
791        assert_eq!(
792            serde_json::from_value::<Address>(serde_json::to_value(addr).unwrap())
793                .ok()
794                .as_ref(),
795            Some(addr)
796        );
797    }
798
799    #[test]
800    fn regression_188() {
801        // Tests that the `tlq` prefix was not accidentally changed, e.g. to `tlg` :).
802        let addr = Address::from_str("tlq1qq2xvpcvfup5j8zscjq05u2wxxjcyewk7979f3mmz5l7uw5pqmx6xf5xy50hsn6vhkm5euwt72x878eq6zxx2z58hd7zrsg9qn").unwrap();
803        roundtrips(&addr);
804    }
805
806    #[test]
807    fn exhaustive() {
808        let blinder_hex = "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
809        let blinder = PublicKey::from_str(blinder_hex).unwrap();
810        let sk_wif = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy";
811        let sk = key::PrivateKey::from_wif(sk_wif).unwrap();
812        let pk = sk.public_key(&Secp256k1::new());
813        let script: Script = vec![1u8, 2, 42, 255, 196].into();
814
815        let vectors = [
816            /* #00 */ Address::p2pkh(&pk, None, &AddressParams::LIQUID),
817            /* #01 */ Address::p2pkh(&pk, None, &AddressParams::ELEMENTS),
818            /* #02 */ Address::p2pkh(&pk, Some(blinder), &AddressParams::LIQUID),
819            /* #03 */ Address::p2pkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
820            /* #04 */ Address::p2sh(&script, None, &AddressParams::LIQUID),
821            /* #05 */ Address::p2sh(&script, None, &AddressParams::ELEMENTS),
822            /* #06 */ Address::p2sh(&script, Some(blinder), &AddressParams::LIQUID),
823            /* #07 */
824            Address::p2sh(&script, Some(blinder), &AddressParams::ELEMENTS),
825            /* #08 */ Address::p2wpkh(&pk, None, &AddressParams::LIQUID),
826            /* #09 */ Address::p2wpkh(&pk, None, &AddressParams::ELEMENTS),
827            /* #10 */ Address::p2wpkh(&pk, Some(blinder), &AddressParams::LIQUID),
828            /* #11 */ Address::p2wpkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
829            /* #12 */ Address::p2shwpkh(&pk, None, &AddressParams::LIQUID),
830            /* #13 */ Address::p2shwpkh(&pk, None, &AddressParams::ELEMENTS),
831            /* #14 */ Address::p2shwpkh(&pk, Some(blinder), &AddressParams::LIQUID),
832            /* #15 */
833            Address::p2shwpkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
834            /* #16 */ Address::p2wsh(&script, None, &AddressParams::LIQUID),
835            /* #17 */ Address::p2wsh(&script, None, &AddressParams::ELEMENTS),
836            /* #18 */ Address::p2wsh(&script, Some(blinder), &AddressParams::LIQUID),
837            /* #19 */
838            Address::p2wsh(&script, Some(blinder), &AddressParams::ELEMENTS),
839            /* #20 */ Address::p2shwsh(&script, None, &AddressParams::LIQUID),
840            /* #21 */ Address::p2shwsh(&script, None, &AddressParams::ELEMENTS),
841            /* #22 */
842            Address::p2shwsh(&script, Some(blinder), &AddressParams::LIQUID),
843            /* #23 */
844            Address::p2shwsh(&script, Some(blinder), &AddressParams::ELEMENTS),
845        ];
846
847        for addr in &vectors {
848            roundtrips(addr);
849        }
850    }
851
852    #[test]
853    fn test_actuals() {
854        // vectors: (address, blinded?, params)
855        let addresses = [
856            // Elements
857            ("2dxmEBXc2qMYcLSKiDBxdEePY3Ytixmnh4E", false, AddressParams::ELEMENTS),
858            ("CTEo6VKG8xbe7HnfVW9mQoWTgtgeRSPktwTLbELzGw5tV8Ngzu53EBiasFMQKVbWmKWWTAdN5AUf4M6Y", true, AddressParams::ELEMENTS),
859            ("ert1qwhh2n5qypypm0eufahm2pvj8raj9zq5c27cysu", false, AddressParams::ELEMENTS),
860            ("el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsmxh4xcjh2rse", true, AddressParams::ELEMENTS),
861            // Liquid
862            ("GqiQRsPEyJLAsEBFB5R34KHuqxDNkG3zur", false, AddressParams::LIQUID),
863            ("VJLDwMVWXg8RKq4mRe3YFNTAEykVN6V8x5MRUKKoC3nfRnbpnZeiG3jygMC6A4Gw967GY5EotJ4Rau2F", true, AddressParams::LIQUID),
864            ("ex1q7gkeyjut0mrxc3j0kjlt7rmcnvsh0gt45d3fud", false, AddressParams::LIQUID),
865            ("lq1qqf8er278e6nyvuwtgf39e6ewvdcnjupn9a86rzpx655y5lhkt0walu3djf9cklkxd3ryld97hu8h3xepw7sh2rlu7q45dcew5", true, AddressParams::LIQUID),
866        ];
867
868        for &(a, blinded, ref params) in &addresses {
869            let result = a.parse();
870            assert!(
871                result.is_ok(),
872                "vector: {}, err: \"{}\"",
873                a,
874                result.unwrap_err()
875            );
876            let addr: Address = result.unwrap();
877            assert_eq!(a, &addr.to_string(), "vector: {}", a);
878            assert_eq!(blinded, addr.is_blinded());
879            assert_eq!(params, addr.params);
880            roundtrips(&addr);
881        }
882    }
883
884    #[test]
885    fn test_blech32_vectors() {
886        // taken from Elements test/functional/rpc_invalid_address_message.py
887        let address: Result<Address, _> = "el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsmxh4xcjh2rse".parse();
888        assert!(address.is_ok());
889
890        let address: Result<Address, _> = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsxguu9nrdg2pc".parse();
891        assert_eq!(
892            address.err().unwrap().to_string(),
893            "blech32 error: invalid checksum", // is valid blech32, but should be blech32m
894        );
895
896        let address: Result<Address, _> = "el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsnnmzrstzt7de".parse();
897        assert_eq!(
898            address.err().unwrap().to_string(),
899            "blech32 error: invalid checksum", // is valid blech32m, but should be blech32
900        );
901
902        let address: Result<Address, _> =
903            "ert130xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqqu2tys".parse();
904        assert_eq!(
905            address.err().unwrap().to_string(),
906            "bech32 error: invalid segwit witness version: 17 (bech32 character: '3')",
907        );
908
909        let address: Result<Address, _> = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9jfn0gypaj".parse();
910        assert_eq!(
911            address.err().unwrap().to_string(),
912            "blech32 error: invalid witness length",
913        );
914
915        // "invalid prefix" gives a weird error message because we do
916        // a dumb prefix check before even attempting bech32 decoding
917        let address: Result<Address, _> = "rrr1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfs2d9rp7meq4kg".parse();
918        assert_eq!(address.err().unwrap().to_string(), "base58 error: decode",);
919    }
920
921    #[test]
922    fn test_fixed_addresses() {
923        let pk = bitcoin::PublicKey::from_str(
924            "0212bf0ea45b733dfde8ecb5e896306c4165c666c99fc5d1ab887f71393a975cea",
925        )
926        .unwrap();
927        let script = Script::default();
928        let secp = Secp256k1::verification_only();
929        let internal_key = UntweakedPublicKey::from_str(
930            "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51",
931        )
932        .unwrap();
933        let tap_node_hash = TapNodeHash::all_zeros();
934
935        let mut expected = IntoIterator::into_iter([
936            "2dszRCFv8Ub4ytKo1Q1vXXGgSx7mekNDwSJ",
937            "XToMocNywBYNSiXUe5xvoa2naAps9Ek1hq",
938            "ert1qew0l0emv7449u7hqgc8utzdzryhse79yhq2sxv",
939            "XZF6k8S6eoVxXMB4NpWjh2s7LjQUP7pw2R",
940            "ert1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2szaqlpq",
941            "ert1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02q2cqvj9",
942            "ert1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390sqkjp06",
943            "CTEkC79sYAvWNcxd8iTYnYo226FqRBbzBcMppq7L2dA8jVXJWoo1kKWB3UBLY6gBjiXf87ibs8c6mQyZ",
944            "AzpjUhKMLJi9y2oLt3ZdM3BP9nHdLPJfGMVxRBaRc2gDpeNqPMVpShTszJW7bX42vT2KoejYy8GtbcxH",
945            "el1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gmz9ej9kyq5yc",
946            "AzpjUhKMLJi9y2oLt3ZdM3BP9nHdLPJfGMVxRBaRc2gDpeNvq6SLVpBVwtakF6nmUFundyW7YjUdVkpr",
947            "el1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz4h79u87cnxdzq",
948            "el1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75cj24fq2u2ls5",
949            "el1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2lhjd0k0q7qn4h",
950            "QFq3vvrr6Ub2KAyb3LdoCxEQvKukB6nN9i",
951            "GydeMhecNgrq17WMkyyTM4ETv1YubMVtLN",
952            "ex1qew0l0emv7449u7hqgc8utzdzryhse79ydjqgek",
953            "H55PJDhj6JpR5k9wViXGEX4nga8WmhXtnD",
954            "ex1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2s4sla8h",
955            "ex1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02qa4lw5j",
956            "ex1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390shmdrfd",
957            "VTptY6cqJbusNpL5xvo8VL38nLX9PGDjfYQfqhu9EaA7FtuidkWyQzMHY9jzZrpBcCXT437vM6V4N8kh",
958            "VJL64Ep3rcngP4cScRme15q9i8MCNiuqWeiG3YbtduUidVyorg7nRsgmmF714QtH3sNpWB2CqsVVciQh",
959            "lq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gs2923tg58xcz",
960            "VJL64Ep3rcngP4cScRme15q9i8MCNiuqWeiG3YbtduUidVyuJR4JUzQPiqBdhzd1bgGHLVnmRUjfHc68",
961            "lq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz47jmkmgmr9a4s",
962            "lq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75375l4kfvf08y",
963            "lq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2l77n92erwrrz8",
964            "FojPFeboBgrd953mXXe72KWthjVwHWozqN",
965            "8vsafXgrB5bJeSidGbK5eYnjKvQ3RiB4BB",
966            "tex1qew0l0emv7449u7hqgc8utzdzryhse79yh5jp9a",
967            "92KKc3jxthYtj5ND1KrtY1d46UyeWV6XbP",
968            "tex1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2s5fd6kc",
969            "tex1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02quvdf9a",
970            "tex1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390skzlycz",
971            "vtS71VhcpFt978sha5d1L2gCzp3UL5kXacRpb3N4GTW5MwvBzz5HwxYyB8Pns4yM2dd2osmQkHSkp88u",
972            "vjTuLJ76nGi8PUopBVmGK8bLKPfBpaBWf6wKfn8z9Vdz6ubVhpvmMr6TK2RcqAYiujN1g1uwg8kejrM3",
973            "tlq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gq8g2kuxfj8ft",
974            "vjTuLJ76nGi8PUopBVmGK8bLKPfBpaBWf6wKfn8z9Vdz6ubb9ZsHQxp5GcWFUkHTTYFUWLgWFk1DN5Fe",
975            "tlq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz4e6vcdfcyp5m8",
976            "tlq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75kkr3rh2tdxfn",
977            "tlq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2lekytucqf82vs",
978        ]);
979
980        for params in [
981            &AddressParams::ELEMENTS,
982            &AddressParams::LIQUID,
983            &AddressParams::LIQUID_TESTNET,
984        ] {
985            for blinder in [None, Some(pk.inner)] {
986                let addr = Address::p2pkh(&pk, blinder, params);
987                assert_eq!(&addr.to_string(), expected.next().unwrap());
988
989                let addr = Address::p2sh(&script, blinder, params);
990                assert_eq!(&addr.to_string(), expected.next().unwrap());
991
992                let addr = Address::p2wpkh(&pk, blinder, params);
993                assert_eq!(&addr.to_string(), expected.next().unwrap());
994
995                let addr = Address::p2shwpkh(&pk, blinder, params);
996                assert_eq!(&addr.to_string(), expected.next().unwrap());
997
998                let addr = Address::p2wsh(&script, blinder, params);
999                assert_eq!(&addr.to_string(), expected.next().unwrap());
1000
1001                let addr = Address::p2tr(&secp, internal_key, None, blinder, params);
1002                assert_eq!(&addr.to_string(), expected.next().unwrap());
1003
1004                let addr = Address::p2tr(&secp, internal_key, Some(tap_node_hash), blinder, params);
1005                assert_eq!(&addr.to_string(), expected.next().unwrap());
1006            }
1007        }
1008    }
1009}