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>
impl Transaction<InConstruction>
Sourcepub fn build<F>(
params: &ProtocolParameters,
resolved_inputs: &BTreeMap<Input, Output>,
build: F,
) -> Result<Transaction<ReadyForSigning>>
pub fn build<F>( params: &ProtocolParameters, resolved_inputs: &BTreeMap<Input, Output>, build: F, ) -> Result<Transaction<ReadyForSigning>>
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_strategymust 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
buildloop.
§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>
impl Transaction<InConstruction>
pub fn ok(&mut self) -> Result<&mut Self>
pub fn with_inputs( &mut self, inputs: impl IntoIterator<Item = (Input, Option<PlutusData<'static>>)>, ) -> &mut Self
pub fn with_collaterals( &mut self, collaterals: impl IntoIterator<Item = Input>, ) -> &mut Self
pub fn with_reference_inputs( &mut self, reference_inputs: impl IntoIterator<Item = Input>, ) -> &mut Self
pub fn with_specified_signatories( &mut self, verification_key_hashes: impl IntoIterator<Item = Hash<28>>, ) -> &mut Self
pub fn with_outputs( &mut self, outputs: impl IntoIterator<Item = Output>, ) -> &mut Self
pub fn with_change_strategy(&mut self, with: ChangeStrategy) -> &mut Self
pub fn with_mint( &mut self, mint: BTreeMap<(Hash<28>, PlutusData<'_>), BTreeMap<Vec<u8>, i64>>, ) -> &mut Self
pub fn with_validity_interval( &mut self, from: SlotBound, until: SlotBound, ) -> &mut Self
pub fn with_fee(&mut self, fee: u64) -> &mut Self
pub fn with_datums( &mut self, datums: impl IntoIterator<Item = PlutusData<'static>>, ) -> &mut Self
pub fn with_plutus_scripts( &mut self, scripts: impl IntoIterator<Item = PlutusScript>, ) -> &mut Self
Source§impl Transaction<ReadyForSigning>
impl Transaction<ReadyForSigning>
pub fn sign(&mut self, signing_key: &SigningKey) -> &mut Self
Sourcepub fn sign_with<VerificationKeyLike: Borrow<VerificationKey>, SignatureLike: Borrow<Signature>>(
&mut self,
sign: impl FnOnce(Hash<32>) -> (VerificationKeyLike, SignatureLike),
) -> &mut Self
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>
impl<State: IsTransactionBodyState> Transaction<State>
Sourcepub fn id(&self) -> Hash<32>
pub fn id(&self) -> Hash<32>
The transaction identifier, as a blake2b-256 hash digest of its serialised body.
pub fn fee(&self) -> u64
pub fn total_collateral(&self) -> u64
Sourcepub fn inputs(&self) -> Box<dyn Iterator<Item = Input> + '_>
pub fn inputs(&self) -> Box<dyn Iterator<Item = Input> + '_>
The declared transaction inputs, which are spent in case of successful transaction.
Sourcepub fn collaterals(&self) -> Box<dyn Iterator<Item = Input> + '_>
pub fn collaterals(&self) -> Box<dyn Iterator<Item = Input> + '_>
The declared transaction collaterals, which are spent in case of failed transaction.
Sourcepub fn reference_inputs(&self) -> Box<dyn Iterator<Item = Input> + '_>
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.
pub fn mint(&self) -> Value<i64>
Sourcepub fn outputs(&self) -> Box<dyn Iterator<Item = Output> + '_>
pub fn outputs(&self) -> Box<dyn Iterator<Item = Output> + '_>
The declared transaction outputs, which are produced in case of successful transaction.
Sourcepub fn as_resolved_inputs(&self) -> BTreeMap<Input, Output>
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>
impl<State: IsTransactionBodyState> Debug for Transaction<State>
Source§impl<'d, C> Decode<'d, C> for Transaction<ReadyForSigning>
impl<'d, C> Decode<'d, C> for Transaction<ReadyForSigning>
Source§impl<'d, C> Decode<'d, C> for Transaction<Unknown>
impl<'d, C> Decode<'d, C> for Transaction<Unknown>
Source§impl Default for Transaction<InConstruction>
impl Default for Transaction<InConstruction>
Source§impl<State: IsTransactionBodyState> Display for Transaction<State>
impl<State: IsTransactionBodyState> Display for Transaction<State>
Source§impl<C, State: IsTransactionBodyState> Encode<C> for Transaction<State>
impl<C, State: IsTransactionBodyState> Encode<C> for Transaction<State>
Auto Trait Implementations§
impl<State> Freeze for Transaction<State>
impl<State> RefUnwindSafe for Transaction<State>
impl<State> Send for Transaction<State>
impl<State> Sync for Transaction<State>
impl<State> Unpin for Transaction<State>
impl<State> UnwindSafe for Transaction<State>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<'a, T> Fragment<'a> for T
impl<'a, T> Fragment<'a> for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
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) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
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
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
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
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
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
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.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
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.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
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.