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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use serde::{Deserialize, Serialize};

#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ChainParams {
    pub chain_name: &'static str,
    pub genesis_block: &'static str,
    pub p2pkh_address_prefix: u8,
    pub p2sh_address_prefix: u8,
    pub pkey_prefix: u8,
    pub bip32_privkey_prefix: u32,
    pub bip32_pubkey_prefix: u32,
    pub bip32_wif_privkey_prefix: &'static str,
    pub bip32_wif_pubkey_prefix: &'static str,
}

pub static DOGE_MAIN_NET_CHAIN: ChainParams = ChainParams {
    chain_name: "doge_main",
    genesis_block: "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691",
    p2pkh_address_prefix: 0x1e,       // D
    p2sh_address_prefix: 0x16,        // 9 or A
    pkey_prefix: 0x9e,                // Q or 6
    bip32_privkey_prefix: 0x02fac398, // dgpv
    bip32_pubkey_prefix: 0x02facafd,  // dgub
    bip32_wif_privkey_prefix: "dgpv",
    bip32_wif_pubkey_prefix: "dgub",
};

pub static DOGE_TEST_NET_CHAIN: ChainParams = ChainParams {
    chain_name: "doge_test",
    genesis_block: "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e",
    p2pkh_address_prefix: 0x71,       // n
    p2sh_address_prefix: 0xc4,        // 2
    pkey_prefix: 0xf1,                // 9 or c
    bip32_privkey_prefix: 0x04358394, // tprv
    bip32_pubkey_prefix: 0x043587cf,  // tpub
    bip32_wif_privkey_prefix: "tprv",
    bip32_wif_pubkey_prefix: "tpub",
};

pub static DOGE_REG_TEST_CHAIN: ChainParams = ChainParams {
    chain_name: "doge_regtest",
    genesis_block: "3d2160a3b5dc4a9d62e7e66a295f70313ac808440ef7400d6c0772171ce973a5",
    p2pkh_address_prefix: 0x6f,       // n
    p2sh_address_prefix: 0xc4,        // 2
    pkey_prefix: 0xef,                //
    bip32_privkey_prefix: 0x04358394, // tprv
    bip32_pubkey_prefix: 0x043587cf,  // tpub
    bip32_wif_privkey_prefix: "tprv",
    bip32_wif_pubkey_prefix: "tpub",
};

pub type KeyBits = u8; // keyECPriv,keyECPub,keyBip32Priv,keyBip32Pub,dogeMainNet,dogeTestNet

pub const KEY_NONE: KeyBits = 0;
pub const KEY_ECPRIV: KeyBits = 1;
pub const KEY_ECPUB: KeyBits = 2;
pub const KEY_BIP32_PRIV: KeyBits = 4;
pub const KEY_BIP32_PUB: KeyBits = 8;
pub const MAIN_NET_DOGE: KeyBits = 16;
pub const TEST_NET_DOGE: KeyBits = 32;
pub const MAIN_NET_BTC: KeyBits = 64;

pub fn chain_from_key_bits(key: KeyBits) -> &'static ChainParams {
    if (key & MAIN_NET_DOGE) != 0 {
        return &DOGE_MAIN_NET_CHAIN;
    }

    &DOGE_TEST_NET_CHAIN // fallback
}

pub fn key_bits_for_chain(chain: &ChainParams) -> KeyBits {
    let mut bits = 0u8;
    if chain == &DOGE_MAIN_NET_CHAIN {
        bits |= MAIN_NET_DOGE
    } else if chain == &DOGE_TEST_NET_CHAIN {
        bits |= TEST_NET_DOGE
    }
    bits
}

pub fn chain_from_wif(wif: &str) -> &'static ChainParams {
    let wif = wif.as_bytes();
    if wif.is_empty() {
        return &DOGE_TEST_NET_CHAIN; // fallback
    }
    match wif[0] {
        b'D' | b'9' | b'A' | b'Q' | b'6' | b'd' => &DOGE_MAIN_NET_CHAIN,
        _ => &DOGE_TEST_NET_CHAIN,
    }
}