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
91
92
93
94
95
96
97
98
99
100
101
102
103
crate::ix!();

pub fn decompress_script(
        script: &mut Script,
        n_size: u32,
        in_:    &CompressedScript) -> bool {
    
    match n_size {

        0x00  => {

            script.resize(25, Default::default());
            script[0] = opcode_type::OP_DUP;
            script[1] = opcode_type::OP_HASH160;
            script[2] = 20;
            unsafe {
                libc::memcpy(
                    as_mut_cvoid!(&mut script[3]), 
                    as_cvoid!(in_.as_ptr()), 
                    20
                );
            }
            script[23] = opcode_type::OP_EQUALVERIFY;
            script[24] = opcode_type::OP_CHECKSIG;
            return true;
        },

        0x01  => {
            script.resize(23, Default::default());
            script[0] = opcode_type::OP_HASH160;
            script[1] = 20;

            unsafe {
                libc::memcpy(
                    as_mut_cvoid!(&mut script[2]), 
                    as_cvoid!(in_.as_ptr()), 
                    20
                );
            }

            script[22] = opcode_type::OP_EQUAL;
            return true;
        },

        0x02 | 0x03  => {

            script.resize(35, Default::default());
            script[0] = 33;
            script[1] = n_size.try_into().unwrap();

            unsafe {
                libc::memcpy(
                    as_mut_cvoid!(&mut script[2]), 
                    as_cvoid!(in_.as_ptr()), 
                    32
                );
            }

            script[34] = opcode_type::OP_CHECKSIG;
            return true;
        },

        0x04 | 0x05  => {

            let mut vch: [u8; 33] = [0; 33];

            vch[0] = (n_size - 2).try_into().unwrap();

            unsafe {
                libc::memcpy(
                    as_mut_cvoid!(&mut vch[1]), 
                    as_cvoid!(in_.as_ptr()), 
                    32
                );
            }

            let mut pubkey: PubKey = PubKey::new(&vch);

            if !pubkey.decompress() {
                return false;
            }

            assert!(pubkey.size() == 65);

            script.resize(67, Default::default());
            script[0] = 65;

            unsafe {
                libc::memcpy(
                    as_mut_cvoid!(&mut script[1]), 
                    as_cvoid!(pubkey.data()), 
                    65
                );
            }

            script[66] = opcode_type::OP_CHECKSIG;
            return true;
        },
        _ => {},
    }

    false
}