shuttle_core/
transaction.rs1use amount::Stroops;
2use time_bounds::TimeBounds;
3use memo::Memo;
4use network::Network;
5use crypto::{KeyPair, PublicKey};
6use signature::DecoratedSignature;
7use operation::Operation;
8use error::Result;
9use xdr::ToXdr;
10use crypto;
11
12const BASE_FEE: Stroops = Stroops(100);
13
14#[derive(Debug, Clone)]
16pub struct Transaction {
17 pub source: PublicKey,
19 pub sequence: u64,
21 pub fee: Stroops,
23 pub time_bounds: Option<TimeBounds>,
25 pub memo: Memo,
27 pub operations: Vec<Operation>,
29}
30
31impl Transaction {
32 pub fn new(
34 source: PublicKey,
35 sequence: u64,
36 time_bounds: Option<TimeBounds>,
37 memo: Memo,
38 operations: Vec<Operation>,
39 ) -> Transaction {
40 let fee = BASE_FEE * operations.len();
41 Transaction {
42 source,
43 sequence,
44 fee,
45 time_bounds,
46 memo,
47 operations,
48 }
49 }
50
51 pub fn source(&self) -> &PublicKey {
53 &self.source
54 }
55
56 pub fn base_fee(&self) -> &Stroops {
58 &self.fee
59 }
60
61 pub fn time_bounds(&self) -> &Option<TimeBounds> {
63 &self.time_bounds
64 }
65
66 pub fn memo(&self) -> &Memo {
68 &self.memo
69 }
70
71 pub fn sequence(&self) -> u64 {
73 self.sequence
74 }
75
76 pub fn operations(&self) -> &Vec<Operation> {
78 &self.operations
79 }
80
81 pub fn sign(self, keypair: &KeyPair, network: &Network) -> Result<SignedTransaction> {
83 let mut sig = SignedTransaction::new(self, network)?;
84 sig.sign(keypair)?;
85 Ok(sig)
86 }
87}
88
89#[derive(Debug, Clone)]
91pub struct SignedTransaction {
92 network_id: Vec<u8>,
93 transaction: Transaction,
94 signatures: Vec<DecoratedSignature>,
95}
96
97impl SignedTransaction {
98 pub fn new(transaction: Transaction, network: &Network) -> Result<SignedTransaction> {
100 Ok(SignedTransaction {
101 network_id: network.network_id().clone(),
102 transaction,
103 signatures: Vec::new(),
104 })
105 }
106
107 pub fn new_without_network(
109 transaction: Transaction,
110 signatures: Vec<DecoratedSignature>,
111 ) -> SignedTransaction {
112 SignedTransaction {
113 network_id: Vec::new(),
114 transaction,
115 signatures,
116 }
117 }
118
119 pub fn sign(&mut self, keypair: &KeyPair) -> Result<()> {
121 let payload = self.hash()?;
122 let new_signature = keypair.sign_decorated(&payload);
123 self.signatures.push(new_signature);
124 Ok(())
125 }
126
127 pub fn hash(&self) -> Result<Vec<u8>> {
129 let payload = self.signature_base()?;
130 Ok(crypto::hash(&payload))
131 }
132
133 pub fn signature_base(&self) -> Result<Vec<u8>> {
136 let sig_payload = TransactionSignaturePayload {
137 network_id: &self.network_id,
138 transaction: &self.transaction,
139 };
140 let mut payload = Vec::new();
141 sig_payload.to_writer(&mut payload)?;
142 Ok(payload)
143 }
144
145 pub fn transaction(&self) -> &Transaction {
147 &self.transaction
148 }
149
150 pub fn signatures(&self) -> &Vec<DecoratedSignature> {
152 &self.signatures
153 }
154}
155
156#[derive(Debug)]
158pub struct TransactionSignaturePayload<'a> {
159 pub network_id: &'a Vec<u8>,
161 pub transaction: &'a Transaction,
163}