ergo_lib/chain/transaction/
input.rs1pub mod prover_result;
4
5use ergotree_interpreter::sigma_protocol::prover::ContextExtension;
6use ergotree_interpreter::sigma_protocol::prover::ProofBytes;
7use ergotree_ir::chain::ergo_box::BoxId;
8use ergotree_ir::serialization::sigma_byte_reader::SigmaByteRead;
9use ergotree_ir::serialization::sigma_byte_writer::SigmaByteWrite;
10use ergotree_ir::serialization::SigmaParsingError;
11use ergotree_ir::serialization::SigmaSerializable;
12use ergotree_ir::serialization::SigmaSerializeResult;
13
14#[cfg(feature = "json")]
15use crate::chain::json::context_extension::ContextExtensionSerde;
16use crate::wallet::box_selector::ErgoBoxId;
17#[cfg(feature = "json")]
18use serde::ser::SerializeStruct;
19#[cfg(feature = "json")]
20use serde::{Deserialize, Serialize};
21
22use self::prover_result::ProverResult;
23
24#[derive(PartialEq, Eq, Debug, Clone)]
26#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
27#[cfg_attr(feature = "json", derive(Deserialize))]
28pub struct UnsignedInput {
29 #[cfg_attr(feature = "json", serde(rename = "boxId"))]
31 pub box_id: BoxId,
32 #[cfg_attr(
34 feature = "json",
35 serde(rename = "extension",),
36 serde(with = "crate::chain::json::context_extension::ContextExtensionSerde")
37 )]
38 pub extension: ContextExtension,
39}
40
41#[cfg(feature = "json")]
42impl Serialize for UnsignedInput {
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: serde::Serializer,
46 {
47 let mut s = serializer.serialize_struct("UnsignedInput", 2)?;
48 s.serialize_field("boxId", &self.box_id)?;
49 s.serialize_field(
50 "extension",
51 &ContextExtensionSerde::from(self.extension.clone()),
52 )?;
53 s.end()
54 }
55}
56
57impl UnsignedInput {
58 pub fn new(box_id: BoxId, extension: ContextExtension) -> Self {
60 UnsignedInput { box_id, extension }
61 }
62
63 pub fn input_to_sign(&self) -> Input {
65 Input {
66 box_id: self.box_id,
67 spending_proof: ProverResult {
68 proof: ProofBytes::Empty,
69 extension: self.extension.clone(),
70 },
71 }
72 }
73}
74
75impl<T: ErgoBoxId> From<T> for UnsignedInput {
76 fn from(b: T) -> Self {
77 UnsignedInput::new(b.box_id(), ContextExtension::empty())
78 }
79}
80
81#[derive(PartialEq, Eq, Debug, Clone)]
83#[cfg_attr(feature = "arbitrary", derive(proptest_derive::Arbitrary))]
84#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
85pub struct Input {
86 #[cfg_attr(feature = "json", serde(rename = "boxId", alias = "id"))]
88 pub box_id: BoxId,
89 #[cfg_attr(
91 feature = "json",
92 serde(
93 rename = "spendingProof",
94 deserialize_with = "ergotree_ir::chain::json::t_as_string_or_struct"
95 )
96 )]
97 pub spending_proof: ProverResult,
98}
99
100impl Input {
101 pub fn new(box_id: BoxId, spending_proof: ProverResult) -> Self {
103 Self {
104 box_id,
105 spending_proof,
106 }
107 }
108
109 pub fn from_unsigned_input(unsigned_input: UnsignedInput, proof_bytes: ProofBytes) -> Self {
111 Self::new(
112 unsigned_input.box_id,
113 ProverResult {
114 proof: proof_bytes,
115 extension: unsigned_input.extension,
116 },
117 )
118 }
119
120 pub fn input_to_sign(&self) -> Input {
122 Input {
123 box_id: self.box_id,
124 spending_proof: ProverResult {
125 proof: ProofBytes::Empty,
126 extension: self.spending_proof.extension.clone(),
127 },
128 }
129 }
130}
131
132impl SigmaSerializable for Input {
133 fn sigma_serialize<W: SigmaByteWrite>(&self, w: &mut W) -> SigmaSerializeResult {
134 self.box_id.sigma_serialize(w)?;
135 self.spending_proof.sigma_serialize(w)?;
136 Ok(())
137 }
138 fn sigma_parse<R: SigmaByteRead>(r: &mut R) -> Result<Self, SigmaParsingError> {
139 let box_id = BoxId::sigma_parse(r)?;
140 let spending_proof = ProverResult::sigma_parse(r)?;
141 Ok(Input {
142 box_id,
143 spending_proof,
144 })
145 }
146}
147
148#[cfg(test)]
149#[allow(clippy::panic)]
150mod tests {
151 use super::*;
152 use ergotree_ir::serialization::sigma_serialize_roundtrip;
153 use proptest::prelude::*;
154
155 proptest! {
156
157 #[test]
158 fn ser_roundtrip(v in any::<Input>()) {
159 prop_assert_eq![sigma_serialize_roundtrip(&v), v];
160 }
161 }
162}