1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
use std::io::Write; use digest::Digest; use crate::{ hashes::{DigestOutput, MarkedDigest, MarkedDigestOutput}, ser::{ByteFormat, SerError}, }; /// A `TxoIdentifier` represents the network's unique identifier an output. In Bitcoin this is an /// outpoint. pub trait TxoIdentifier {} /// An `Input` spends a specific TXO, and typically contains a `TxoIdentifier` for that TXO. pub trait Input { /// An input must define what type contains the TXO ID it is spending. type TxoIdentifier: TxoIdentifier; } /// A RecipientIdentifier represents the network's identifier for a recipient. In Bitcoin this is /// a `ScriptPubkey`. pub trait RecipientIdentifier {} /// An Output represents a new TXO being created. It has an associated `RecipientIdentifier`. pub trait Output { /// How is value represented in this Output? For Bitcoin this is a u64. type Value; /// The associated `RecipientIdentifier` type that describes to whom the output is paid. /// For Bitcoin, this is a `ScriptPubkey` type RecipientIdentifier: RecipientIdentifier; } /// Basic functionality for a Transaction /// /// This trait has been generalized to support transactions from Non-Bitcoin networks. The /// transaction specificies which types it considers to be inputs and outputs, and a struct that /// contains its Sighash arguments. This allows others to define custom transaction types with /// unique functionality. pub trait Transaction: ByteFormat { /// An associated error type, used in Results returned by the Transaction. type TxError: From<SerError> + From<<Self as ByteFormat>::Error>; /// The Input type for the transaction type TxIn: Input; /// The Output type for the transaction type TxOut: Output; /// A type describing arguments for the sighash function for this transaction. type SighashArgs; /// A marked hash (see crate::hashes::marked) to be used as the transaction ID type. type TXID: MarkedDigestOutput; /// A type that implements `HashWriter`. Used to generate the `TXID` and `Sighash`. type HashWriter: MarkedDigest<Self::TXID>; /// Instantiate a new Transaction by specifying inputs and outputs. fn new<I, O>(version: u32, vin: I, vout: O, locktime: u32) -> Result<Self, Self::TxError> where I: Into<Vec<Self::TxIn>>, O: Into<Vec<Self::TxOut>>, Self: Sized; /// Returns the transaction version number fn version(&self) -> u32; /// Returns a reference to the transaction input vector fn inputs(&self) -> &[Self::TxIn]; /// Returns a reference the the transaction output vector fn outputs(&self) -> &[Self::TxOut]; /// Returns the transaction's nLocktime field fn locktime(&self) -> u32; /// Calculates and returns the transaction's ID. The default TXID is simply the digest of the /// serialized transaction. fn txid(&self) -> Self::TXID { let mut w = Self::HashWriter::default(); self.write_to(&mut w) .expect("No IOError from hash functions"); w.finalize_marked() } /// Generate the digest that must be signed to authorize inputs. For Bitcoin transactions /// this is a function of the transaction, and the input's prevout. /// /// # Note: /// /// For Bitcoin, this will write the DEFAULT sighash for the current transaction type. For /// witness transactions, that is the BIP143 sighash. When signing Legacy inputs included in a /// witness transaction, use `write_legacy_sighash_preimage` instead. fn write_sighash_preimage<W: Write>( &self, writer: &mut W, _args: &Self::SighashArgs, ) -> Result<(), Self::TxError>; /// Calls `write_sighash_preimage` with the provided arguments and a new HashWriter. /// Returns the sighash digest which should be signed. fn sighash( &self, args: &Self::SighashArgs, ) -> Result<DigestOutput<Self::HashWriter>, Self::TxError> { let mut w = Self::HashWriter::default(); self.write_sighash_preimage(&mut w, args)?; Ok(w.finalize()) } }