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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
crate::ix!();
/**
| Signs a PSBTInput, verifying that all
| provided data matches what is being
| signed.
|
| txdata should be the output of PrecomputePSBTData
| (which can be shared across multiple
| SignPSBTInput calls). If it is nullptr,
| a dummy signature will be created.
|
*/
pub fn sign_psbt_input(
provider: &SigningProvider,
psbt: &mut PartiallySignedTransaction,
index: i32,
txdata: *const PrecomputedTransactionData,
sighash: Option<i32>,
out_sigdata: Option<*mut SignatureData>) -> bool {
let sighash: i32 = sighash.unwrap_or(SIGHASH_ALL.try_into().unwrap());
let input: &mut PSBTInput = &mut psbt.inputs[index as usize];
let tx: &MutableTransaction = psbt.tx.as_ref().unwrap();
if psbt_input_signed(input) {
return true;
}
// Fill SignatureData with input info
let mut sigdata = SignatureData::default();
input.fill_signature_data(&mut sigdata);
// Get UTXO
let mut require_witness_sig: bool = false;
let mut utxo = TxOut::default();
if Arc::<Transaction>::strong_count(&input.non_witness_utxo) != 0 {
// If we're taking our information
// from a non-witness UTXO, verify that it
// matches the prevout.
let prevout: &OutPoint = &tx.vin[index as usize].prevout;;
if prevout.n as usize >= (*input.non_witness_utxo).vout.len() {
return false;
}
if (*input.non_witness_utxo).get_hash() != &prevout.hash {
return false;
}
utxo = (*input.non_witness_utxo).vout[prevout.n as usize].clone();
} else if !input.witness_utxo.is_null() {
utxo = input.witness_utxo.clone();
/*
| When we're taking our information from
| a witness UTXO, we can't verify it is
| actually data from the output being
| spent. This is safe in case a witness
| signature is produced (which includes
| this information directly in the hash),
| but not for non-witness
| signatures. Remember that we require
| a witness signature in this situation.
*/
require_witness_sig = true;
} else {
return false;
}
sigdata.witness = false;
let mut sig_complete = bool::default();
if txdata == std::ptr::null_mut() {
sig_complete = produce_signature(
provider,
&**DUMMY_SIGNATURE_CREATOR.lock().unwrap(),
&utxo.script_pub_key,
&mut sigdata
);
} else {
let creator: MutableTransactionSignatureCreator
= MutableTransactionSignatureCreator::new_with_txdata(
tx,
index.try_into().unwrap(),
&utxo.n_value,
txdata,
sighash
);
sig_complete = produce_signature(
provider,
&creator,
&utxo.script_pub_key,
&mut sigdata
);
}
// Verify that a witness signature was
// produced in case one was required.
if require_witness_sig && !sigdata.witness {
return false;
}
input.from_signature_data(&sigdata);
/**
| If we have a witness signature, put
| a witness UTXO.
|
| TODO: For segwit v1, we should remove
| the non_witness_utxo
*/
if sigdata.witness {
input.witness_utxo = utxo;
//input.non_witness_utxo = std::ptr::null_mut();
}
let out_sigdata = out_sigdata.unwrap();
// Fill in the missing info
if out_sigdata != std::ptr::null_mut() {
unsafe {
(*out_sigdata).missing_pubkeys = sigdata.missing_pubkeys;
(*out_sigdata).missing_sigs = sigdata.missing_sigs;
(*out_sigdata).missing_redeem_script = sigdata.missing_redeem_script;
(*out_sigdata).missing_witness_script = sigdata.missing_witness_script;
}
}
sig_complete
}