1use super::address::*;
2use super::certificate::{Certificates, Ed25519KeyHashes, UnitInterval};
3use super::coin::Coin;
4use super::common::*;
5use super::hash::*;
6use super::metadata::Metadata;
7use super::witness::TransactionWitness;
8use cbored::tagged::EncodedCBOR;
9use cbored::CborDataOf;
10use cbored::CborRepr;
11use cryptoxide::hashing::blake2b_256;
12use std::fmt;
13
14#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
21#[cborrepr(structure = "array")]
22pub struct Transaction {
23 pub body: SerializedTransactionBody,
24 pub witness: TransactionWitness,
25 pub is_valid: bool,
26 pub auxiliary_data: Nullable<Metadata>,
27}
28
29#[derive(Clone, CborRepr, PartialEq, Eq)]
30#[cborrepr(structure = "flat")]
31pub struct SerializedTransactionBody(CborDataOf<TransactionBody>);
32
33impl SerializedTransactionBody {
34 pub fn hash(&self) -> TxHash {
35 TxHash(blake2b_256(self.0.as_ref()))
36 }
37
38 pub fn unserialize(&self) -> TransactionBody {
39 self.0.unserialize()
40 }
41}
42
43impl AsRef<[u8]> for SerializedTransactionBody {
44 fn as_ref(&self) -> &[u8] {
45 self.0.as_ref()
46 }
47}
48
49impl fmt::Debug for SerializedTransactionBody {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 write!(f, "{}", hex::encode(&self.0.as_ref()))
52 }
53}
54
55#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
57#[cborrepr(structure = "mapint", skipkey = 10, skipkey = 12)]
58pub struct TransactionBody {
59 #[cborrepr(mandatory)]
60 pub inputs: TransactionInputs,
61 #[cborrepr(mandatory)]
62 pub outputs: TransactionOutputs,
63 #[cborrepr(mandatory)]
64 pub fee: Coin,
65 pub ttl: Option<u64>,
66 pub certs: Option<Certificates>,
67 pub withdrawals: Option<Withdrawals>,
68 pub update: Option<AnyCbor>,
69 pub metadata_hash: Option<MetadataHash>,
70 pub validity_start_interval: Option<u64>,
71 pub mint: Option<Mint>,
72 pub script_data_hash: Option<ScriptDataHash>,
73 pub collateral: Option<TransactionInputs>,
74 pub required_signers: Option<Ed25519KeyHashes>,
75 pub network_id: Option<u8>,
76 pub collateral_return: Option<TransactionOutput>,
77 pub total_collateral: Option<Coin>,
78 pub reference_inputs: Option<TransactionInputs>,
79}
80
81impl TransactionBody {
82 pub fn serialize(&self) -> SerializedTransactionBody {
83 SerializedTransactionBody(CborDataOf::from(self))
84 }
85
86 pub fn hash(&self) -> TxHash {
87 TxHash(blake2b_256(&self.serialize().as_ref()))
88 }
89}
90
91#[derive(Clone, Copy, Debug, CborRepr, PartialEq, Eq, PartialOrd, Ord, Hash)]
92#[cborrepr(structure = "flat")]
93pub struct TxIndex(pub u64);
94
95#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
96#[cborrepr(structure = "array")]
97pub struct TransactionInput(pub TxHash, pub TxIndex);
98
99#[derive(Clone, Debug, PartialEq, Eq, CborRepr)]
100#[cborrepr(enumtype = "enumtype")]
101pub enum TransactionOutput {
102 #[cborrepr(cbortype = "array")]
103 V1(TransactionOutputV1),
104 #[cborrepr(cbortype = "map")]
105 V2(TransactionOutputV2),
106}
107
108#[derive(Clone, Debug, PartialEq, Eq, CborRepr)]
109#[cborrepr(structure = "array_lastopt")]
110pub struct TransactionOutputV1 {
111 pub address: SerializedAddress,
112 pub amount: TransactionOutputValue,
113 pub data_hash: Option<Bytes>,
114}
115
116#[derive(Clone, Debug, PartialEq, Eq, CborRepr)]
117#[cborrepr(structure = "mapint")]
118pub struct TransactionOutputV2 {
119 #[cborrepr(mandatory)]
120 pub address: SerializedAddress,
121 #[cborrepr(mandatory)]
122 pub amount: TransactionOutputValue,
123 pub datum: Option<Datum>,
124 pub script_ref: Option<EncodedCBOR>,
125}
126
127#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
128#[cborrepr(enumtype = "tagvariant")]
129pub enum Datum {
130 Hash(Bytes),
131 Inline(EncodedCBOR),
132}
133
134impl TransactionOutput {
135 pub fn value(&self) -> Coin {
136 match self {
137 TransactionOutput::V1(v) => v.value(),
138 TransactionOutput::V2(v) => v.value(),
139 }
140 }
141}
142
143impl TransactionOutputV1 {
144 pub fn value(&self) -> Coin {
145 self.amount.value()
146 }
147}
148
149impl TransactionOutputV2 {
150 pub fn value(&self) -> Coin {
151 self.amount.value()
152 }
153}
154
155#[derive(Clone, Debug, PartialEq, Eq, CborRepr)]
156#[cborrepr(enumtype = "enumtype")]
157pub enum TransactionOutputValue {
158 #[cborrepr(cbortype = "positive")]
159 OnlyCoin(Coin),
160 #[cborrepr(cbortype = "array")]
161 CoinAsset(CoinMultiasset),
162}
163
164impl TransactionOutputValue {
165 pub fn value(&self) -> Coin {
166 match self {
167 TransactionOutputValue::OnlyCoin(coin) => *coin,
168 TransactionOutputValue::CoinAsset(ca) => ca.coin,
169 }
170 }
171}
172
173#[derive(Clone, Debug, PartialEq, Eq, CborRepr)]
174#[cborrepr(structure = "array")]
175pub struct CoinMultiasset {
176 pub coin: Coin,
177 pub multiasset: Multiasset,
178}
179
180crate::map_structure!(Multiasset, Bytes, Assets);
181crate::map_structure!(Assets, Bytes, u64);
182crate::map_structure!(Withdrawals, Bytes, Coin);
183crate::map_structure!(Mint, ScriptHash, MintAssets);
184crate::map_structure!(MintAssets, Bytes, Number64);
185crate::map_structure!(CostModels, Language, Numbers64);
186crate::vec_structure!(TransactionInputs, TransactionInput);
187crate::vec_structure!(TransactionOutputs, TransactionOutput);
188crate::vec_structure!(TransactionBodies, SerializedTransactionBody);
189crate::vec_structure!(TxIndexes, TxIndex);
190crate::vec_structure!(ProtocolVersions, super::header::ProtocolVersion);
191
192#[derive(Clone, Debug, PartialEq, Eq, CborRepr, PartialOrd, Ord)]
193#[cborrepr(enumtype = "enumint")]
194pub enum Language {
195 PlutusV1,
196 PlutusV2,
197}
198
199impl TransactionOutputs {
200 pub fn iter_indexed(&self) -> impl Iterator<Item = (TxIndex, &TransactionOutput)> {
201 self.0
202 .iter()
203 .enumerate()
204 .map(|(idx, txo)| (TxIndex(idx as u64), txo))
205 }
206}
207
208#[derive(Clone, Debug, CborRepr, PartialEq, Eq)]
209#[cborrepr(structure = "mapint")]
210pub struct UpdateProtocolParam {
211 pub minfee_a: Option<Coin>,
212 pub minfee_b: Option<Coin>,
213 pub max_block_body_size: Option<u32>,
214 pub max_tx_size: Option<u32>,
215 pub max_block_header_size: Option<u32>,
216 pub key_deposit: Option<Coin>,
217 pub pool_deposit: Option<Coin>,
218 pub max_epoch: Option<u32>,
219 pub desired_stake_pools: Option<u32>,
220 pub pool_pledge_influence: Option<UnitInterval>,
221 pub expansion_rate: Option<UnitInterval>,
222 pub treasury_growth_rate: Option<UnitInterval>,
223 pub decentralization_d: Option<UnitInterval>,
224 pub extra_entropy: Option<AnyCbor>,
225 pub protocol_version: Option<ProtocolVersions>,
226 pub min_pool_cost: Option<Coin>,
227 pub ada_per_utxo_byte: Option<Coin>,
228 pub cost_models: Option<CostModels>,
229 pub execution_costs: Option<AnyCbor>,
230 pub max_tx_ex_units: Option<AnyCbor>,
231 pub max_block_ex_units: Option<AnyCbor>,
232 pub max_value_size: Option<u32>,
233 pub collateral_percentage: Option<u32>,
234 pub max_collateral_inputs: Option<u32>,
235}