1use bitcoin::consensus::encode::Encodable;
8use bitcoin::hashes::sha256;
9use bitcoin::hashes::Hash;
10use bitcoin::util::amount::Amount;
11
12pub trait CTVHash {
16 fn get_ctv_hash(&self, input_index: u32) -> sha256::Hash;
18 fn total_amount(&self) -> Amount;
20}
21impl CTVHash for bitcoin::Transaction {
22 fn get_ctv_hash(&self, input_index: u32) -> sha256::Hash {
23 let mut ctv_hash = sha256::Hash::engine();
24 self.version.consensus_encode(&mut ctv_hash).unwrap();
25 self.lock_time.consensus_encode(&mut ctv_hash).unwrap();
26 (self.input.len() as u32)
27 .consensus_encode(&mut ctv_hash)
28 .unwrap();
29 {
30 let mut enc = sha256::Hash::engine();
31 for seq in self.input.iter().map(|i| i.sequence) {
32 seq.consensus_encode(&mut enc).unwrap();
33 }
34 sha256::Hash::from_engine(enc)
35 .into_inner()
36 .consensus_encode(&mut ctv_hash)
37 .unwrap();
38 }
39
40 (self.output.len() as u32)
41 .consensus_encode(&mut ctv_hash)
42 .unwrap();
43
44 {
45 let mut enc = sha256::Hash::engine();
46 for out in self.output.iter() {
47 out.consensus_encode(&mut enc).unwrap();
48 }
49 sha256::Hash::from_engine(enc)
50 .into_inner()
51 .consensus_encode(&mut ctv_hash)
52 .unwrap();
53 }
54 input_index.consensus_encode(&mut ctv_hash).unwrap();
55 sha256::Hash::from_engine(ctv_hash)
56 }
57
58 fn total_amount(&self) -> Amount {
59 Amount::from_sat(self.output.iter().fold(0, |a, b| a + b.value))
60 }
61}