Transaction

Struct Transaction 

Source
pub struct Transaction<State: IsTransactionBodyState> { /* private fields */ }
Expand description

A transaction, either under construction or fully signed.

The State captures the current state of the transaction and restricts the methods available based on the state. In practice, a transaction starts in the state::InConstruction using either Self::default or provided in the callback to Self::build.

Then it reaches the state::ReadyForSigning which enables the method Self::sign, and forbid any method that modifies the transaction body.

Note that Self::build is currently the only way by which one can get a transaction in the state::ReadyForSigning.

Implementations§

Source§

impl Transaction<InConstruction>

Source

pub fn build<F>( params: &ProtocolParameters, resolved_inputs: &BTreeMap<Input, Output>, build: F, ) -> Result<Transaction<ReadyForSigning>>
where F: Fn(&mut Self) -> Result<&mut Self>,

Build a transaction by repeatedly executing some building logic with different fee and execution units settings. Stops when a fixed point is reached.

The final transaction has corresponding fees, execution units, collateral return and script integrity hash set.

§notes
  • any input specified in the transaction (either as input, reference input or collateral) must be present in the provided resolved_inputs.
  • with_change_strategy must always be present for there’s no default change strategy.
  • while it is allowed (for whatever reasons), you aren’t expected to fiddle with fees here; this is entirely managed by the build loop.
§examples
§A simple transaction from a single input to a single recipient, with change.
// The available UTxO, typically fetched from a blockchain provider or an indexer.
let resolved_inputs = BTreeMap::from([
  (
    input!("32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c", 1),
    output!(
      "addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47",
      value!(10_000_000),
    ),
  )
]);

// Send a minimum lovelace value to an arbitrary address, and the change back to the
// sender.
assert_eq!(
  Transaction::build(&ProtocolParameters::mainnet(), &resolved_inputs, |tx| tx
    .with_inputs(vec![
      input!("32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c", 1, _),
    ])
    .with_outputs(vec![
      output!("addr1wyhcwt6h7mf6rlaqadmhh5awnyd44t7v4lju5ur430fk4xczzq8aw"),
    ])
    .with_change_strategy(ChangeStrategy::as_last_output(
      address!("addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47"),
    ))
    .ok()
  ).unwrap().to_string(),
  indoc!{"
    Transaction (id = 6f8e53f61fe0a709e1c895c1bd9487e555779de0902ad25377d4de1df48f08b8) {
        inputs: [
            Input(32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c#1),
        ],
        outputs: [
            Output {
                address: addr1wyhcwt6h7mf6rlaqadmhh5awnyd44t7v4lju5ur430fk4xczzq8aw,
                value: Value {
                    lovelace: 857690,
                },
            },
            Output {
                address: addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47,
                value: Value {
                    lovelace: 8976061,
                },
            },
        ],
        fee: 166249,
        validity: ]-∞; +∞[,
    }"
  }
);
§Minting assets using a plutus script.
let resolved_inputs = BTreeMap::from([
  (
    input!("32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c", 1),
    output!(
      "addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47",
      value!(10_000_000),
    ),
  )
]);

// Notice the absence of outputs and of collateral return. We let the builder handler those for us.
assert_eq!(
  Transaction::build(&ProtocolParameters::mainnet(), &resolved_inputs, |tx| tx
    .with_inputs(vec![
      input!("32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c", 1, _),
    ])
    .with_collaterals(vec![
      input!("32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c", 1),
    ])
    .with_change_strategy(ChangeStrategy::as_last_output(
      address!("addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47"),
    ))
    .with_mint(assets!(
      (
        "bd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777",
        "7768617465766572",
        100_i64,
        PlutusData::list::<PlutusData>([]),
      ),
    ))
    .with_validity_interval(SlotBound::None, SlotBound::Exclusive(123456789))
    .with_plutus_scripts(vec![
      plutus_script!(PlutusVersion::V3, "5101010023259800a518a4d136564004ae69")
    ])
    .ok()
  ).unwrap().to_string(),
  indoc!{"
    Transaction (id = 07fbde0af6eaceb28a59f764e442002382181af756707e0ce0325354d2b26fac) {
        inputs: [
            Input(32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c#1),
        ],
        outputs: [
            Output {
                address: addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47,
                value: Value {
                    lovelace: 9824087,
                    assets: {
                        bd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777: {
                            whatever: 100,
                        },
                    },
                },
            },
        ],
        fee: 175913,
        validity: ]-∞; 123456789[,
        mint: Value {
            lovelace: 0,
            assets: {
                bd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777: {
                    whatever: 100,
                },
            },
        },
        script_integrity_hash: b5a66ea46c7628f9b151d6e029f322058d9dff3793a98f3cfed6e21ed7064c4f,
        collaterals: [
            Input(32b5e793d26af181cb837ab7470ba6e10e15ff638088bc6b099bb22b54b4796c#1),
        ],
        collateral_return: Output {
            address: addr1vx7n46v3kk40ejh7tjnswk9ax65m97rj74lk6wsllg8twacak3e47,
            value: Value {
                lovelace: 9736130,
            },
        },
        total_collateral: 263870,
        scripts: [
            v3(bd3ae991b5aafccafe5ca70758bd36a9b2f872f57f6d3a1ffa0eb777),
        ],
        redeemers: {
            Mint(0): Redeemer(
                CBOR(80),
                ExecutionUnits {
                    mem: 1601,
                    cpu: 316149,
                },
            ),
        },
    }"
  },
);
Source§

impl Transaction<InConstruction>

Source

pub fn ok(&mut self) -> Result<&mut Self>

Source

pub fn with_inputs( &mut self, inputs: impl IntoIterator<Item = (Input, Option<PlutusData<'static>>)>, ) -> &mut Self

Source

pub fn with_collaterals( &mut self, collaterals: impl IntoIterator<Item = Input>, ) -> &mut Self

Source

pub fn with_reference_inputs( &mut self, reference_inputs: impl IntoIterator<Item = Input>, ) -> &mut Self

Source

pub fn with_specified_signatories( &mut self, verification_key_hashes: impl IntoIterator<Item = Hash<28>>, ) -> &mut Self

Source

pub fn with_outputs( &mut self, outputs: impl IntoIterator<Item = Output>, ) -> &mut Self

Source

pub fn with_change_strategy(&mut self, with: ChangeStrategy) -> &mut Self

Source

pub fn with_mint( &mut self, mint: BTreeMap<(Hash<28>, PlutusData<'_>), BTreeMap<Vec<u8>, i64>>, ) -> &mut Self

Source

pub fn with_validity_interval( &mut self, from: SlotBound, until: SlotBound, ) -> &mut Self

Source

pub fn with_fee(&mut self, fee: u64) -> &mut Self

Source

pub fn with_datums( &mut self, datums: impl IntoIterator<Item = PlutusData<'static>>, ) -> &mut Self

Source

pub fn with_plutus_scripts( &mut self, scripts: impl IntoIterator<Item = PlutusScript>, ) -> &mut Self

Source§

impl Transaction<ReadyForSigning>

Source

pub fn sign(&mut self, signing_key: &SigningKey) -> &mut Self

Source

pub fn sign_with<VerificationKeyLike: Borrow<VerificationKey>, SignatureLike: Borrow<Signature>>( &mut self, sign: impl FnOnce(Hash<32>) -> (VerificationKeyLike, SignatureLike), ) -> &mut Self

Like ‘sign’, but allows signing through a callback to avoid leaking the signing key.

Source§

impl<State: IsTransactionBodyState> Transaction<State>

Source

pub fn id(&self) -> Hash<32>

The transaction identifier, as a blake2b-256 hash digest of its serialised body.

While the method can be called at any time, any change on the transaction body will alter the id. It is only stable when the state is [`state::ReadyForSigning`]
Source

pub fn fee(&self) -> u64

Source

pub fn total_collateral(&self) -> u64

Source

pub fn inputs(&self) -> Box<dyn Iterator<Item = Input> + '_>

The declared transaction inputs, which are spent in case of successful transaction.

Source

pub fn collaterals(&self) -> Box<dyn Iterator<Item = Input> + '_>

The declared transaction collaterals, which are spent in case of failed transaction.

Source

pub fn reference_inputs(&self) -> Box<dyn Iterator<Item = Input> + '_>

The declared transaction reference inputs, which are never spent but contribute to the script context for smart-contract execution.

Source

pub fn mint(&self) -> Value<i64>

Source

pub fn outputs(&self) -> Box<dyn Iterator<Item = Output> + '_>

The declared transaction outputs, which are produced in case of successful transaction.

Source

pub fn as_resolved_inputs(&self) -> BTreeMap<Input, Output>

View this transaction as a UTxO, mapping each output to its corresponding input reference.

Trait Implementations§

Source§

impl<State: IsTransactionBodyState> Debug for Transaction<State>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'d, C> Decode<'d, C> for Transaction<ReadyForSigning>

Source§

fn decode(d: &mut Decoder<'d>, ctx: &mut C) -> Result<Self, Error>

Decode a value using the given Decoder. Read more
§

fn nil() -> Option<Self>

If possible, return a nil value of Self. Read more
Source§

impl<'d, C> Decode<'d, C> for Transaction<Unknown>

Source§

fn decode(d: &mut Decoder<'d>, ctx: &mut C) -> Result<Self, Error>

Decode a value using the given Decoder. Read more
§

fn nil() -> Option<Self>

If possible, return a nil value of Self. Read more
Source§

impl Default for Transaction<InConstruction>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<State: IsTransactionBodyState> Display for Transaction<State>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C, State: IsTransactionBodyState> Encode<C> for Transaction<State>

Source§

fn encode<W: Write>( &self, e: &mut Encoder<W>, ctx: &mut C, ) -> Result<(), Error<W::Error>>

Encode a value of this type using the given Encoder. Read more
§

fn is_nil(&self) -> bool

Is this value of Self a nil value? Read more

Auto Trait Implementations§

§

impl<State> Freeze for Transaction<State>

§

impl<State> RefUnwindSafe for Transaction<State>

§

impl<State> Send for Transaction<State>
where <State as IsTransactionBodyState>::ChangeStrategy: Send, State: Send,

§

impl<State> Sync for Transaction<State>
where <State as IsTransactionBodyState>::ChangeStrategy: Sync, State: Sync,

§

impl<State> Unpin for Transaction<State>
where <State as IsTransactionBodyState>::ChangeStrategy: Unpin, State: Unpin,

§

impl<State> UnwindSafe for Transaction<State>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
§

impl<'a, T> Fragment<'a> for T
where T: Encode<()> + Decode<'a, ()>,

§

fn encode_fragment(&self) -> Result<Vec<u8>, Box<dyn Error>>

§

fn decode_fragment(bytes: &'a [u8]) -> Result<T, Box<dyn Error>>

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<'d, T> FromCbor<'d> for T
where T: Decode<'d, ()>,

Source§

fn from_cbor(bytes: &'d [u8]) -> Result<T, Error>

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToCbor for T
where T: Encode<()>,

Source§

fn to_cbor(&self) -> Vec<u8>

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Fragment for T
where T: for<'b> Decode<'b, ()> + Encode<()>,