// Rust Bitcoin Library // Written by // The Rust Bitcoin developers // // To the extent possible under law, the author(s) have dedicated all // copyright and related and neighboring rights to this software to // the public domain worldwide. This software is distributed without // any warranty. // // You should have received a copy of the CC0 Public Domain Dedication // along with this software. // If not, see . // //! # PSBT Serialization //! //! Defines traits used for (de)serializing PSBT values into/from raw //! bytes in PSBT key-value pairs. use std::io; use blockdata::script::Script; use blockdata::transaction::{SigHashType, Transaction, TxOut}; use consensus::encode::{self, serialize, Decodable}; use util::bip32::{ChildNumber, Fingerprint, KeySource}; use hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use util::ecdsa::PublicKey; use util::psbt; /// A trait for serializing a value as raw data for insertion into PSBT /// key-value pairs. pub trait Serialize { /// Serialize a value as raw data. fn serialize(&self) -> Vec; } /// A trait for deserializing a value from raw data in PSBT key-value pairs. pub trait Deserialize: Sized { /// Deserialize a value from raw data. fn deserialize(bytes: &[u8]) -> Result; } impl_psbt_de_serialize!(Transaction); impl_psbt_de_serialize!(TxOut); impl_psbt_de_serialize!(Vec>); // scriptWitness impl_psbt_hash_de_serialize!(ripemd160::Hash); impl_psbt_hash_de_serialize!(sha256::Hash); impl_psbt_hash_de_serialize!(hash160::Hash); impl_psbt_hash_de_serialize!(sha256d::Hash); impl Serialize for Script { fn serialize(&self) -> Vec { self.to_bytes() } } impl Deserialize for Script { fn deserialize(bytes: &[u8]) -> Result { Ok(Self::from(bytes.to_vec())) } } impl Serialize for PublicKey { fn serialize(&self) -> Vec { let mut buf = Vec::new(); self.write_into(&mut buf).expect("vecs don't error"); buf } } impl Deserialize for PublicKey { fn deserialize(bytes: &[u8]) -> Result { PublicKey::from_slice(bytes) .map_err(|_| encode::Error::ParseFailed("invalid public key")) } } impl Serialize for KeySource { fn serialize(&self) -> Vec { let mut rv: Vec = Vec::with_capacity(4 + 4 * (self.1).as_ref().len()); rv.append(&mut self.0.to_bytes().to_vec()); for cnum in self.1.into_iter() { rv.append(&mut serialize(&u32::from(*cnum))) } rv } } impl Deserialize for KeySource { fn deserialize(bytes: &[u8]) -> Result { if bytes.len() < 4 { return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) } let fprint: Fingerprint = Fingerprint::from(&bytes[0..4]); let mut dpath: Vec = Default::default(); let mut d = &bytes[4..]; while !d.is_empty() { match u32::consensus_decode(&mut d) { Ok(index) => dpath.push(index.into()), Err(e) => return Err(e), } } Ok((fprint, dpath.into())) } } // partial sigs impl Serialize for Vec { fn serialize(&self) -> Vec { self.clone() } } impl Deserialize for Vec { fn deserialize(bytes: &[u8]) -> Result { Ok(bytes.to_vec()) } } impl Serialize for SigHashType { fn serialize(&self) -> Vec { serialize(&self.as_u32()) } } impl Deserialize for SigHashType { fn deserialize(bytes: &[u8]) -> Result { let raw: u32 = encode::deserialize(bytes)?; let rv: SigHashType = SigHashType::from_u32_consensus(raw); if rv.as_u32() == raw { Ok(rv) } else { Err(psbt::Error::NonStandardSigHashType(raw).into()) } } }