pub fn cashaddr_decode(input: &str, network: Network) -> Result<(Vec<u8>, AddressType)> {
    // Do some sanity checks on the string
    let mut upper = false;
    let mut lower = false;
    for c in input.chars() {
        if c.is_lowercase() {
            if upper {
                let msg = "Address cannot contain both upper and lower case".to_string();
                return Err(Error::BadData(msg));
            }
            lower = true;
        } else if c.is_uppercase() {
            if lower {
                let msg = "Address cannot contain both upper and lower case".to_string();
                return Err(Error::BadData(msg));
            }
            upper = true;
        }
    }

    // Split the prefix from the rest
    let parts: Vec<&str> = input.split(':').collect();
    if parts.len() < 2 {
        return Err(Error::BadData("No prefix separator ':'".to_string()));
    }
    if parts.len() > 2 {
        return Err(Error::BadData("Too many prefixes".to_string()));
    }
    if parts[0].to_lowercase() != network.cashaddr_prefix() {
        let msg = format!("Unexpected prefix: {}", parts[0]);
        return Err(Error::BadData(msg));
    }

    // Verify the checksum
    let mut checksum_input = Vec::with_capacity(input.len());
    for c in network.cashaddr_prefix().chars() {
        checksum_input.push((c as u8) & 31);
    }
    checksum_input.push(0); // 0 for prefix
    for c in parts[1].chars() {
        if c as u32 > 127 {
            let msg = format!("Address contains non-ascii characters: {}", c);
            return Err(Error::BadData(msg));
        }
        let d = CHARSET_REV[c as usize];
        if d == -1 {
            let msg = format!("Address contains invalid cashaddr characters: {}", c);
            return Err(Error::BadData(msg));
        }
        checksum_input.push(d as u8);
    }
    let checksum = polymod(&checksum_input);
    if checksum != 0 {
        return Err(Error::BadData("Nonzero checksum".to_string()));
    }

    // Extract the payload squeezed between the prefix and checksum in the checksum_input
    let lower = parts[0].len() + 1;
    let upper = checksum_input.len() - 8;
    let payload = convert_bits(&checksum_input[lower..upper], 5, 8, false);

    // Verify the version byte
    let version = payload[0];
    let encoded_data = payload[1..].to_vec();

    let version_size = version & version_byte_flags::SIZE_MASK;
    if (version_size == version_byte_flags::SIZE_160 && encoded_data.len() != 20)
        || (version_size == version_byte_flags::SIZE_192 && encoded_data.len() != 24)
        || (version_size == version_byte_flags::SIZE_224 && encoded_data.len() != 28)
        || (version_size == version_byte_flags::SIZE_256 && encoded_data.len() != 32)
        || (version_size == version_byte_flags::SIZE_320 && encoded_data.len() != 40)
        || (version_size == version_byte_flags::SIZE_384 && encoded_data.len() != 48)
        || (version_size == version_byte_flags::SIZE_448 && encoded_data.len() != 56)
        || (version_size == version_byte_flags::SIZE_512 && encoded_data.len() != 64)
    {
        let msg = format!("Wrong size: {}", encoded_data.len());
        return Err(Error::BadData(msg));
    }

    // Extract the address type and return
    let version_type = version & version_byte_flags::TYPE_MASK;
    let addr_type = if version_type == version_byte_flags::TYPE_P2PKH {
        AddressType::P2PKH
    } else if version_type == version_byte_flags::TYPE_P2SH {
        AddressType::P2SH
    } else {
        let msg = format!("Invalid type in version byte: {}", version);
        return Err(Error::BadData(msg));
    };

    Ok((encoded_data, addr_type))
}
/// Decodes a cashaddr address to a public key hash
Decodes a cashaddr address to a public key hash
Decodes a cashaddr address to a public key hash
pub fn cashaddr_decode(input: &str, network: Network) -> Result<(Vec<u8>, AddressType)> {
    // Do some sanity checks on the string
    let mut upper = false;
    let mut lower = false;
    for c in input.chars() {
        if c.is_lowercase() {
            if upper {
                let msg = "Address cannot contain both upper and lower case".to_string();
                return Err(Error::BadData(msg));
            }
            lower = true;
        } else if c.is_uppercase() {
            if lower {
                let msg = "Address cannot contain both upper and lower case".to_string();
                return Err(Error::BadData(msg));
            }
            upper = true;
        }
    }
    // Split the prefix from the rest
    let parts: Vec<&str> = input.split(':').collect();
    if parts.len() < 2 {
        return Err(Error::BadData("No prefix separator ':'".to_string()));
    }
    if parts.len() > 2 {
        return Err(Error::BadData("Too many prefixes".to_string()));
    }
    if parts[0].to_lowercase() != network.cashaddr_prefix() {
        let msg = format!("Unexpected prefix: {}", parts[0]);
        return Err(Error::BadData(msg));
    }
    // Verify the checksum
    let mut checksum_input = Vec::with_capacity(input.len());
    for c in network.cashaddr_prefix().chars() {
        checksum_input.push((c as u8) & 31);
    }
    checksum_input.push(0); // 0 for prefix
    for c in parts[1].chars() {
        if c as u32 > 127 {
            let msg = format!("Address contains non-ascii characters: {}", c);
            return Err(Error::BadData(msg));
        }
        let d = CHARSET_REV[c as usize];
        if d == -1 {
            let msg = format!("Address contains invalid cashaddr characters: {}", c);
            return Err(Error::BadData(msg));
        }
        checksum_input.push(d as u8);
    }
    let checksum = polymod(&checksum_input);
    if checksum != 0 {
        return Err(Error::BadData("Nonzero checksum".to_string()));
    }
    // Extract the payload squeezed between the prefix and checksum in the checksum_input
    let lower = parts[0].len() + 1;
    let upper = checksum_input.len() - 8;
    let payload = convert_bits(&checksum_input[lower..upper], 5, 8, false);
    // Verify the version byte
    let version = payload[0];
    let encoded_data = payload[1..].to_vec();
    let version_size = version & version_byte_flags::SIZE_MASK;
    if (version_size == version_byte_flags::SIZE_160 && encoded_data.len() != 20)
        || (version_size == version_byte_flags::SIZE_192 && encoded_data.len() != 24)
        || (version_size == version_byte_flags::SIZE_224 && encoded_data.len() != 28)
        || (version_size == version_byte_flags::SIZE_256 && encoded_data.len() != 32)
        || (version_size == version_byte_flags::SIZE_320 && encoded_data.len() != 40)
        || (version_size == version_byte_flags::SIZE_384 && encoded_data.len() != 48)
        || (version_size == version_byte_flags::SIZE_448 && encoded_data.len() != 56)
        || (version_size == version_byte_flags::SIZE_512 && encoded_data.len() != 64)
    {
        let msg = format!("Wrong size: {}", encoded_data.len());
        return Err(Error::BadData(msg));
    }
    // Extract the address type and return
    let version_type = version & version_byte_flags::TYPE_MASK;
    let addr_type = if version_type == version_byte_flags::TYPE_P2PKH {
        AddressType::P2PKH
    } else if version_type == version_byte_flags::TYPE_P2SH {
        AddressType::P2SH
    } else {
        let msg = format!("Invalid type in version byte: {}", version);
        return Err(Error::BadData(msg));
    };
    Ok((encoded_data, addr_type))
}
pub fn cashaddr_decode ( input : & str , network : Network ) -> Result < ( Vec < u8 > , AddressType ) > { // Do some sanity checks on the string let mut upper = false ; let mut lower = false ; for c in input . chars ( ) { if c . is_lowercase ( ) { if upper { let msg = " " . to_string ( ) ; return Err ( Error :: BadData ( msg ) ) ; } lower = true ; } else if c . is_uppercase ( ) { if lower { let msg = " " . to_string ( ) ; return Err ( Error :: BadData ( msg ) ) ; } upper = true ; } } // Split the prefix from the rest let parts : Vec < & str > = input . split ( ':' ) . collect ( ) ; if parts . len ( ) < 2 { return Err ( Error :: BadData ( " " . to_string ( ) ) ) ; } if parts . len ( ) > 2 { return Err ( Error :: BadData ( " " . to_string ( ) ) ) ; } if parts [ 0 ] . to_lowercase ( ) != network . cashaddr_prefix ( ) { let msg = format ! ( " " parts [ 0 ] ) ; return Err ( Error :: BadData ( msg ) ) ; } // Verify the checksum let mut checksum_input = Vec :: with_capacity ( input . len ( ) ) ; for c in network . cashaddr_prefix ( ) . chars ( ) { checksum_input . push ( ( c as u8 ) & 31 ) ; } checksum_input . push ( 0 ) ; // 0 for prefix for c in parts [ 1 ] . chars ( ) { if c as u32 > 127 { let msg = format ! ( " " c ) ; return Err ( Error :: BadData ( msg ) ) ; } let d = CHARSET_REV [ c as usize ] ; if d == - 1 { let msg = format ! ( " " c ) ; return Err ( Error :: BadData ( msg ) ) ; } checksum_input . push ( d as u8 ) ; } let checksum = polymod ( & checksum_input ) ; if checksum != 0 { return Err ( Error :: BadData ( " " . to_string ( ) ) ) ; } // Extract the payload squeezed between the prefix and checksum in the checksum_input let lower = parts [ 0 ] . len ( ) + 1 ; let upper = checksum_input . len ( ) - 8 ; let payload = convert_bits ( & checksum_input [ lower .. upper ] , 5 , 8 , false ) ; // Verify the version byte let version = payload [ 0 ] ; let encoded_data = payload [ 1 .. ] . to_vec ( ) ; let version_size = version & version_byte_flags :: SIZE_MASK ; if ( version_size == version_byte_flags :: SIZE_160 && encoded_data . len ( ) != 20 ) || ( version_size == version_byte_flags :: SIZE_192 && encoded_data . len ( ) != 24 ) || ( version_size == version_byte_flags :: SIZE_224 && encoded_data . len ( ) != 28 ) || ( version_size == version_byte_flags :: SIZE_256 && encoded_data . len ( ) != 32 ) || ( version_size == version_byte_flags :: SIZE_320 && encoded_data . len ( ) != 40 ) || ( version_size == version_byte_flags :: SIZE_384 && encoded_data . len ( ) != 48 ) || ( version_size == version_byte_flags :: SIZE_448 && encoded_data . len ( ) != 56 ) || ( version_size == version_byte_flags :: SIZE_512 && encoded_data . len ( ) != 64 ) { let msg = format ! ( " " encoded_data len ( ) ) ; return Err ( Error :: BadData ( msg ) ) ; } // Extract the address type and return let version_type = version & version_byte_flags :: TYPE_MASK ; let addr_type = if version_type == version_byte_flags :: TYPE_P2PKH { AddressType :: P2PKH } else if version_type == version_byte_flags :: TYPE_P2SH { AddressType :: P2SH } else { let msg = format ! ( " " version ) ; return Err ( Error :: BadData ( msg ) ) ; } ; Ok ( ( encoded_data , addr_type ) ) }
Decodes a cashaddr address to a public key hash
Decodes a cashaddr address to a public key hash
input
&str
network
Network
input
&str
network
Network