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(witver.to_u8() as i64)
434                .push_slice(witprog),
435        }
436        .into_script()
437    }
438
439    /// Convert this address to an unconfidential address.
440    pub fn to_unconfidential(&self) -> Address {
441        Address {
442            params: self.params,
443            payload: self.payload.clone(),
444            blinding_pubkey: None,
445        }
446    }
447
448    /// Convert this address to a confidential address with the given blinding pubkey.
449    pub fn to_confidential(&self, blinding_pubkey: secp256k1_zkp::PublicKey) -> Address {
450        Address {
451            params: self.params,
452            payload: self.payload.clone(),
453            blinding_pubkey: Some(blinding_pubkey),
454        }
455    }
456
457    fn from_bech32(
458        s: &str,
459        blinded: bool,
460        params: &'static AddressParams,
461    ) -> Result<Address, AddressError> {
462        let (version, data): (Fe32, Vec<u8>) = if blinded {
463            let hs = crate::blech32::decode::SegwitHrpstring::new(s)?;
464            (hs.witness_version(), hs.byte_iter().collect())
465        } else {
466            let hs = bech32::primitives::decode::SegwitHrpstring::new(s)?;
467            (hs.witness_version(), hs.byte_iter().collect())
468        };
469
470        let (blinding_pubkey, program) = match blinded {
471            true => (
472                Some(
473                    secp256k1_zkp::PublicKey::from_slice(&data[..33])
474                        .map_err(AddressError::InvalidBlindingPubKey)?,
475                ),
476                data[33..].to_vec(),
477            ),
478            false => (None, data),
479        };
480
481        Ok(Address {
482            params,
483            payload: Payload::WitnessProgram { version, program },
484            blinding_pubkey,
485        })
486    }
487
488    // data.len() should be >= 1 when this method is called
489    fn from_base58(data: &[u8], params: &'static AddressParams) -> Result<Address, AddressError> {
490        // When unblinded, the structure is:
491        // <1: regular prefix> <20: hash160>
492        // When blinded, the structure is:
493        // <1: blinding prefix> <1: regular prefix> <33: blinding pubkey> <20: hash160>
494
495        let (blinded, prefix) = match data[0] == params.blinded_prefix {
496            true => {
497                if data.len() != 55 {
498                    return Err(AddressError::InvalidLength(data.len()));
499                }
500                (true, data[1])
501            }
502            false => {
503                if data.len() != 21 {
504                    return Err(AddressError::InvalidLength(data.len()));
505                }
506                (false, data[0])
507            }
508        };
509
510        let (blinding_pubkey, payload_data) = match blinded {
511            true => (
512                Some(
513                    secp256k1_zkp::PublicKey::from_slice(&data[2..35])
514                        .map_err(AddressError::InvalidBlindingPubKey)?,
515                ),
516                &data[35..],
517            ),
518            false => (None, &data[1..]),
519        };
520
521        let payload = if prefix == params.p2pkh_prefix {
522            Payload::PubkeyHash(PubkeyHash::from_slice(payload_data).unwrap())
523        } else if prefix == params.p2sh_prefix {
524            Payload::ScriptHash(ScriptHash::from_slice(payload_data).unwrap())
525        } else {
526            return Err(AddressError::InvalidAddressVersion(prefix));
527        };
528
529        Ok(Address {
530            params,
531            payload,
532            blinding_pubkey,
533        })
534    }
535
536    /// Parse the address using the given parameters.
537    /// When using the built-in parameters, you can use [FromStr].
538    pub fn parse_with_params(
539        s: &str,
540        params: &'static AddressParams,
541    ) -> Result<Address, AddressError> {
542        // Bech32.
543        let prefix = find_prefix(s);
544        let b32_ex = match_prefix(prefix, params.bech_hrp);
545        let b32_bl = match_prefix(prefix, params.blech_hrp);
546        if b32_ex || b32_bl {
547            return Address::from_bech32(s, b32_bl, params);
548        }
549
550        // Base58.
551        if s.len() > 150 {
552            return Err(AddressError::InvalidLength(s.len() * 11 / 15));
553        }
554        let data = base58::decode_check(s)?;
555        Address::from_base58(&data, params)
556    }
557}
558
559impl fmt::Display for Address {
560    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
561        match self.payload {
562            Payload::PubkeyHash(ref hash) => {
563                if let Some(ref blinder) = self.blinding_pubkey {
564                    let mut prefixed = [0; 55]; // 1 + 1 + 33 + 20
565                    prefixed[0] = self.params.blinded_prefix;
566                    prefixed[1] = self.params.p2pkh_prefix;
567                    prefixed[2..35].copy_from_slice(&blinder.serialize());
568                    prefixed[35..].copy_from_slice(&hash[..]);
569                    base58::encode_check_to_fmt(fmt, &prefixed[..])
570                } else {
571                    let mut prefixed = [0; 21];
572                    prefixed[0] = self.params.p2pkh_prefix;
573                    prefixed[1..].copy_from_slice(&hash[..]);
574                    base58::encode_check_to_fmt(fmt, &prefixed[..])
575                }
576            }
577            Payload::ScriptHash(ref hash) => {
578                if let Some(ref blinder) = self.blinding_pubkey {
579                    let mut prefixed = [0; 55]; // 1 + 1 + 33 + 20
580                    prefixed[0] = self.params.blinded_prefix;
581                    prefixed[1] = self.params.p2sh_prefix;
582                    prefixed[2..35].copy_from_slice(&blinder.serialize());
583                    prefixed[35..].copy_from_slice(&hash[..]);
584                    base58::encode_check_to_fmt(fmt, &prefixed[..])
585                } else {
586                    let mut prefixed = [0; 21];
587                    prefixed[0] = self.params.p2sh_prefix;
588                    prefixed[1..].copy_from_slice(&hash[..]);
589                    base58::encode_check_to_fmt(fmt, &prefixed[..])
590                }
591            }
592            Payload::WitnessProgram {
593                version: witver,
594                program: ref witprog,
595            } => {
596                let hrp = match self.blinding_pubkey.is_some() {
597                    true => self.params.blech_hrp,
598                    false => self.params.bech_hrp,
599                };
600
601                // FIXME: surely we can fix this logic to not be so repetitive.
602                if self.is_blinded() {
603                    if let Some(ref blinder) = self.blinding_pubkey {
604                        let byte_iter = IntoIterator::into_iter(blinder.serialize())
605                            .chain(witprog.iter().copied());
606                        let fe_iter = byte_iter.bytes_to_fes();
607                        if witver.to_u8() == 0 {
608                            for c in fe_iter
609                                .with_checksum::<Blech32>(&hrp)
610                                .with_witness_version(witver)
611                                .chars()
612                            {
613                                fmt.write_char(c)?;
614                            }
615                        } else {
616                            for c in fe_iter
617                                .with_checksum::<Blech32m>(&hrp)
618                                .with_witness_version(witver)
619                                .chars()
620                            {
621                                fmt.write_char(c)?;
622                            }
623                        }
624                        return Ok(());
625                    }
626                }
627
628                let byte_iter = witprog.iter().copied();
629                let fe_iter = byte_iter.bytes_to_fes();
630                if witver.to_u8() == 0 {
631                    for c in fe_iter
632                        .with_checksum::<Bech32>(&hrp)
633                        .with_witness_version(witver)
634                        .chars()
635                    {
636                        fmt.write_char(c)?;
637                    }
638                } else {
639                    for c in fe_iter
640                        .with_checksum::<Bech32m>(&hrp)
641                        .with_witness_version(witver)
642                        .chars()
643                    {
644                        fmt.write_char(c)?;
645                    }
646                }
647                Ok(())
648            }
649        }
650    }
651}
652
653impl fmt::Debug for Address {
654    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
655        fmt::Display::fmt(self, fmt)
656    }
657}
658
659/// Extract the bech32 prefix.
660/// Returns the same slice when no prefix is found.
661fn find_prefix(bech32: &str) -> &str {
662    // Split at the last occurrence of the separator character '1'.
663    match bech32.rfind('1') {
664        None => bech32,
665        Some(sep) => bech32.split_at(sep).0,
666    }
667}
668
669/// Checks if both prefixes match, regardless of case.
670/// The first prefix can be mixed case, but the second one is expected in
671/// lower case.
672fn match_prefix(prefix_mixed: &str, target: Hrp) -> bool {
673    if target.len() != prefix_mixed.len() {
674        false
675    } else {
676        target
677            .lowercase_char_iter()
678            .zip(prefix_mixed.chars())
679            .all(|(char_lower, char_mixed)| char_lower == char_mixed.to_ascii_lowercase())
680    }
681}
682
683impl FromStr for Address {
684    type Err = AddressError;
685
686    fn from_str(s: &str) -> Result<Address, AddressError> {
687        // shorthands
688        let liq = &AddressParams::LIQUID;
689        let ele = &AddressParams::ELEMENTS;
690        let liq_test = &AddressParams::LIQUID_TESTNET;
691
692        let net_arr = [liq, ele, liq_test];
693
694        let prefix = find_prefix(s);
695        for net in net_arr.iter() {
696            // Bech32.
697            if match_prefix(prefix, net.bech_hrp) {
698                return Address::from_bech32(s, false, net);
699            }
700            if match_prefix(prefix, net.blech_hrp) {
701                return Address::from_bech32(s, true, net);
702            }
703        }
704
705        // Base58.
706        if s.len() > 150 {
707            return Err(AddressError::InvalidLength(s.len() * 11 / 15));
708        }
709        let data = base58::decode_check(s)?;
710        if data.is_empty() {
711            return Err(AddressError::InvalidLength(data.len()));
712        }
713
714        let p = data[0];
715        for net in net_arr.iter() {
716            if p == net.p2pkh_prefix || p == net.p2sh_prefix || p == net.blinded_prefix {
717                return Address::from_base58(&data, net);
718            }
719        }
720
721        Err(AddressError::InvalidAddress(s.to_owned()))
722    }
723}
724
725#[cfg(feature = "serde")]
726impl<'de> serde::Deserialize<'de> for Address {
727    #[inline]
728    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
729    where
730        D: serde::Deserializer<'de>,
731    {
732        use std::fmt::Formatter;
733
734        struct Visitor;
735        impl<'de> serde::de::Visitor<'de> for Visitor {
736            type Value = Address;
737
738            fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
739                formatter.write_str("a Bitcoin address")
740            }
741
742            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
743            where
744                E: serde::de::Error,
745            {
746                Address::from_str(v).map_err(E::custom)
747            }
748
749            fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
750            where
751                E: serde::de::Error,
752            {
753                self.visit_str(v)
754            }
755
756            fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
757            where
758                E: serde::de::Error,
759            {
760                self.visit_str(&v)
761            }
762        }
763
764        deserializer.deserialize_str(Visitor)
765    }
766}
767
768#[cfg(feature = "serde")]
769impl serde::Serialize for Address {
770    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
771    where
772        S: serde::Serializer,
773    {
774        serializer.serialize_str(&self.to_string())
775    }
776}
777
778#[cfg(test)]
779mod test {
780    use super::*;
781    use crate::Script;
782    use bitcoin::key;
783    use secp256k1_zkp::{PublicKey, Secp256k1};
784    #[cfg(feature = "serde")]
785    use serde_json;
786
787    fn roundtrips(addr: &Address) {
788        assert_eq!(
789            Address::from_str(&addr.to_string()).ok().as_ref(),
790            Some(addr),
791            "string round-trip failed for {}",
792            addr,
793        );
794        assert_eq!(
795            Address::from_script(&addr.script_pubkey(), addr.blinding_pubkey, addr.params).as_ref(),
796            Some(addr),
797            "script round-trip failed for {}",
798            addr,
799        );
800        #[cfg(feature = "serde")]
801        assert_eq!(
802            serde_json::from_value::<Address>(serde_json::to_value(addr).unwrap())
803                .ok()
804                .as_ref(),
805            Some(addr)
806        );
807    }
808
809    #[test]
810    fn regression_188() {
811        // Tests that the `tlq` prefix was not accidentally changed, e.g. to `tlg` :).
812        let addr = Address::from_str("tlq1qq2xvpcvfup5j8zscjq05u2wxxjcyewk7979f3mmz5l7uw5pqmx6xf5xy50hsn6vhkm5euwt72x878eq6zxx2z58hd7zrsg9qn").unwrap();
813        roundtrips(&addr);
814    }
815
816    #[test]
817    fn exhaustive() {
818        let blinder_hex = "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
819        let blinder = PublicKey::from_str(blinder_hex).unwrap();
820        let sk_wif = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy";
821        let sk = key::PrivateKey::from_wif(sk_wif).unwrap();
822        let pk = sk.public_key(&Secp256k1::new());
823        let script: Script = vec![1u8, 2, 42, 255, 196].into();
824
825        let vectors = [
826            /* #00 */ Address::p2pkh(&pk, None, &AddressParams::LIQUID),
827            /* #01 */ Address::p2pkh(&pk, None, &AddressParams::ELEMENTS),
828            /* #02 */ Address::p2pkh(&pk, Some(blinder), &AddressParams::LIQUID),
829            /* #03 */ Address::p2pkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
830            /* #04 */ Address::p2sh(&script, None, &AddressParams::LIQUID),
831            /* #05 */ Address::p2sh(&script, None, &AddressParams::ELEMENTS),
832            /* #06 */ Address::p2sh(&script, Some(blinder), &AddressParams::LIQUID),
833            /* #07 */
834            Address::p2sh(&script, Some(blinder), &AddressParams::ELEMENTS),
835            /* #08 */ Address::p2wpkh(&pk, None, &AddressParams::LIQUID),
836            /* #09 */ Address::p2wpkh(&pk, None, &AddressParams::ELEMENTS),
837            /* #10 */ Address::p2wpkh(&pk, Some(blinder), &AddressParams::LIQUID),
838            /* #11 */ Address::p2wpkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
839            /* #12 */ Address::p2shwpkh(&pk, None, &AddressParams::LIQUID),
840            /* #13 */ Address::p2shwpkh(&pk, None, &AddressParams::ELEMENTS),
841            /* #14 */ Address::p2shwpkh(&pk, Some(blinder), &AddressParams::LIQUID),
842            /* #15 */
843            Address::p2shwpkh(&pk, Some(blinder), &AddressParams::ELEMENTS),
844            /* #16 */ Address::p2wsh(&script, None, &AddressParams::LIQUID),
845            /* #17 */ Address::p2wsh(&script, None, &AddressParams::ELEMENTS),
846            /* #18 */ Address::p2wsh(&script, Some(blinder), &AddressParams::LIQUID),
847            /* #19 */
848            Address::p2wsh(&script, Some(blinder), &AddressParams::ELEMENTS),
849            /* #20 */ Address::p2shwsh(&script, None, &AddressParams::LIQUID),
850            /* #21 */ Address::p2shwsh(&script, None, &AddressParams::ELEMENTS),
851            /* #22 */
852            Address::p2shwsh(&script, Some(blinder), &AddressParams::LIQUID),
853            /* #23 */
854            Address::p2shwsh(&script, Some(blinder), &AddressParams::ELEMENTS),
855        ];
856
857        for addr in &vectors {
858            roundtrips(addr);
859        }
860    }
861
862    #[test]
863    fn test_actuals() {
864        // vectors: (address, blinded?, params)
865        let addresses = [
866            // Elements
867            ("2dxmEBXc2qMYcLSKiDBxdEePY3Ytixmnh4E", false, AddressParams::ELEMENTS),
868            ("CTEo6VKG8xbe7HnfVW9mQoWTgtgeRSPktwTLbELzGw5tV8Ngzu53EBiasFMQKVbWmKWWTAdN5AUf4M6Y", true, AddressParams::ELEMENTS),
869            ("ert1qwhh2n5qypypm0eufahm2pvj8raj9zq5c27cysu", false, AddressParams::ELEMENTS),
870            ("el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsmxh4xcjh2rse", true, AddressParams::ELEMENTS),
871            // Liquid
872            ("GqiQRsPEyJLAsEBFB5R34KHuqxDNkG3zur", false, AddressParams::LIQUID),
873            ("VJLDwMVWXg8RKq4mRe3YFNTAEykVN6V8x5MRUKKoC3nfRnbpnZeiG3jygMC6A4Gw967GY5EotJ4Rau2F", true, AddressParams::LIQUID),
874            ("ex1q7gkeyjut0mrxc3j0kjlt7rmcnvsh0gt45d3fud", false, AddressParams::LIQUID),
875            ("lq1qqf8er278e6nyvuwtgf39e6ewvdcnjupn9a86rzpx655y5lhkt0walu3djf9cklkxd3ryld97hu8h3xepw7sh2rlu7q45dcew5", true, AddressParams::LIQUID),
876        ];
877
878        for &(a, blinded, ref params) in &addresses {
879            let result = a.parse();
880            assert!(
881                result.is_ok(),
882                "vector: {}, err: \"{}\"",
883                a,
884                result.unwrap_err()
885            );
886            let addr: Address = result.unwrap();
887            assert_eq!(a, &addr.to_string(), "vector: {}", a);
888            assert_eq!(blinded, addr.is_blinded());
889            assert_eq!(params, addr.params);
890            roundtrips(&addr);
891        }
892    }
893
894    #[test]
895    fn test_blech32_vectors() {
896        // taken from Elements test/functional/rpc_invalid_address_message.py
897        let address: Result<Address, _> = "el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsmxh4xcjh2rse".parse();
898        assert!(address.is_ok());
899
900        let address: Result<Address, _> = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsxguu9nrdg2pc".parse();
901        assert_eq!(
902            address.err().unwrap().to_string(),
903            "blech32 error: invalid checksum", // is valid blech32, but should be blech32m
904        );
905
906        let address: Result<Address, _> = "el1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsnnmzrstzt7de".parse();
907        assert_eq!(
908            address.err().unwrap().to_string(),
909            "blech32 error: invalid checksum", // is valid blech32m, but should be blech32
910        );
911
912        let address: Result<Address, _> =
913            "ert130xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqqu2tys".parse();
914        assert_eq!(
915            address.err().unwrap().to_string(),
916            "bech32 error: invalid segwit witness version: 17 (bech32 character: '3')",
917        );
918
919        let address: Result<Address, _> = "el1pq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfsqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpe9jfn0gypaj".parse();
920        assert_eq!(
921            address.err().unwrap().to_string(),
922            "blech32 error: invalid witness length",
923        );
924
925        // "invalid prefix" gives a weird error message because we do
926        // a dumb prefix check before even attempting bech32 decoding
927        let address: Result<Address, _> = "rrr1qq0umk3pez693jrrlxz9ndlkuwne93gdu9g83mhhzuyf46e3mdzfpva0w48gqgzgrklncnm0k5zeyw8my2ypfs2d9rp7meq4kg".parse();
928        assert_eq!(address.err().unwrap().to_string(), "base58 error: decode",);
929    }
930
931    #[test]
932    fn test_fixed_addresses() {
933        let pk = bitcoin::PublicKey::from_str(
934            "0212bf0ea45b733dfde8ecb5e896306c4165c666c99fc5d1ab887f71393a975cea",
935        )
936        .unwrap();
937        let script = Script::default();
938        let secp = Secp256k1::verification_only();
939        let internal_key = UntweakedPublicKey::from_str(
940            "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51",
941        )
942        .unwrap();
943        let tap_node_hash = TapNodeHash::all_zeros();
944
945        let mut expected = IntoIterator::into_iter([
946            "2dszRCFv8Ub4ytKo1Q1vXXGgSx7mekNDwSJ",
947            "XToMocNywBYNSiXUe5xvoa2naAps9Ek1hq",
948            "ert1qew0l0emv7449u7hqgc8utzdzryhse79yhq2sxv",
949            "XZF6k8S6eoVxXMB4NpWjh2s7LjQUP7pw2R",
950            "ert1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2szaqlpq",
951            "ert1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02q2cqvj9",
952            "ert1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390sqkjp06",
953            "CTEkC79sYAvWNcxd8iTYnYo226FqRBbzBcMppq7L2dA8jVXJWoo1kKWB3UBLY6gBjiXf87ibs8c6mQyZ",
954            "AzpjUhKMLJi9y2oLt3ZdM3BP9nHdLPJfGMVxRBaRc2gDpeNqPMVpShTszJW7bX42vT2KoejYy8GtbcxH",
955            "el1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gmz9ej9kyq5yc",
956            "AzpjUhKMLJi9y2oLt3ZdM3BP9nHdLPJfGMVxRBaRc2gDpeNvq6SLVpBVwtakF6nmUFundyW7YjUdVkpr",
957            "el1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz4h79u87cnxdzq",
958            "el1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75cj24fq2u2ls5",
959            "el1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2lhjd0k0q7qn4h",
960            "QFq3vvrr6Ub2KAyb3LdoCxEQvKukB6nN9i",
961            "GydeMhecNgrq17WMkyyTM4ETv1YubMVtLN",
962            "ex1qew0l0emv7449u7hqgc8utzdzryhse79ydjqgek",
963            "H55PJDhj6JpR5k9wViXGEX4nga8WmhXtnD",
964            "ex1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2s4sla8h",
965            "ex1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02qa4lw5j",
966            "ex1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390shmdrfd",
967            "VTptY6cqJbusNpL5xvo8VL38nLX9PGDjfYQfqhu9EaA7FtuidkWyQzMHY9jzZrpBcCXT437vM6V4N8kh",
968            "VJL64Ep3rcngP4cScRme15q9i8MCNiuqWeiG3YbtduUidVyorg7nRsgmmF714QtH3sNpWB2CqsVVciQh",
969            "lq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gs2923tg58xcz",
970            "VJL64Ep3rcngP4cScRme15q9i8MCNiuqWeiG3YbtduUidVyuJR4JUzQPiqBdhzd1bgGHLVnmRUjfHc68",
971            "lq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz47jmkmgmr9a4s",
972            "lq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75375l4kfvf08y",
973            "lq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2l77n92erwrrz8",
974            "FojPFeboBgrd953mXXe72KWthjVwHWozqN",
975            "8vsafXgrB5bJeSidGbK5eYnjKvQ3RiB4BB",
976            "tex1qew0l0emv7449u7hqgc8utzdzryhse79yh5jp9a",
977            "92KKc3jxthYtj5ND1KrtY1d46UyeWV6XbP",
978            "tex1quwcvgs5clswpfxhm7nyfjmaeysn6us0yvjdexn9yjkv3k7zjhp2s5fd6kc",
979            "tex1p8qs0qcn25l2y6yvtc5t95rr8w9pndcj64c8rkutnvkcvdp6gh02quvdf9a",
980            "tex1pxrrurkg8j8pve97lffvv2y67cf7ux478h077c87qacqzhue7390skzlycz",
981            "vtS71VhcpFt978sha5d1L2gCzp3UL5kXacRpb3N4GTW5MwvBzz5HwxYyB8Pns4yM2dd2osmQkHSkp88u",
982            "vjTuLJ76nGi8PUopBVmGK8bLKPfBpaBWf6wKfn8z9Vdz6ubVhpvmMr6TK2RcqAYiujN1g1uwg8kejrM3",
983            "tlq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4jul7lnkeat2teawq3s0cky6yxf0pnu2gq8g2kuxfj8ft",
984            "vjTuLJ76nGi8PUopBVmGK8bLKPfBpaBWf6wKfn8z9Vdz6ubb9ZsHQxp5GcWFUkHTTYFUWLgWFk1DN5Fe",
985            "tlq1qqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww4casc3pf3lquzjd0haxgn9hmjfp84eq7geymjdx2f9verdu99wz4e6vcdfcyp5m8",
986            "tlq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5wpq7p3x4f75f5gch3gktgxxwu2rxm394tsw8dchxedsc6r53w75kkr3rh2tdxfn",
987            "tlq1pqgft7r4ytdenml0gaj67393sd3qkt3nxex0ut5dt3plhzwf6jaww5vx8c8vs0ywzejta7jjcc5f4asnacdtu0wlaas0upmsq90enaz2lekytucqf82vs",
988        ]);
989
990        for params in [
991            &AddressParams::ELEMENTS,
992            &AddressParams::LIQUID,
993            &AddressParams::LIQUID_TESTNET,
994        ] {
995            for blinder in [None, Some(pk.inner)] {
996                let addr = Address::p2pkh(&pk, blinder, params);
997                assert_eq!(&addr.to_string(), expected.next().unwrap());
998
999                let addr = Address::p2sh(&script, blinder, params);
1000                assert_eq!(&addr.to_string(), expected.next().unwrap());
1001
1002                let addr = Address::p2wpkh(&pk, blinder, params);
1003                assert_eq!(&addr.to_string(), expected.next().unwrap());
1004
1005                let addr = Address::p2shwpkh(&pk, blinder, params);
1006                assert_eq!(&addr.to_string(), expected.next().unwrap());
1007
1008                let addr = Address::p2wsh(&script, blinder, params);
1009                assert_eq!(&addr.to_string(), expected.next().unwrap());
1010
1011                let addr = Address::p2tr(&secp, internal_key, None, blinder, params);
1012                assert_eq!(&addr.to_string(), expected.next().unwrap());
1013
1014                let addr = Address::p2tr(&secp, internal_key, Some(tap_node_hash), blinder, params);
1015                assert_eq!(&addr.to_string(), expected.next().unwrap());
1016            }
1017        }
1018    }
1019}