1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use bech32::Error as BechError;
use coins_core::enc::{
decode_bech32 as core_decode_bech32, encode_bech32 as core_encode_bech32, EncodingError,
EncodingResult,
};
pub fn encode_bech32(hrp: &str, v: &[u8]) -> EncodingResult<String> {
if v.len() < 2 || v.len() > 40 {
return Err(BechError::InvalidLength.into());
}
let (version_and_len, payload) = v.split_at(2);
if version_and_len[0] > 16 || version_and_len[1] as usize != payload.len() {
return Err(EncodingError::UnknownScriptType);
};
core_encode_bech32(hrp, version_and_len[0], payload)
}
pub fn decode_bech32(expected_hrp: &str, s: &str) -> EncodingResult<Vec<u8>> {
let (version, data) = core_decode_bech32(expected_hrp, s)?;
let mut s: Vec<u8> = vec![version, data.len() as u8];
s.extend(&data);
Ok(s)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn it_should_encode_and_decode_bech32() {
let hrp = "bc";
let addrs = [
"bc1q233q49ve8ysdsztqh9ue57m6227627j8ztscl9",
"bc1qaqm8wh8sr6gfx49mdpz3w70z48xdh0pzlf5kgr",
"bc1qjl8uwezzlech723lpnyuza0h2cdkvxvh54v3dn",
"bc1qn0q63kkp3rj5wyap5fzymlvat28cu2s87tgzu6",
"bc1qnsupj8eqya02nm8v6tmk93zslu2e2z8chlmcej",
"bc1qmcwrdlcqrwcfs6654m8zvmzdmtpuvcxuzn9ahy",
"bc1qvyyvsdcd0t9863stt7u9rf37wx443lzasg0usy",
"bc1qza7dfgl2q83cf68fqkkdd754qx546h4u9vd9tg",
"bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej",
];
for addr in addrs.iter() {
let s = decode_bech32(hrp, addr).unwrap();
let reencoded = encode_bech32(hrp, &s).unwrap();
assert_eq!(*addr, reencoded);
}
}
}