iota_sdk_types/transaction/
mod.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2025 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use super::{
6    Address, CheckpointTimestamp, Digest, EpochId, Event, GenesisObject, Identifier, Jwk, JwkId,
7    ObjectId, ObjectReference, ProtocolVersion, TypeTag, UserSignature, Version,
8};
9
10#[cfg(feature = "serde")]
11#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
12mod serialization;
13#[cfg(feature = "serde")]
14#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
15pub(crate) use serialization::SignedTransactionWithIntentMessage;
16
17/// Transaction
18///
19/// # BCS
20///
21/// The BCS serialized form for this type is defined by the following ABNF:
22///
23/// ```text
24/// transaction = %x00 transaction-v1
25///
26/// transaction-v1 = transaction-kind address gas-payment transaction-expiration
27/// ```
28#[derive(Clone, Debug, PartialEq, Eq)]
29#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
30#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub enum Transaction {
33    #[cfg_attr(feature = "serde", serde(rename = "1"))]
34    V1(TransactionV1),
35    // When new variants are introduced, it is important that we check version support
36    // in the validity_check function based on the protocol config.
37}
38
39impl Transaction {
40    crate::def_is_as_into_opt!(V1(TransactionV1));
41}
42
43impl From<TransactionV1> for Transaction {
44    fn from(v1: TransactionV1) -> Self {
45        Transaction::V1(v1)
46    }
47}
48
49#[derive(Debug, PartialEq, Eq, Clone)]
50#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
51#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
52#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
53pub struct TransactionV1 {
54    pub kind: TransactionKind,
55    pub sender: Address,
56    pub gas_payment: GasPayment,
57    pub expiration: TransactionExpiration,
58}
59
60#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
61pub struct SenderSignedTransaction(
62    #[cfg_attr(
63        feature = "serde",
64        serde(with = "::serde_with::As::<crate::_serde::SignedTransactionWithIntentMessage>")
65    )]
66    pub SignedTransaction,
67);
68
69#[derive(Clone, Debug, PartialEq, Eq)]
70#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
71#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
72#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
73pub struct SignedTransaction {
74    pub transaction: Transaction,
75    pub signatures: Vec<UserSignature>,
76}
77
78/// A TTL for a transaction
79///
80/// # BCS
81///
82/// The BCS serialized form for this type is defined by the following ABNF:
83///
84/// ```text
85/// transaction-expiration =  %x00      ; none
86///                        =/ %x01 u64  ; epoch
87/// ```
88#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Hash)]
89#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
90pub enum TransactionExpiration {
91    /// The transaction has no expiration
92    #[default]
93    None,
94    /// Validators wont sign a transaction unless the expiration Epoch
95    /// is greater than or equal to the current epoch
96    Epoch(EpochId),
97}
98
99impl TransactionExpiration {
100    crate::def_is!(None);
101
102    crate::def_is_as_into_opt!(Epoch(EpochId));
103}
104
105/// Payment information for executing a transaction
106///
107/// # BCS
108///
109/// The BCS serialized form for this type is defined by the following ABNF:
110///
111/// ```text
112/// gas-payment = (vector object-ref) ; gas coin objects
113///               address             ; owner
114///               u64                 ; price
115///               u64                 ; budget
116/// ```
117#[derive(Clone, Debug, PartialEq, Eq)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
120#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
121pub struct GasPayment {
122    pub objects: Vec<ObjectReference>,
123    /// Owner of the gas objects, either the transaction sender or a sponsor
124    pub owner: Address,
125    /// Gas unit price to use when charging for computation
126    ///
127    /// Must be greater-than-or-equal-to the network's current RGP (reference
128    /// gas price)
129    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
130    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
131    pub price: u64,
132    /// Total budget willing to spend for the execution of a transaction
133    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
134    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
135    pub budget: u64,
136}
137
138/// Randomness update
139///
140/// # BCS
141///
142/// The BCS serialized form for this type is defined by the following ABNF:
143///
144/// ```text
145/// randomness-state-update = u64 u64 bytes u64
146/// ```
147#[derive(Clone, Debug, PartialEq, Eq)]
148#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
149#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
150#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
151pub struct RandomnessStateUpdate {
152    /// Epoch of the randomness state update transaction
153    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
154    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
155    pub epoch: u64,
156    /// Randomness round of the update
157    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
158    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
159    pub randomness_round: u64,
160    /// Updated random bytes
161    #[cfg_attr(
162        feature = "serde",
163        serde(with = "crate::_serde::ReadableBase64Encoded")
164    )]
165    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::Base64"))]
166    pub random_bytes: Vec<u8>,
167    /// The initial version of the randomness object that it was shared at.
168    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
169    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
170    pub randomness_obj_initial_shared_version: u64,
171}
172
173/// Transaction type
174///
175/// # BCS
176///
177/// The BCS serialized form for this type is defined by the following ABNF:
178///
179/// ```text
180/// transaction-kind    =  %x00 ptb
181///                     =/ %x01 change-epoch
182///                     =/ %x02 genesis-transaction
183///                     =/ %x03 consensus-commit-prologue
184///                     =/ %x04 authenticator-state-update
185///                     =/ %x05 (vector end-of-epoch-transaction-kind)
186///                     =/ %x06 randomness-state-update
187///                     =/ %x07 consensus-commit-prologue-v2
188///                     =/ %x08 consensus-commit-prologue-v3
189/// ```
190#[derive(Clone, Debug, PartialEq, Eq)]
191#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
192pub enum TransactionKind {
193    /// A user transaction comprised of a list of native commands and move calls
194    ProgrammableTransaction(ProgrammableTransaction),
195    /// Transaction used to initialize the chain state.
196    ///
197    /// Only valid if in the genesis checkpoint (0) and if this is the very
198    /// first transaction ever executed on the chain.
199    Genesis(GenesisTransaction),
200    /// V1 consensus commit update
201    ConsensusCommitPrologueV1(ConsensusCommitPrologueV1),
202    /// Update set of valid JWKs used for zklogin
203    AuthenticatorStateUpdateV1(AuthenticatorStateUpdateV1),
204    /// Set of operations to run at the end of the epoch to close out the
205    /// current epoch and start the next one.
206    EndOfEpoch(Vec<EndOfEpochTransactionKind>),
207    /// Randomness update
208    RandomnessStateUpdate(RandomnessStateUpdate),
209}
210
211impl TransactionKind {
212    crate::def_is_as_into_opt! {
213        ProgrammableTransaction,
214        ConsensusCommitPrologueV1,
215        AuthenticatorStateUpdateV1,
216        RandomnessStateUpdate,
217    }
218
219    crate::def_is_as_into_opt! {
220        Genesis(GenesisTransaction),
221        EndOfEpoch(Vec<EndOfEpochTransactionKind>),
222    }
223}
224
225/// Operation run at the end of an epoch
226///
227/// # BCS
228///
229/// The BCS serialized form for this type is defined by the following ABNF:
230///
231/// ```text
232/// end-of-epoch-transaction-kind   =  eoe-change-epoch
233///                                 =/ eoe-authenticator-state-create
234///                                 =/ eoe-authenticator-state-expire
235///                                 =/ eoe-randomness-state-create
236///                                 =/ eoe-deny-list-state-create
237///                                 =/ eoe-bridge-state-create
238///                                 =/ eoe-bridge-committee-init
239///                                 =/ eoe-store-execution-time-observations
240///
241/// eoe-change-epoch                = %x00 change-epoch
242/// eoe-authenticator-state-create  = %x01
243/// eoe-authenticator-state-expire  = %x02 authenticator-state-expire
244/// eoe-randomness-state-create     = %x03
245/// eoe-deny-list-state-create      = %x04
246/// eoe-bridge-state-create         = %x05 digest
247/// eoe-bridge-committee-init       = %x06 u64
248/// eoe-store-execution-time-observations = %x07 stored-execution-time-observations
249/// ```
250#[derive(Clone, Debug, PartialEq, Eq)]
251#[cfg_attr(
252    feature = "schemars",
253    derive(schemars::JsonSchema),
254    schemars(tag = "kind", rename_all = "snake_case")
255)]
256#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
257pub enum EndOfEpochTransactionKind {
258    /// End the epoch and start the next one
259    ChangeEpoch(ChangeEpoch),
260    /// End the epoch and start the next one
261    ChangeEpochV2(ChangeEpochV2),
262    /// End the epoch and start the next one
263    ChangeEpochV3(ChangeEpochV3),
264    /// Create and initialize the authenticator object used for zklogin
265    AuthenticatorStateCreate,
266    /// Expire JWKs used for zklogin
267    AuthenticatorStateExpire(AuthenticatorStateExpire),
268}
269
270impl EndOfEpochTransactionKind {
271    crate::def_is!(AuthenticatorStateCreate);
272
273    crate::def_is_as_into_opt!(ChangeEpoch, ChangeEpochV2, AuthenticatorStateExpire);
274}
275
276/// Set of Execution Time Observations from the committee.
277///
278/// # BCS
279///
280/// The BCS serialized form for this type is defined by the following ABNF:
281///
282/// ```text
283/// stored-execution-time-observations =  %x00 v1-stored-execution-time-observations
284///
285/// v1-stored-execution-time-observations = (vec
286///                                          execution-time-observation-key
287///                                          (vec execution-time-observation)
288///                                         )
289/// ```
290#[derive(Debug, Hash, PartialEq, Eq, Clone)]
291#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
292#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
293#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
294pub enum ExecutionTimeObservations {
295    V1(Vec<ExecutionTimeObservation>),
296}
297
298impl ExecutionTimeObservations {
299    crate::def_is_as_into_opt!(V1(Vec<ExecutionTimeObservation>));
300}
301
302#[derive(Debug, Hash, PartialEq, Eq, Clone)]
303#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
304#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
305#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
306pub struct ExecutionTimeObservation {
307    pub key: ExecutionTimeObservationKey,
308    pub observations: Vec<ValidatorExecutionTimeObservation>,
309}
310
311/// An execution time observation from a particular validator
312///
313/// # BCS
314///
315/// The BCS serialized form for this type is defined by the following ABNF:
316///
317/// ```text
318/// execution-time-observation = bls-public-key duration
319/// duration =  u64 ; seconds
320///             u32 ; subsecond nanoseconds
321/// ```
322#[derive(Debug, Hash, PartialEq, Eq, Clone)]
323#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
324#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
325#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
326pub struct ValidatorExecutionTimeObservation {
327    pub validator: crate::Bls12381PublicKey,
328    pub duration: std::time::Duration,
329}
330
331/// Key for an execution time observation
332///
333/// # BCS
334///
335/// The BCS serialized form for this type is defined by the following ABNF:
336///
337/// ```text
338/// execution-time-observation-key  =  %x00 move-entry-point
339///                                 =/ %x01 ; transfer-objects
340///                                 =/ %x02 ; split-coins
341///                                 =/ %x03 ; merge-coins
342///                                 =/ %x04 ; publish
343///                                 =/ %x05 ; make-move-vec
344///                                 =/ %x06 ; upgrade
345///
346/// move-entry-point = object-id string string (vec type-tag)
347/// ```
348#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
349#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
350#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
351#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
352pub enum ExecutionTimeObservationKey {
353    // Contains all the fields from `ProgrammableMoveCall` besides `arguments`.
354    MoveEntryPoint {
355        /// The package containing the module and function.
356        package: ObjectId,
357        /// The specific module in the package containing the function.
358        module: String,
359        /// The function to be called.
360        function: String,
361        /// The type arguments to the function.
362        /// NOTE: This field is currently not populated.
363        type_arguments: Vec<TypeTag>,
364    },
365    TransferObjects,
366    SplitCoins,
367    MergeCoins,
368    Publish, // special case: should not be used; we only use hard-coded estimate for this
369    MakeMoveVec,
370    Upgrade,
371}
372
373impl ExecutionTimeObservationKey {
374    crate::def_is!(
375        MoveEntryPoint,
376        TransferObjects,
377        SplitCoins,
378        MergeCoins,
379        Publish,
380        MakeMoveVec,
381        Upgrade,
382    );
383}
384
385/// Expire old JWKs
386///
387/// # BCS
388///
389/// The BCS serialized form for this type is defined by the following ABNF:
390///
391/// ```text
392/// authenticator-state-expire = u64 u64
393/// ```
394#[derive(Clone, Debug, PartialEq, Eq)]
395#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
396#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
397#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
398pub struct AuthenticatorStateExpire {
399    /// expire JWKs that have a lower epoch than this
400    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
401    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
402    pub min_epoch: u64,
403    /// The initial version of the authenticator object that it was shared at.
404    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
405    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
406    pub authenticator_obj_initial_shared_version: u64,
407}
408
409/// Update the set of valid JWKs
410///
411/// # BCS
412///
413/// The BCS serialized form for this type is defined by the following ABNF:
414///
415/// ```text
416/// authenticator-state-update = u64 ; epoch
417///                              u64 ; round
418///                              (vector active-jwk)
419///                              u64 ; initial version of the authenticator object
420/// ```
421#[derive(Clone, Debug, PartialEq, Eq)]
422#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
423#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
424#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
425pub struct AuthenticatorStateUpdateV1 {
426    /// Epoch of the authenticator state update transaction
427    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
428    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
429    pub epoch: u64,
430    /// Consensus round of the authenticator state update
431    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
432    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
433    pub round: u64,
434    /// newly active jwks
435    pub new_active_jwks: Vec<ActiveJwk>,
436    /// The initial version of the authenticator object that it was shared at.
437    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
438    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
439    pub authenticator_obj_initial_shared_version: u64,
440}
441
442/// A new Jwk
443///
444/// # BCS
445///
446/// The BCS serialized form for this type is defined by the following ABNF:
447///
448/// ```text
449/// active-jwk = jwk-id jwk u64
450/// ```
451#[derive(Clone, Debug, PartialEq, Eq)]
452#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
453#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
454#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
455pub struct ActiveJwk {
456    /// Identifier used to uniquely identify a Jwk
457    pub jwk_id: JwkId,
458    /// The Jwk
459    pub jwk: Jwk,
460    /// Most recent epoch in which the jwk was validated
461    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
462    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
463    pub epoch: u64,
464}
465
466#[derive(Clone, Debug, PartialEq, Eq)]
467#[cfg_attr(
468    feature = "schemars",
469    derive(schemars::JsonSchema),
470    schemars(tag = "kind", rename_all = "snake_case")
471)]
472#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
473pub enum ConsensusDeterminedVersionAssignments {
474    /// Cancelled transaction version assignment.
475    CancelledTransactions {
476        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
477        cancelled_transactions: Vec<CancelledTransaction>,
478    },
479}
480
481impl ConsensusDeterminedVersionAssignments {
482    crate::def_is!(CancelledTransactions);
483
484    pub fn as_cancelled_transactions(&self) -> &[CancelledTransaction] {
485        let Self::CancelledTransactions {
486            cancelled_transactions,
487        } = self;
488        cancelled_transactions
489    }
490}
491
492/// A transaction that was cancelled
493///
494/// # BCS
495///
496/// The BCS serialized form for this type is defined by the following ABNF:
497///
498/// ```text
499/// cancelled-transaction = digest (vector version-assignment)
500/// ```
501#[derive(Clone, Debug, PartialEq, Eq)]
502#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
503#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
504#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
505pub struct CancelledTransaction {
506    pub digest: Digest,
507    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
508    pub version_assignments: Vec<VersionAssignment>,
509}
510
511/// Object version assignment from consensus
512///
513/// # BCS
514///
515/// The BCS serialized form for this type is defined by the following ABNF:
516///
517/// ```text
518/// version-assignment = object-id u64
519/// ```
520#[derive(Clone, Debug, PartialEq, Eq)]
521#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
522#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
523#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
524pub struct VersionAssignment {
525    pub object_id: ObjectId,
526    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
527    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
528    pub version: Version,
529}
530
531/// V1 of the consensus commit prologue system transaction
532///
533/// # BCS
534///
535/// The BCS serialized form for this type is defined by the following ABNF:
536///
537/// ```text
538/// consensus-commit-prologue-v1 = u64 u64 (option u64) u64 digest
539///                                consensus-determined-version-assignments
540/// ```
541#[derive(Clone, Debug, PartialEq, Eq)]
542#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
543#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
544#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
545pub struct ConsensusCommitPrologueV1 {
546    /// Epoch of the commit prologue transaction
547    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
548    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
549    pub epoch: u64,
550    /// Consensus round of the commit
551    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
552    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
553    pub round: u64,
554    /// The sub DAG index of the consensus commit. This field will be populated
555    /// if there are multiple consensus commits per round.
556    #[cfg_attr(
557        feature = "serde",
558        serde(with = "crate::_serde::OptionReadableDisplay")
559    )]
560    #[cfg_attr(feature = "schemars", schemars(with = "Option<crate::_schemars::U64>"))]
561    pub sub_dag_index: Option<u64>,
562    /// Unix timestamp from consensus
563    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
564    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
565    pub commit_timestamp_ms: CheckpointTimestamp,
566    /// Digest of consensus output
567    pub consensus_commit_digest: Digest,
568    /// Stores consensus handler determined shared object version assignments.
569    pub consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments,
570}
571
572/// System transaction used to change the epoch
573///
574/// # BCS
575///
576/// The BCS serialized form for this type is defined by the following ABNF:
577///
578/// ```text
579/// change-epoch = u64  ; next epoch
580///                u64  ; protocol version
581///                u64  ; storage charge
582///                u64  ; computation charge
583///                u64  ; storage rebate
584///                u64  ; non-refundable storage fee
585///                u64  ; epoch start timestamp
586///                (vector system-package)
587/// ```
588#[derive(Clone, Debug, PartialEq, Eq)]
589#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
590#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
591#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
592pub struct ChangeEpoch {
593    /// The next (to become) epoch ID.
594    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
595    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
596    pub epoch: EpochId,
597    /// The protocol version in effect in the new epoch.
598    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
599    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
600    pub protocol_version: ProtocolVersion,
601    /// The total amount of gas charged for storage during the epoch.
602    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
603    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
604    pub storage_charge: u64,
605    /// The total amount of gas charged for computation during the epoch.
606    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
607    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
608    pub computation_charge: u64,
609    /// The amount of storage rebate refunded to the txn senders.
610    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
611    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
612    pub storage_rebate: u64,
613    /// The non-refundable storage fee.
614    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
615    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
616    pub non_refundable_storage_fee: u64,
617    /// Unix timestamp when epoch started
618    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
619    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
620    pub epoch_start_timestamp_ms: u64,
621    /// System packages (specifically framework and move stdlib) that are
622    /// written before the new epoch starts. This tracks framework upgrades
623    /// on chain. When executing the ChangeEpoch txn, the validator must
624    /// write out the modules below.  Modules are provided with the version they
625    /// will be upgraded to, their modules in serialized form (which include
626    /// their package ID), and a list of their transitive dependencies.
627    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
628    pub system_packages: Vec<SystemPackage>,
629}
630
631/// System transaction used to change the epoch
632///
633/// # BCS
634///
635/// The BCS serialized form for this type is defined by the following ABNF:
636///
637/// ```text
638/// change-epoch = u64  ; next epoch
639///                u64  ; protocol version
640///                u64  ; storage charge
641///                u64  ; computation charge
642///                u64  ; computation charge burned
643///                u64  ; storage rebate
644///                u64  ; non-refundable storage fee
645///                u64  ; epoch start timestamp
646///                (vector system-package)
647/// ```
648#[derive(Clone, Debug, PartialEq, Eq)]
649#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
650#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
651#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
652pub struct ChangeEpochV2 {
653    /// The next (to become) epoch ID.
654    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
655    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
656    pub epoch: EpochId,
657    /// The protocol version in effect in the new epoch.
658    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
659    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
660    pub protocol_version: ProtocolVersion,
661    /// The total amount of gas charged for storage during the epoch.
662    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
663    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
664    pub storage_charge: u64,
665    /// The total amount of gas charged for computation during the epoch.
666    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
667    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
668    pub computation_charge: u64,
669    /// The total amount of gas burned for computation during the epoch.
670    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
671    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
672    pub computation_charge_burned: u64,
673    /// The amount of storage rebate refunded to the txn senders.
674    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
675    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
676    pub storage_rebate: u64,
677    /// The non-refundable storage fee.
678    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
679    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
680    pub non_refundable_storage_fee: u64,
681    /// Unix timestamp when epoch started
682    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
683    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
684    pub epoch_start_timestamp_ms: u64,
685    /// System packages (specifically framework and move stdlib) that are
686    /// written before the new epoch starts. This tracks framework upgrades
687    /// on chain. When executing the ChangeEpoch txn, the validator must
688    /// write out the modules below.  Modules are provided with the version they
689    /// will be upgraded to, their modules in serialized form (which include
690    /// their package ID), and a list of their transitive dependencies.
691    #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))]
692    pub system_packages: Vec<SystemPackage>,
693}
694
695#[derive(Clone, Debug, PartialEq, Eq)]
696#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
697#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
698#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
699pub struct ChangeEpochV3 {
700    /// The next (to become) epoch ID.
701    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
702    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
703    pub epoch: EpochId,
704    /// The protocol version in effect in the new epoch.
705    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
706    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
707    pub protocol_version: ProtocolVersion,
708    /// The total amount of gas charged for storage during the epoch.
709    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
710    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
711    pub storage_charge: u64,
712    /// The total amount of gas charged for computation during the epoch.
713    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
714    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
715    pub computation_charge: u64,
716    /// The total amount of gas burned for computation during the epoch.
717    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
718    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
719    pub computation_charge_burned: u64,
720    /// The amount of storage rebate refunded to the txn senders.
721    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
722    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
723    pub storage_rebate: u64,
724    /// The non-refundable storage fee.
725    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
726    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
727    pub non_refundable_storage_fee: u64,
728    /// Unix timestamp when epoch started
729    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
730    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
731    pub epoch_start_timestamp_ms: u64,
732    /// System packages (specifically framework and move stdlib) that are
733    /// written before the new epoch starts. This tracks framework upgrades
734    /// on chain. When executing the ChangeEpoch txn, the validator must
735    /// write out the modules below.  Modules are provided with the version they
736    /// will be upgraded to, their modules in serialized form (which include
737    /// their package ID), and a list of their transitive dependencies.
738    #[cfg_attr(test, any(proptest::collection::size_range(0..=2).lift()))]
739    pub system_packages: Vec<SystemPackage>,
740    /// Vector of active validator indices eligible to take part in committee
741    /// selection because they support the new, target protocol version.
742    pub eligible_active_validators: Vec<u64>,
743}
744
745#[derive(Clone, Debug, PartialEq, Eq)]
746#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
747#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
748#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
749pub struct SystemPackage {
750    #[cfg_attr(feature = "serde", serde(with = "crate::_serde::ReadableDisplay"))]
751    #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
752    pub version: Version,
753    #[cfg_attr(
754        feature = "serde",
755        serde(
756            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
757        )
758    )]
759    #[cfg_attr(feature = "schemars", schemars(with = "Vec<crate::_schemars::Base64>"))]
760    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
761    pub modules: Vec<Vec<u8>>,
762    pub dependencies: Vec<ObjectId>,
763}
764
765/// The genesis transaction
766///
767/// # BCS
768///
769/// The BCS serialized form for this type is defined by the following ABNF:
770///
771/// ```text
772/// genesis-transaction = (vector genesis-object)
773/// ```
774#[derive(Clone, Debug, PartialEq, Eq)]
775#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
776#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
777#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
778pub struct GenesisTransaction {
779    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
780    pub objects: Vec<GenesisObject>,
781    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=10).lift()))]
782    pub events: Vec<Event>,
783}
784
785/// A user transaction
786///
787/// Contains a series of native commands and move calls where the results of one
788/// command can be used in future commands.
789///
790/// # BCS
791///
792/// The BCS serialized form for this type is defined by the following ABNF:
793///
794/// ```text
795/// ptb = (vector input) (vector command)
796/// ```
797#[derive(Clone, Debug, PartialEq, Eq)]
798#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
799#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
800#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
801pub struct ProgrammableTransaction {
802    /// Input objects or primitive values
803    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=10).lift()))]
804    pub inputs: Vec<Input>,
805    /// The commands to be executed sequentially. A failure in any command will
806    /// result in the failure of the entire transaction.
807    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=10).lift()))]
808    pub commands: Vec<Command>,
809}
810
811/// An input to a user transaction
812///
813/// # BCS
814///
815/// The BCS serialized form for this type is defined by the following ABNF:
816///
817/// ```text
818/// input = input-pure / input-immutable-or-owned / input-shared / input-receiving
819///
820/// input-pure                  = %x00 bytes
821/// input-immutable-or-owned    = %x01 object-ref
822/// input-shared                = %x02 object-id u64 bool
823/// input-receiving             = %x04 object-ref
824/// ```
825#[derive(Clone, Debug, PartialEq, Eq, Hash)]
826#[cfg_attr(
827    feature = "schemars",
828    derive(schemars::JsonSchema),
829    schemars(tag = "type", rename_all = "snake_case")
830)]
831#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
832pub enum Input {
833    /// A move value serialized as BCS.
834    ///
835    /// For normal operations this is required to be a move primitive type and
836    /// not contain structs or objects.
837    Pure {
838        #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::Base64"))]
839        value: Vec<u8>,
840    },
841    /// A move object that is either immutable or address owned
842    ImmutableOrOwned(ObjectReference),
843    /// A move object whose owner is "Shared"
844    Shared {
845        object_id: ObjectId,
846        #[cfg_attr(feature = "schemars", schemars(with = "crate::_schemars::U64"))]
847        initial_shared_version: u64,
848        /// Controls whether the caller asks for a mutable reference to the
849        /// shared object.
850        mutable: bool,
851    },
852    /// A move object that is attempted to be received in this transaction.
853    // TODO add discussion around what receiving is
854    Receiving(ObjectReference),
855}
856
857impl Input {
858    crate::def_is!(Pure, Shared);
859
860    crate::def_is_as_into_opt!(
861        ImmutableOrOwned(ObjectReference),
862        Receiving(ObjectReference)
863    );
864}
865
866/// A single command in a programmable transaction.
867///
868/// # BCS
869///
870/// The BCS serialized form for this type is defined by the following ABNF:
871///
872/// ```text
873/// command =  command-move-call
874///         =/ command-transfer-objects
875///         =/ command-split-coins
876///         =/ command-merge-coins
877///         =/ command-publish
878///         =/ command-make-move-vector
879///         =/ command-upgrade
880///
881/// command-move-call           = %x00 move-call
882/// command-transfer-objects    = %x01 transfer-objects
883/// command-split-coins         = %x02 split-coins
884/// command-merge-coins         = %x03 merge-coins
885/// command-publish             = %x04 publish
886/// command-make-move-vector    = %x05 make-move-vector
887/// command-upgrade             = %x06 upgrade
888/// ```
889#[derive(Clone, Debug, PartialEq, Eq)]
890#[cfg_attr(
891    feature = "schemars",
892    derive(schemars::JsonSchema),
893    schemars(tag = "command", rename_all = "snake_case")
894)]
895#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
896pub enum Command {
897    /// A call to either an entry or a public Move function
898    MoveCall(MoveCall),
899    /// `(Vec<forall T:key+store. T>, address)`
900    /// It sends n-objects to the specified address. These objects must have
901    /// store (public transfer) and either the previous owner must be an
902    /// address or the object must be newly created.
903    TransferObjects(TransferObjects),
904    /// `(&mut Coin<T>, Vec<u64>)` -> `Vec<Coin<T>>`
905    /// It splits off some amounts into a new coins with those amounts
906    SplitCoins(SplitCoins),
907    /// `(&mut Coin<T>, Vec<Coin<T>>)`
908    /// It merges n-coins into the first coin
909    MergeCoins(MergeCoins),
910    /// Publishes a Move package. It takes the package bytes and a list of the
911    /// package's transitive dependencies to link against on-chain.
912    Publish(Publish),
913    /// `forall T: Vec<T> -> vector<T>`
914    /// Given n-values of the same type, it constructs a vector. For non objects
915    /// or an empty vector, the type tag must be specified.
916    MakeMoveVector(MakeMoveVector),
917    /// Upgrades a Move package
918    /// Takes (in order):
919    /// 1. A vector of serialized modules for the package.
920    /// 2. A vector of object ids for the transitive dependencies of the new
921    ///    package.
922    /// 3. The object ID of the package being upgraded.
923    /// 4. An argument holding the `UpgradeTicket` that must have been produced
924    ///    from an earlier command in the same programmable transaction.
925    Upgrade(Upgrade),
926}
927
928impl Command {
929    crate::def_is_as_into_opt!(
930        MoveCall,
931        TransferObjects,
932        SplitCoins,
933        MergeCoins,
934        Publish,
935        MakeMoveVector,
936        Upgrade,
937    );
938}
939
940/// Command to transfer ownership of a set of objects to an address
941///
942/// # BCS
943///
944/// The BCS serialized form for this type is defined by the following ABNF:
945///
946/// ```text
947/// transfer-objects = (vector argument) argument
948/// ```
949#[derive(Clone, Debug, PartialEq, Eq)]
950#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
951#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
952#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
953pub struct TransferObjects {
954    /// Set of objects to transfer
955    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
956    pub objects: Vec<Argument>,
957    /// The address to transfer ownership to
958    pub address: Argument,
959}
960
961/// Command to split a single coin object into multiple coins
962///
963/// # BCS
964///
965/// The BCS serialized form for this type is defined by the following ABNF:
966///
967/// ```text
968/// split-coins = argument (vector argument)
969/// ```
970#[derive(Clone, Debug, PartialEq, Eq)]
971#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
972#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
973#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
974pub struct SplitCoins {
975    /// The coin to split
976    pub coin: Argument,
977    /// The amounts to split off
978    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
979    pub amounts: Vec<Argument>,
980}
981
982/// Command to merge multiple coins of the same type into a single coin
983///
984/// # BCS
985///
986/// The BCS serialized form for this type is defined by the following ABNF:
987///
988/// ```text
989/// merge-coins = argument (vector argument)
990/// ```
991#[derive(Clone, Debug, PartialEq, Eq)]
992#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
993#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
994#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
995pub struct MergeCoins {
996    /// Coin to merge coins into
997    pub coin: Argument,
998    /// Set of coins to merge into `coin`
999    ///
1000    /// All listed coins must be of the same type and be the same type as `coin`
1001    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1002    pub coins_to_merge: Vec<Argument>,
1003}
1004
1005/// Command to publish a new move package
1006///
1007/// # BCS
1008///
1009/// The BCS serialized form for this type is defined by the following ABNF:
1010///
1011/// ```text
1012/// publish = (vector bytes)        ; the serialized move modules
1013///           (vector object-id)    ; the set of package dependencies
1014/// ```
1015#[derive(Clone, Debug, PartialEq, Eq)]
1016#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1017#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1018#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1019pub struct Publish {
1020    /// The serialized move modules
1021    #[cfg_attr(
1022        feature = "serde",
1023        serde(
1024            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
1025        )
1026    )]
1027    #[cfg_attr(feature = "schemars", schemars(with = "Vec<crate::_schemars::Base64>"))]
1028    pub modules: Vec<Vec<u8>>,
1029    /// Set of packages that the to-be published package depends on
1030    pub dependencies: Vec<ObjectId>,
1031}
1032
1033/// Command to build a move vector out of a set of individual elements
1034///
1035/// # BCS
1036///
1037/// The BCS serialized form for this type is defined by the following ABNF:
1038///
1039/// ```text
1040/// make-move-vector = (option type-tag) (vector argument)
1041/// ```
1042#[derive(Clone, Debug, PartialEq, Eq)]
1043#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1044#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1045#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1046pub struct MakeMoveVector {
1047    /// Type of the individual elements
1048    ///
1049    /// This is required to be set when the type can't be inferred, for example
1050    /// when the set of provided arguments are all pure input values.
1051    #[cfg_attr(feature = "serde", serde(rename = "type"))]
1052    pub type_: Option<TypeTag>,
1053    /// The set individual elements to build the vector with
1054    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1055    pub elements: Vec<Argument>,
1056}
1057
1058/// Command to upgrade an already published package
1059///
1060/// # BCS
1061///
1062/// The BCS serialized form for this type is defined by the following ABNF:
1063///
1064/// ```text
1065/// upgrade = (vector bytes)        ; move modules
1066///           (vector object-id)    ; dependencies
1067///           object-id             ; package-id of the package
1068///           argument              ; upgrade ticket
1069/// ```
1070#[derive(Clone, Debug, PartialEq, Eq)]
1071#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1072#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1073#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1074pub struct Upgrade {
1075    /// The serialized move modules
1076    #[cfg_attr(
1077        feature = "serde",
1078        serde(
1079            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
1080        )
1081    )]
1082    #[cfg_attr(feature = "schemars", schemars(with = "Vec<crate::_schemars::Base64>"))]
1083    pub modules: Vec<Vec<u8>>,
1084    /// Set of packages that the to-be published package depends on
1085    pub dependencies: Vec<ObjectId>,
1086    /// Package id of the package to upgrade
1087    pub package: ObjectId,
1088    /// Ticket authorizing the upgrade
1089    pub ticket: Argument,
1090}
1091
1092/// An argument to a programmable transaction command
1093///
1094/// # BCS
1095///
1096/// The BCS serialized form for this type is defined by the following ABNF:
1097///
1098/// ```text
1099/// argument    =  argument-gas
1100///             =/ argument-input
1101///             =/ argument-result
1102///             =/ argument-nested-result
1103///
1104/// argument-gas            = %x00
1105/// argument-input          = %x01 u16
1106/// argument-result         = %x02 u16
1107/// argument-nested-result  = %x03 u16 u16
1108/// ```
1109#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1110#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1111pub enum Argument {
1112    /// The gas coin. The gas coin can only be used by-ref, except for with
1113    /// `TransferObjects`, which can use it by-value.
1114    Gas,
1115    /// One of the input objects or primitive values (from
1116    /// `ProgrammableTransaction` inputs)
1117    Input(u16),
1118    /// The result of another command (from `ProgrammableTransaction` commands)
1119    Result(u16),
1120    /// Like a `Result` but it accesses a nested result. Currently, the only
1121    /// usage of this is to access a value from a Move call with multiple
1122    /// return values.
1123    // (command index, subresult index)
1124    NestedResult(u16, u16),
1125}
1126
1127impl Argument {
1128    crate::def_is!(Gas, Input, Result, NestedResult);
1129
1130    pub fn as_input_opt(&self) -> Option<u16> {
1131        if let Self::Input(idx) = self {
1132            Some(*idx)
1133        } else {
1134            None
1135        }
1136    }
1137
1138    pub fn as_input(&self) -> u16 {
1139        self.as_input_opt().expect("not an input")
1140    }
1141
1142    pub fn as_result_opt(&self) -> Option<u16> {
1143        if let Self::Result(idx) = self {
1144            Some(*idx)
1145        } else {
1146            None
1147        }
1148    }
1149
1150    pub fn as_result(&self) -> u16 {
1151        self.as_result_opt().expect("not a result")
1152    }
1153
1154    pub fn as_nested_result_opt(&self) -> Option<(u16, u16)> {
1155        if let Self::NestedResult(idx0, idx1) = self {
1156            Some((*idx0, *idx1))
1157        } else {
1158            None
1159        }
1160    }
1161
1162    pub fn as_nested_result(&self) -> (u16, u16) {
1163        self.as_nested_result_opt().expect("not a nested result")
1164    }
1165
1166    /// Get the nested result for this result at the given index. Returns None
1167    /// if this is not a Result.
1168    pub fn get_nested_result(&self, ix: u16) -> Option<Argument> {
1169        match self {
1170            Argument::Result(i) => Some(Argument::NestedResult(*i, ix)),
1171            _ => None,
1172        }
1173    }
1174}
1175
1176/// Command to call a move function
1177///
1178/// Functions that can be called by a `MoveCall` command are those that have a
1179/// function signature that is either `entry` or `public` (which don't have a
1180/// reference return type).
1181///
1182/// # BCS
1183///
1184/// The BCS serialized form for this type is defined by the following ABNF:
1185///
1186/// ```text
1187/// move-call = object-id           ; package id
1188///             identifier          ; module name
1189///             identifier          ; function name
1190///             (vector type-tag)   ; type arguments, if any
1191///             (vector argument)   ; input arguments
1192/// ```
1193#[derive(Clone, Debug, PartialEq, Eq)]
1194#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1195#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1196#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1197pub struct MoveCall {
1198    /// The package containing the module and function.
1199    pub package: ObjectId,
1200    /// The specific module in the package containing the function.
1201    pub module: Identifier,
1202    /// The function to be called.
1203    pub function: Identifier,
1204    /// The type arguments to the function.
1205    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1206    pub type_arguments: Vec<TypeTag>,
1207    /// The arguments to the function.
1208    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1209    pub arguments: Vec<Argument>,
1210}