satellite_bitcoin/
script.rs1use borsh::io::{Error as IoError, ErrorKind as IoErrorKind};
2use borsh::{BorshDeserialize, BorshSerialize};
3
4pub const MAX_BTC_SCRIPT_BYTES: usize =
6 satellite_bitcoin_transactions::constants::MAX_BTC_SCRIPT_BYTES;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct ScriptPubkey(Vec<u8>);
12
13impl ScriptPubkey {
14 #[inline]
15 pub fn as_bytes(&self) -> &[u8] {
16 &self.0
17 }
18
19 #[inline]
20 pub fn into_vec(self) -> Vec<u8> {
21 self.0
22 }
23
24 pub fn is_empty(&self) -> bool {
25 self.0.is_empty()
26 }
27}
28
29impl TryFrom<Vec<u8>> for ScriptPubkey {
30 type Error = ScriptPubkeyError;
31 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
32 if value.is_empty() || value.len() > MAX_BTC_SCRIPT_BYTES {
33 return Err(ScriptPubkeyError::InvalidLength);
34 }
35 Ok(ScriptPubkey(value))
36 }
37}
38
39impl BorshSerialize for ScriptPubkey {
40 fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> std::result::Result<(), IoError> {
41 borsh::BorshSerialize::serialize(&self.0, writer)
42 }
43}
44
45impl BorshDeserialize for ScriptPubkey {
46 fn deserialize_reader<R: borsh::io::Read>(
47 reader: &mut R,
48 ) -> std::result::Result<Self, IoError> {
49 let value = Vec::<u8>::deserialize_reader(reader)?;
50 if value.is_empty() || value.len() > MAX_BTC_SCRIPT_BYTES {
51 return Err(IoError::new(
52 IoErrorKind::InvalidData,
53 "script_pubkey length invalid",
54 ));
55 }
56 Ok(ScriptPubkey(value))
57 }
58}
59
60impl From<ScriptPubkey> for bitcoin::ScriptBuf {
61 fn from(value: ScriptPubkey) -> Self {
62 bitcoin::ScriptBuf::from_bytes(value.0)
63 }
64}
65
66impl TryFrom<bitcoin::ScriptBuf> for ScriptPubkey {
67 type Error = ScriptPubkeyError;
68 fn try_from(value: bitcoin::ScriptBuf) -> Result<Self, Self::Error> {
69 if value.is_empty() || value.to_bytes().len() > MAX_BTC_SCRIPT_BYTES {
70 return Err(ScriptPubkeyError::InvalidLength);
71 }
72 Ok(ScriptPubkey(value.to_bytes()))
73 }
74}
75
76impl Default for ScriptPubkey {
77 fn default() -> Self {
78 ScriptPubkey(Vec::new())
79 }
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub enum ScriptPubkeyError {
84 InvalidLength,
85}
86
87impl core::fmt::Display for ScriptPubkeyError {
88 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89 match self {
90 ScriptPubkeyError::InvalidLength => write!(f, "invalid script_pubkey length"),
91 }
92 }
93}