63 lines
1.9 KiB
Rust
63 lines
1.9 KiB
Rust
use bs58;
|
|
use hex;
|
|
use sha256;
|
|
|
|
// Mainnet
|
|
enum Prefixes {
|
|
P2PKH,
|
|
P2SH,
|
|
WIFPrivateKey,
|
|
ExtendedPrivateKey,
|
|
ExtendedPublicKey,
|
|
}
|
|
|
|
impl Prefixes {
|
|
fn value(&self) -> Vec<u8> {
|
|
match *self {
|
|
Prefixes::P2PKH => vec![0], // 00
|
|
Prefixes::P2SH => vec![5], // 05
|
|
Prefixes::WIFPrivateKey => vec![128], // 80
|
|
Prefixes::ExtendedPrivateKey => vec![4, 136, 173, 228], // 04 88 AD E4
|
|
Prefixes::ExtendedPublicKey => vec![4, 136, 178, 30], // 04 88 B2 1E
|
|
}
|
|
}
|
|
}
|
|
|
|
fn my_checksum(data: &Vec<u8>) -> String {
|
|
// There was a bug here because the first sha256 returns a String - didn't even think of
|
|
// Kind of fucking dumb it returns that as the "default" data type IUAM
|
|
sha256::digest(hex::decode(sha256::digest(data)).unwrap())[0..8].to_string()
|
|
}
|
|
|
|
fn pubkeyhash_to_address(prefix: &str, p2pkh: &str, checksum: Option<&str>) -> String {
|
|
let mut address_unencoded: Vec<u8> = vec![];
|
|
address_unencoded.extend(hex::decode(prefix).unwrap());
|
|
address_unencoded.extend(hex::decode(p2pkh).unwrap());
|
|
let determined_checksum = my_checksum(&address_unencoded);
|
|
if let Some(chk) = checksum {
|
|
assert_eq!(chk, determined_checksum);
|
|
};
|
|
address_unencoded.extend(hex::decode(determined_checksum).unwrap());
|
|
bs58::encode(address_unencoded).into_string()
|
|
}
|
|
|
|
fn main() {
|
|
println!("Hello, world!");
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn satoshi2() {
|
|
let prefix = hex::encode(Prefixes::P2PKH.value());
|
|
let pubkeyhash = "11b366edfc0a8b66feebae5c2e25a7b6a5d1cf31".to_string();
|
|
let satoshi2_address = pubkeyhash_to_address(&prefix, &pubkeyhash, None);
|
|
assert_eq!(
|
|
satoshi2_address,
|
|
"12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S".to_string()
|
|
);
|
|
}
|
|
}
|