bitcoin/util/psbt/
serialize.rs

1// Rust Bitcoin Library
2// Written by
3//   The Rust Bitcoin developers
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the CC0 Public Domain Dedication
11// along with this software.
12// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
13//
14
15//! # PSBT Serialization
16//!
17//! Defines traits used for (de)serializing PSBT values into/from raw
18//! bytes in PSBT key-value pairs.
19
20use std::io;
21
22use blockdata::script::Script;
23use blockdata::transaction::{SigHashType, Transaction, TxOut};
24use consensus::encode::{self, serialize, Decodable};
25use util::bip32::{ChildNumber, Fingerprint, KeySource};
26use hashes::{hash160, ripemd160, sha256, sha256d, Hash};
27use secp256k1::{ContextFlag, Secp256k1};
28use util::key::PublicKey;
29use util::psbt;
30
31/// A trait for serializing a value as raw data for insertion into PSBT
32/// key-value pairs.
33pub trait Serialize {
34    /// Serialize a value as raw data.
35    fn serialize(&self) -> Vec<u8>;
36}
37
38/// A trait for deserializing a value from raw data in PSBT key-value pairs.
39pub trait Deserialize: Sized {
40    /// Deserialize a value from raw data.
41    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error>;
42}
43
44impl_psbt_de_serialize!(Transaction);
45impl_psbt_de_serialize!(TxOut);
46impl_psbt_de_serialize!(Vec<Vec<u8>>); // scriptWitness
47impl_psbt_hash_de_serialize!(ripemd160::Hash);
48impl_psbt_hash_de_serialize!(sha256::Hash);
49impl_psbt_hash_de_serialize!(hash160::Hash);
50impl_psbt_hash_de_serialize!(sha256d::Hash);
51
52impl Serialize for Script {
53    fn serialize(&self) -> Vec<u8> {
54        self.to_bytes()
55    }
56}
57
58impl Deserialize for Script {
59    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
60        Ok(Self::from(bytes.to_vec()))
61    }
62}
63
64impl Serialize for PublicKey {
65    fn serialize(&self) -> Vec<u8> {
66        let mut buf = Vec::new();
67        let secp = Secp256k1::with_caps(ContextFlag::None);
68        self.write_into(&secp, &mut buf).expect("vecs don't error");
69        buf
70    }
71}
72
73impl Deserialize for PublicKey {
74    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
75        let secp = Secp256k1::with_caps(ContextFlag::None);
76        PublicKey::from_slice(&secp, bytes)
77            .map_err(|_| encode::Error::ParseFailed("invalid public key"))
78    }
79}
80
81impl Serialize for KeySource {
82    fn serialize(&self) -> Vec<u8> {
83        let mut rv: Vec<u8> = Vec::with_capacity(4 + 4 * (self.1).as_ref().len());
84
85        rv.append(&mut self.0.to_bytes().to_vec());
86
87        for cnum in self.1.into_iter() {
88            rv.append(&mut serialize(&u32::from(*cnum)))
89        }
90
91        rv
92    }
93}
94
95impl Deserialize for KeySource {
96    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
97        if bytes.len() < 4 {
98            return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into())
99        }
100
101        let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]);
102        let mut dpath: Vec<ChildNumber> = Default::default();
103
104        let mut d = &bytes[4..];
105        while !d.is_empty() {
106            match u32::consensus_decode(&mut d) {
107                Ok(index) => dpath.push(index.into()),
108                Err(e) => return Err(e),
109            }
110        }
111
112        Ok((fprint, dpath.into()))
113    }
114}
115
116// partial sigs
117impl Serialize for Vec<u8> {
118    fn serialize(&self) -> Vec<u8> {
119        self.clone()
120    }
121}
122
123impl Deserialize for Vec<u8> {
124    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
125        Ok(bytes.to_vec())
126    }
127}
128
129impl Serialize for SigHashType {
130    fn serialize(&self) -> Vec<u8> {
131        serialize(&self.as_u32())
132    }
133}
134
135impl Deserialize for SigHashType {
136    fn deserialize(bytes: &[u8]) -> Result<Self, encode::Error> {
137        let raw: u32 = encode::deserialize(bytes)?;
138        let rv: SigHashType = SigHashType::from_u32(raw);
139
140        if rv.as_u32() == raw {
141            Ok(rv)
142        } else {
143            Err(psbt::Error::NonStandardSigHashType(raw).into())
144        }
145    }
146}