zebra_chain/transparent/
script.rs
1use std::{fmt, io};
4
5use hex::{FromHex, FromHexError, ToHex};
6
7use crate::serialization::{
8 zcash_serialize_bytes, SerializationError, ZcashDeserialize, ZcashSerialize,
9};
10
11#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
13#[cfg_attr(
14 any(test, feature = "proptest-impl"),
15 derive(proptest_derive::Arbitrary)
16)]
17pub struct Script(
18 #[serde(with = "hex")]
23 Vec<u8>,
24);
25
26impl Script {
27 pub fn new(raw_bytes: &[u8]) -> Self {
30 Script(raw_bytes.to_vec())
31 }
32
33 pub fn as_raw_bytes(&self) -> &[u8] {
41 &self.0
42 }
43}
44
45impl From<zcash_transparent::address::Script> for Script {
46 fn from(script: zcash_transparent::address::Script) -> Self {
47 Script(script.0)
48 }
49}
50
51impl fmt::Display for Script {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 f.write_str(&self.encode_hex::<String>())
54 }
55}
56
57impl fmt::Debug for Script {
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 f.debug_tuple("Script")
60 .field(&hex::encode(&self.0))
61 .finish()
62 }
63}
64
65impl ToHex for &Script {
66 fn encode_hex<T: FromIterator<char>>(&self) -> T {
67 self.as_raw_bytes().encode_hex()
68 }
69
70 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
71 self.as_raw_bytes().encode_hex_upper()
72 }
73}
74
75impl ToHex for Script {
76 fn encode_hex<T: FromIterator<char>>(&self) -> T {
77 (&self).encode_hex()
78 }
79
80 fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
81 (&self).encode_hex_upper()
82 }
83}
84
85impl FromHex for Script {
86 type Error = FromHexError;
87
88 fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
89 let bytes = Vec::from_hex(hex)?;
90 Ok(Script::new(&bytes))
91 }
92}
93
94impl ZcashSerialize for Script {
95 fn zcash_serialize<W: io::Write>(&self, writer: W) -> Result<(), io::Error> {
96 zcash_serialize_bytes(&self.0, writer)
97 }
98}
99
100impl ZcashDeserialize for Script {
101 fn zcash_deserialize<R: io::Read>(reader: R) -> Result<Self, SerializationError> {
102 Vec::zcash_deserialize(reader).map(Script)
103 }
104}
105
106#[cfg(test)]
107mod proptests {
108 use std::io::Cursor;
109
110 use proptest::prelude::*;
111
112 use super::*;
113
114 proptest! {
115 #[test]
116 fn script_roundtrip(script in any::<Script>()) {
117 let _init_guard = zebra_test::init();
118
119 let mut bytes = Cursor::new(Vec::new());
120 script.zcash_serialize(&mut bytes)?;
121
122 bytes.set_position(0);
123 let other_script = Script::zcash_deserialize(&mut bytes)?;
124
125 prop_assert_eq![script, other_script];
126 }
127 }
128}