Skip to main content

sui_sdk_types/transaction/
mod.rs

1use crate::Digest;
2
3use super::Address;
4use super::CheckpointTimestamp;
5use super::EpochId;
6use super::GenesisObject;
7use super::Identifier;
8use super::Jwk;
9use super::JwkId;
10use super::ObjectReference;
11use super::ProtocolVersion;
12use super::TypeTag;
13use super::UserSignature;
14use super::Version;
15
16#[cfg(feature = "serde")]
17#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
18mod serialization;
19#[cfg(feature = "serde")]
20#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
21pub(crate) use serialization::SignedTransactionWithIntentMessage;
22
23/// A transaction
24///
25/// # BCS
26///
27/// The BCS serialized form for this type is defined by the following ABNF:
28///
29/// ```text
30/// transaction = %x00 transaction-v1
31///
32/// transaction-v1 = transaction-kind address gas-payment transaction-expiration
33/// ```
34#[derive(Clone, Debug, PartialEq, Eq)]
35#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
36pub struct Transaction {
37    pub kind: TransactionKind,
38    pub sender: Address,
39    pub gas_payment: GasPayment,
40    pub expiration: TransactionExpiration,
41}
42
43#[derive(Clone, Debug, PartialEq, Eq)]
44#[cfg_attr(
45    feature = "serde",
46    derive(serde_derive::Serialize, serde_derive::Deserialize)
47)]
48#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
49pub struct SignedTransaction {
50    pub transaction: Transaction,
51    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
52    pub signatures: Vec<UserSignature>,
53}
54
55/// A TTL for a transaction
56///
57/// # BCS
58///
59/// The BCS serialized form for this type is defined by the following ABNF:
60///
61/// ```text
62/// transaction-expiration =  %x00      ; none
63///                        =/ %x01 u64  ; epoch
64/// ```
65#[derive(Clone, Default, Debug, PartialEq, Eq, Hash)]
66#[cfg_attr(
67    feature = "serde",
68    derive(serde_derive::Serialize, serde_derive::Deserialize)
69)]
70#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
71#[non_exhaustive]
72pub enum TransactionExpiration {
73    /// The transaction has no expiration
74    #[default]
75    None,
76
77    /// Validators wont sign a transaction unless the expiration Epoch
78    /// is greater than or equal to the current epoch
79    Epoch(EpochId),
80
81    /// ValidDuring enables gas payments from address balances.
82    ///
83    /// When transactions use address balances for gas payment instead of explicit gas coins,
84    /// we lose the natural transaction uniqueness and replay prevention that comes from
85    /// mutation of gas coin objects.
86    ///
87    /// By bounding expiration and providing a nonce, validators must only retain
88    /// executed digests for the maximum possible expiry range to differentiate
89    /// retries from unique transactions with otherwise identical inputs.
90    ValidDuring {
91        /// Transaction invalid before this epoch. Must equal current epoch.
92        min_epoch: Option<EpochId>,
93        /// Transaction expires after this epoch. Must equal current epoch
94        max_epoch: Option<EpochId>,
95        /// Future support for sub-epoch timing (not yet implemented)
96        min_timestamp: Option<u64>,
97        /// Future support for sub-epoch timing (not yet implemented)
98        max_timestamp: Option<u64>,
99        /// Network identifier to prevent cross-chain replay
100        chain: Digest,
101        /// User-provided uniqueness identifier to differentiate otherwise identical transactions
102        nonce: u32,
103    },
104
105    /// Everything in `ValidDuring`, plus a restriction on which validators may propose the
106    /// transaction in consensus.
107    Validity {
108        /// Transaction invalid before this epoch. Must equal current epoch.
109        min_epoch: Option<EpochId>,
110        /// Transaction expires after this epoch. Must equal current epoch
111        max_epoch: Option<EpochId>,
112        /// Future support for sub-epoch timing (not yet implemented)
113        min_timestamp: Option<u64>,
114        /// Future support for sub-epoch timing (not yet implemented)
115        max_timestamp: Option<u64>,
116        /// Network identifier to prevent cross-chain replay
117        chain: Digest,
118        /// User-provided uniqueness identifier to differentiate otherwise identical transactions
119        nonce: u32,
120        /// The validators allowed to propose this transaction in consensus, if it restricts them
121        allowed_proposers: Option<AllowedProposers>,
122    },
123}
124
125/// The validators allowed to propose a transaction in consensus
126///
127/// Proposal by any other validator is byzantine behavior and invalidates the whole block.
128///
129/// # BCS
130///
131/// The BCS serialized form for this type is defined by the following ABNF:
132///
133/// ```text
134/// allowed-proposers = u64 (vector u32)  ; epoch, then committee indices
135/// ```
136#[derive(Clone, Debug, PartialEq, Eq, Hash)]
137#[cfg_attr(
138    feature = "serde",
139    derive(serde_derive::Serialize, serde_derive::Deserialize)
140)]
141#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
142pub struct AllowedProposers {
143    /// The epoch whose committee `proposers` indexes into
144    ///
145    /// Committee indices are only meaningful against one committee, so a set recorded for any
146    /// other epoch is ignored and the transaction is treated as naming no proposers.
147    pub epoch: EpochId,
148    /// Committee indices of the allowed proposers, strictly increasing and non-empty
149    ///
150    /// An empty set is rejected at deserialization, since it names no validator and would be
151    /// rejected on chain.
152    #[cfg_attr(
153        feature = "proptest",
154        strategy(proptest::collection::vec(proptest::prelude::any::<u32>(), 1..8))
155    )]
156    #[cfg_attr(feature = "serde", serde(deserialize_with = "deserialize_non_empty"))]
157    pub proposers: Vec<u32>,
158}
159
160#[cfg(feature = "serde")]
161fn deserialize_non_empty<'de, D>(deserializer: D) -> Result<Vec<u32>, D::Error>
162where
163    D: serde::Deserializer<'de>,
164{
165    use serde::Deserialize;
166    let proposers = Vec::<u32>::deserialize(deserializer)?;
167    if proposers.is_empty() {
168        return Err(serde::de::Error::custom("empty vector"));
169    }
170    Ok(proposers)
171}
172
173/// Payment information for executing a transaction
174///
175/// # BCS
176///
177/// The BCS serialized form for this type is defined by the following ABNF:
178///
179/// ```text
180/// gas-payment = (vector object-ref) ; gas coin objects
181///               address             ; owner
182///               u64                 ; price
183///               u64                 ; budget
184/// ```
185#[derive(Clone, Debug, PartialEq, Eq)]
186#[cfg_attr(
187    feature = "serde",
188    derive(serde_derive::Serialize, serde_derive::Deserialize)
189)]
190#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
191pub struct GasPayment {
192    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
193    pub objects: Vec<ObjectReference>,
194
195    /// Owner of the gas objects, either the transaction sender or a sponsor
196    pub owner: Address,
197
198    /// Gas unit price to use when charging for computation
199    ///
200    /// Must be greater-than-or-equal-to the network's current RGP (reference gas price)
201    pub price: u64,
202
203    /// Total budget willing to spend for the execution of a transaction
204    pub budget: u64,
205}
206
207/// Randomness update
208///
209/// # BCS
210///
211/// The BCS serialized form for this type is defined by the following ABNF:
212///
213/// ```text
214/// randomness-state-update = u64 u64 bytes u64
215/// ```
216#[derive(Clone, Debug, PartialEq, Eq)]
217#[cfg_attr(
218    feature = "serde",
219    derive(serde_derive::Serialize, serde_derive::Deserialize)
220)]
221#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
222pub struct RandomnessStateUpdate {
223    /// Epoch of the randomness state update transaction
224    pub epoch: u64,
225
226    /// Randomness round of the update
227    pub randomness_round: u64,
228
229    /// Updated random bytes
230    #[cfg_attr(
231        feature = "serde",
232        serde(with = "crate::_serde::ReadableBase64Encoded")
233    )]
234    pub random_bytes: Vec<u8>,
235
236    /// The initial version of the randomness object that it was shared at.
237    pub randomness_obj_initial_shared_version: u64,
238}
239
240/// Transaction type
241///
242/// # BCS
243///
244/// The BCS serialized form for this type is defined by the following ABNF:
245///
246/// ```text
247/// transaction-kind    =  %x00 ptb
248///                     =/ %x01 change-epoch
249///                     =/ %x02 genesis-transaction
250///                     =/ %x03 consensus-commit-prologue
251///                     =/ %x04 authenticator-state-update
252///                     =/ %x05 (vector end-of-epoch-transaction-kind)
253///                     =/ %x06 randomness-state-update
254///                     =/ %x07 consensus-commit-prologue-v2
255///                     =/ %x08 consensus-commit-prologue-v3
256///                     =/ %x09 consensus-commit-prologue-v4
257///                     =/ %x0A ptb
258/// ```
259#[derive(Clone, Debug, PartialEq, Eq)]
260#[cfg_attr(
261    feature = "serde",
262    derive(serde_derive::Serialize, serde_derive::Deserialize)
263)]
264#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
265#[non_exhaustive]
266pub enum TransactionKind {
267    /// A user transaction comprised of a list of native commands and move calls
268    ProgrammableTransaction(ProgrammableTransaction),
269
270    /// System transaction used to end an epoch.
271    ///
272    /// The ChangeEpoch variant is now deprecated (but the ChangeEpoch struct is still used by
273    /// EndOfEpochTransaction below).
274    ChangeEpoch(ChangeEpoch),
275
276    /// Transaction used to initialize the chain state.
277    ///
278    /// Only valid if in the genesis checkpoint (0) and if this is the very first transaction ever
279    /// executed on the chain.
280    Genesis(GenesisTransaction),
281
282    /// V1 consensus commit update
283    ConsensusCommitPrologue(ConsensusCommitPrologue),
284
285    /// Update set of valid JWKs used for zklogin
286    AuthenticatorStateUpdate(AuthenticatorStateUpdate),
287
288    /// Set of operations to run at the end of the epoch to close out the current epoch and start
289    /// the next one.
290    EndOfEpoch(
291        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
292        Vec<EndOfEpochTransactionKind>,
293    ),
294
295    /// Randomness update
296    RandomnessStateUpdate(RandomnessStateUpdate),
297
298    /// V2 consensus commit update
299    ConsensusCommitPrologueV2(ConsensusCommitPrologueV2),
300
301    /// V3 consensus commit update
302    ConsensusCommitPrologueV3(ConsensusCommitPrologueV3),
303
304    /// V4 consensus commit update
305    ConsensusCommitPrologueV4(ConsensusCommitPrologueV4),
306
307    /// A system transaction comprised of a list of native commands and move calls
308    ProgrammableSystemTransaction(ProgrammableTransaction),
309}
310
311/// Operation run at the end of an epoch
312///
313/// # BCS
314///
315/// The BCS serialized form for this type is defined by the following ABNF:
316///
317/// ```text
318/// end-of-epoch-transaction-kind   =  eoe-change-epoch
319///                                 =/ eoe-authenticator-state-create
320///                                 =/ eoe-authenticator-state-expire
321///                                 =/ eoe-randomness-state-create
322///                                 =/ eoe-deny-list-state-create
323///                                 =/ eoe-bridge-state-create
324///                                 =/ eoe-bridge-committee-init
325///                                 =/ eoe-store-execution-time-observations
326///
327/// eoe-change-epoch                = %x00 change-epoch
328/// eoe-authenticator-state-create  = %x01
329/// eoe-authenticator-state-expire  = %x02 authenticator-state-expire
330/// eoe-randomness-state-create     = %x03
331/// eoe-deny-list-state-create      = %x04
332/// eoe-bridge-state-create         = %x05 digest
333/// eoe-bridge-committee-init       = %x06 u64
334/// eoe-store-execution-time-observations = %x07 stored-execution-time-observations
335/// ```
336#[derive(Clone, Debug, PartialEq, Eq)]
337#[cfg_attr(
338    feature = "serde",
339    derive(serde_derive::Serialize, serde_derive::Deserialize)
340)]
341#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
342#[non_exhaustive]
343pub enum EndOfEpochTransactionKind {
344    /// End the epoch and start the next one
345    ChangeEpoch(ChangeEpoch),
346
347    /// Create and initialize the authenticator object used for zklogin
348    AuthenticatorStateCreate,
349
350    /// Expire JWKs used for zklogin
351    AuthenticatorStateExpire(AuthenticatorStateExpire),
352
353    /// Create and initialize the randomness object
354    RandomnessStateCreate,
355
356    /// Create and initialize the deny list object
357    DenyListStateCreate,
358
359    /// Create and initialize the bridge object
360    BridgeStateCreate { chain_id: Digest },
361
362    /// Initialize the bridge committee
363    BridgeCommitteeInit { bridge_object_version: u64 },
364
365    /// Execution time observations from the committee to preserve cross epoch
366    StoreExecutionTimeObservations(ExecutionTimeObservations),
367
368    /// Create and initialize the accumulator root object
369    AccumulatorRootCreate,
370
371    /// Create and initialize the coin metadata registry object
372    CoinRegistryCreate,
373
374    /// Create and initialize the display metadata registry object
375    DisplayRegistryCreate,
376
377    /// Create and initialize the address alias state object
378    AddressAliasStateCreate,
379
380    /// Contains the end-of-epoch-computed storage cost for accumulator objects.
381    WriteAccumulatorStorageCost { storage_cost: u64 },
382
383    /// Create and initialize the forwarding address registry object
384    ForwardingAddressRegistryCreate,
385}
386
387/// Set of Execution Time Observations from the committee.
388///
389/// # BCS
390///
391/// The BCS serialized form for this type is defined by the following ABNF:
392///
393/// ```text
394/// stored-execution-time-observations =  %x00 v1-stored-execution-time-observations
395///
396/// v1-stored-execution-time-observations = (vec
397///                                          execution-time-observation-key
398///                                          (vec execution-time-observation)
399///                                         )
400/// ```
401#[derive(Debug, Hash, PartialEq, Eq, Clone)]
402#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
403#[cfg_attr(
404    feature = "serde",
405    derive(serde_derive::Serialize, serde_derive::Deserialize)
406)]
407#[non_exhaustive]
408pub enum ExecutionTimeObservations {
409    V1(
410        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
411        Vec<(
412            ExecutionTimeObservationKey,
413            Vec<ValidatorExecutionTimeObservation>,
414        )>,
415    ),
416}
417
418/// An execution time observation from a particular validator
419///
420/// # BCS
421///
422/// The BCS serialized form for this type is defined by the following ABNF:
423///
424/// ```text
425/// execution-time-observation = bls-public-key duration
426/// duration =  u64 ; seconds
427///             u32 ; subsecond nanoseconds
428/// ```
429#[derive(Debug, Hash, PartialEq, Eq, Clone)]
430#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
431#[cfg_attr(
432    feature = "serde",
433    derive(serde_derive::Serialize, serde_derive::Deserialize)
434)]
435pub struct ValidatorExecutionTimeObservation {
436    pub validator: crate::Bls12381PublicKey,
437    #[cfg_attr(feature = "proptest", strategy(proptest::strategy::Strategy::prop_map(proptest::arbitrary::any::<u32>(), |x| std::time::Duration::from_millis(x.into()))))]
438    pub duration: std::time::Duration,
439}
440
441/// Key for an execution time observation
442///
443/// # BCS
444///
445/// The BCS serialized form for this type is defined by the following ABNF:
446///
447/// ```text
448/// execution-time-observation-key  =  %x00 move-entry-point
449///                                 =/ %x01 ; transfer-objects
450///                                 =/ %x02 ; split-coins
451///                                 =/ %x03 ; merge-coins
452///                                 =/ %x04 ; publish
453///                                 =/ %x05 ; make-move-vec
454///                                 =/ %x06 ; upgrade
455/// ValidatorExecutionTimeObservation
456/// move-entry-point = address string string (vec type-tag)
457/// ```
458#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
459#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
460#[cfg_attr(
461    feature = "serde",
462    derive(serde_derive::Serialize, serde_derive::Deserialize)
463)]
464#[non_exhaustive]
465pub enum ExecutionTimeObservationKey {
466    // Containts all the fields from `ProgrammableMoveCall` besides `arguments`.
467    MoveEntryPoint {
468        /// The package containing the module and function.
469        package: Address,
470        /// The specific module in the package containing the function.
471        module: String,
472        /// The function to be called.
473        function: String,
474        /// The type arguments to the function.
475        /// NOTE: This field is currently not populated.
476        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
477        type_arguments: Vec<TypeTag>,
478    },
479    TransferObjects,
480    SplitCoins,
481    MergeCoins,
482    Publish, // special case: should not be used; we only use hard-coded estimate for this
483    MakeMoveVec,
484    Upgrade,
485}
486
487/// Expire old JWKs
488///
489/// # BCS
490///
491/// The BCS serialized form for this type is defined by the following ABNF:
492///
493/// ```text
494/// authenticator-state-expire = u64 u64
495/// ```
496#[derive(Clone, Debug, PartialEq, Eq)]
497#[cfg_attr(
498    feature = "serde",
499    derive(serde_derive::Serialize, serde_derive::Deserialize)
500)]
501#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
502pub struct AuthenticatorStateExpire {
503    /// expire JWKs that have a lower epoch than this
504    pub min_epoch: u64,
505
506    /// The initial version of the authenticator object that it was shared at.
507    pub authenticator_object_initial_shared_version: u64,
508}
509
510/// Update the set of valid JWKs
511///
512/// # BCS
513///
514/// The BCS serialized form for this type is defined by the following ABNF:
515///
516/// ```text
517/// authenticator-state-update = u64 ; epoch
518///                              u64 ; round
519///                              (vector active-jwk)
520///                              u64 ; initial version of the authenticator object
521/// ```
522#[derive(Clone, Debug, PartialEq, Eq)]
523#[cfg_attr(
524    feature = "serde",
525    derive(serde_derive::Serialize, serde_derive::Deserialize)
526)]
527#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
528pub struct AuthenticatorStateUpdate {
529    /// Epoch of the authenticator state update transaction
530    pub epoch: u64,
531
532    /// Consensus round of the authenticator state update
533    pub round: u64,
534
535    /// newly active jwks
536    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
537    pub new_active_jwks: Vec<ActiveJwk>,
538
539    /// The initial version of the authenticator object that it was shared at.
540    pub authenticator_obj_initial_shared_version: u64,
541}
542
543/// A new Jwk
544///
545/// # BCS
546///
547/// The BCS serialized form for this type is defined by the following ABNF:
548///
549/// ```text
550/// active-jwk = jwk-id jwk u64
551/// ```
552#[derive(Clone, Debug, PartialEq, Eq)]
553#[cfg_attr(
554    feature = "serde",
555    derive(serde_derive::Serialize, serde_derive::Deserialize)
556)]
557#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
558pub struct ActiveJwk {
559    /// Identifier used to uniquely identify a Jwk
560    pub jwk_id: JwkId,
561
562    /// The Jwk
563    pub jwk: Jwk,
564
565    /// Most recent epoch in which the jwk was validated
566    pub epoch: u64,
567}
568
569/// V1 of the consensus commit prologue system transaction
570///
571/// # BCS
572///
573/// The BCS serialized form for this type is defined by the following ABNF:
574///
575/// ```text
576/// consensus-commit-prologue = u64 u64 u64
577/// ```
578#[derive(Clone, Debug, PartialEq, Eq)]
579#[cfg_attr(
580    feature = "serde",
581    derive(serde_derive::Serialize, serde_derive::Deserialize)
582)]
583#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
584pub struct ConsensusCommitPrologue {
585    /// Epoch of the commit prologue transaction
586    pub epoch: u64,
587
588    /// Consensus round of the commit
589    pub round: u64,
590
591    /// Unix timestamp from consensus
592    pub commit_timestamp_ms: CheckpointTimestamp,
593}
594
595/// V2 of the consensus commit prologue system transaction
596///
597/// # BCS
598///
599/// The BCS serialized form for this type is defined by the following ABNF:
600///
601/// ```text
602/// consensus-commit-prologue-v2 = u64 u64 u64 digest
603/// ```
604#[derive(Clone, Debug, PartialEq, Eq)]
605#[cfg_attr(
606    feature = "serde",
607    derive(serde_derive::Serialize, serde_derive::Deserialize)
608)]
609#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
610pub struct ConsensusCommitPrologueV2 {
611    /// Epoch of the commit prologue transaction
612    pub epoch: u64,
613
614    /// Consensus round of the commit
615    pub round: u64,
616
617    /// Unix timestamp from consensus
618    pub commit_timestamp_ms: CheckpointTimestamp,
619
620    /// Digest of consensus output
621    pub consensus_commit_digest: Digest,
622}
623
624/// Version assignments performed by consensus
625///
626/// # BCS
627///
628/// The BCS serialized form for this type is defined by the following ABNF:
629///
630/// ```text
631/// consensus-determined-version-assignments = canceled-transactions
632///
633/// canceled-transactions = %x00 (vector canceled-transaction)
634///                       = %x01 (vector canceled-transaction-v2)
635/// ```
636#[derive(Clone, Debug, PartialEq, Eq)]
637#[cfg_attr(
638    feature = "serde",
639    derive(serde_derive::Serialize, serde_derive::Deserialize)
640)]
641#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
642#[non_exhaustive]
643pub enum ConsensusDeterminedVersionAssignments {
644    /// Canceled transaction version assignment.
645    CanceledTransactions {
646        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
647        canceled_transactions: Vec<CanceledTransaction>,
648    },
649    /// Canceled transaction version assignment V2.
650    CanceledTransactionsV2 {
651        #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
652        canceled_transactions: Vec<CanceledTransactionV2>,
653    },
654}
655
656/// A transaction that was canceled
657///
658/// # BCS
659///
660/// The BCS serialized form for this type is defined by the following ABNF:
661///
662/// ```text
663/// canceled-transaction = digest (vector version-assignment)
664/// ```
665#[derive(Clone, Debug, PartialEq, Eq)]
666#[cfg_attr(
667    feature = "serde",
668    derive(serde_derive::Serialize, serde_derive::Deserialize)
669)]
670#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
671pub struct CanceledTransaction {
672    pub digest: Digest,
673    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
674    pub version_assignments: Vec<VersionAssignment>,
675}
676
677/// Object version assignment from consensus
678///
679/// # BCS
680///
681/// The BCS serialized form for this type is defined by the following ABNF:
682///
683/// ```text
684/// version-assignment = address u64
685/// ```
686#[derive(Clone, Debug, PartialEq, Eq)]
687#[cfg_attr(
688    feature = "serde",
689    derive(serde_derive::Serialize, serde_derive::Deserialize)
690)]
691#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
692pub struct VersionAssignment {
693    pub object_id: Address,
694    pub version: Version,
695}
696
697/// A transaction that was canceled
698///
699/// # BCS
700///
701/// The BCS serialized form for this type is defined by the following ABNF:
702///
703/// ```text
704/// canceled-transaction-v2 = digest (vector version-assignment-v2)
705/// ```
706#[derive(Clone, Debug, PartialEq, Eq)]
707#[cfg_attr(
708    feature = "serde",
709    derive(serde_derive::Serialize, serde_derive::Deserialize)
710)]
711#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
712pub struct CanceledTransactionV2 {
713    pub digest: Digest,
714    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
715    pub version_assignments: Vec<VersionAssignmentV2>,
716}
717
718/// Object version assignment from consensus
719///
720/// # BCS
721///
722/// The BCS serialized form for this type is defined by the following ABNF:
723///
724/// ```text
725/// version-assignment-v2 = address u64 u64
726/// ```
727#[derive(Clone, Debug, PartialEq, Eq)]
728#[cfg_attr(
729    feature = "serde",
730    derive(serde_derive::Serialize, serde_derive::Deserialize)
731)]
732#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
733pub struct VersionAssignmentV2 {
734    pub object_id: Address,
735    pub start_version: Version,
736    pub version: Version,
737}
738
739/// V3 of the consensus commit prologue system transaction
740///
741/// # BCS
742///
743/// The BCS serialized form for this type is defined by the following ABNF:
744///
745/// ```text
746/// consensus-commit-prologue-v3 = u64 u64 (option u64) u64 digest
747///                                consensus-determined-version-assignments
748/// ```
749#[derive(Clone, Debug, PartialEq, Eq)]
750#[cfg_attr(
751    feature = "serde",
752    derive(serde_derive::Serialize, serde_derive::Deserialize)
753)]
754#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
755pub struct ConsensusCommitPrologueV3 {
756    /// Epoch of the commit prologue transaction
757    pub epoch: u64,
758
759    /// Consensus round of the commit
760    pub round: u64,
761
762    /// The sub DAG index of the consensus commit. This field will be populated if there
763    /// are multiple consensus commits per round.
764    pub sub_dag_index: Option<u64>,
765
766    /// Unix timestamp from consensus
767    pub commit_timestamp_ms: CheckpointTimestamp,
768
769    /// Digest of consensus output
770    pub consensus_commit_digest: Digest,
771
772    /// Stores consensus handler determined shared object version assignments.
773    pub consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments,
774}
775
776/// V4 of the consensus commit prologue system transaction
777///
778/// # BCS
779///
780/// The BCS serialized form for this type is defined by the following ABNF:
781///
782/// ```text
783/// consensus-commit-prologue-v4 = u64 u64 (option u64) u64 digest
784///                                consensus-determined-version-assignments
785///                                digest
786/// ```
787#[derive(Clone, Debug, PartialEq, Eq)]
788#[cfg_attr(
789    feature = "serde",
790    derive(serde_derive::Serialize, serde_derive::Deserialize)
791)]
792#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
793pub struct ConsensusCommitPrologueV4 {
794    /// Epoch of the commit prologue transaction
795    pub epoch: u64,
796
797    /// Consensus round of the commit
798    pub round: u64,
799
800    /// The sub DAG index of the consensus commit. This field will be populated if there
801    /// are multiple consensus commits per round.
802    pub sub_dag_index: Option<u64>,
803
804    /// Unix timestamp from consensus
805    pub commit_timestamp_ms: CheckpointTimestamp,
806
807    /// Digest of consensus output
808    pub consensus_commit_digest: Digest,
809
810    /// Stores consensus handler determined shared object version assignments.
811    pub consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments,
812
813    /// Digest of any additional state computed by the consensus handler.
814    /// Used to detect forking bugs as early as possible.
815    pub additional_state_digest: Digest,
816}
817
818/// System transaction used to change the epoch
819///
820/// # BCS
821///
822/// The BCS serialized form for this type is defined by the following ABNF:
823///
824/// ```text
825/// change-epoch = u64  ; next epoch
826///                u64  ; protocol version
827///                u64  ; storage charge
828///                u64  ; computation charge
829///                u64  ; storage rebate
830///                u64  ; non-refundable storage fee
831///                u64  ; epoch start timestamp
832///                (vector system-package)
833/// ```
834#[derive(Clone, Debug, PartialEq, Eq)]
835#[cfg_attr(
836    feature = "serde",
837    derive(serde_derive::Serialize, serde_derive::Deserialize)
838)]
839#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
840pub struct ChangeEpoch {
841    /// The next (to become) epoch ID.
842    pub epoch: EpochId,
843
844    /// The protocol version in effect in the new epoch.
845    pub protocol_version: ProtocolVersion,
846
847    /// The total amount of gas charged for storage during the epoch.
848    pub storage_charge: u64,
849
850    /// The total amount of gas charged for computation during the epoch.
851    pub computation_charge: u64,
852
853    /// The amount of storage rebate refunded to the txn senders.
854    pub storage_rebate: u64,
855
856    /// The non-refundable storage fee.
857    pub non_refundable_storage_fee: u64,
858
859    /// Unix timestamp when epoch started
860    pub epoch_start_timestamp_ms: u64,
861
862    /// System packages (specifically framework and move stdlib) that are written before the new
863    /// epoch starts. This tracks framework upgrades on chain. When executing the ChangeEpoch txn,
864    /// the validator must write out the modules below.  Modules are provided with the version they
865    /// will be upgraded to, their modules in serialized form (which include their package ID), and
866    /// a list of their transitive dependencies.
867    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
868    pub system_packages: Vec<SystemPackage>,
869}
870
871/// System package
872///
873/// # BCS
874///
875/// The BCS serialized form for this type is defined by the following ABNF:
876///
877/// ```text
878/// system-package = u64                ; version
879///                  (vector bytes)     ; modules
880///                  (vector address) ; dependencies
881/// ```
882#[derive(Clone, Debug, PartialEq, Eq)]
883#[cfg_attr(
884    feature = "serde",
885    derive(serde_derive::Serialize, serde_derive::Deserialize)
886)]
887#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
888pub struct SystemPackage {
889    pub version: Version,
890    #[cfg_attr(
891        feature = "serde",
892        serde(
893            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
894        )
895    )]
896    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
897    pub modules: Vec<Vec<u8>>,
898    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
899    pub dependencies: Vec<Address>,
900}
901
902/// The genesis transaction
903///
904/// # BCS
905///
906/// The BCS serialized form for this type is defined by the following ABNF:
907///
908/// ```text
909/// genesis-transaction = (vector genesis-object)
910/// ```
911#[derive(Clone, Debug, PartialEq, Eq)]
912#[cfg_attr(
913    feature = "serde",
914    derive(serde_derive::Serialize, serde_derive::Deserialize)
915)]
916#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
917pub struct GenesisTransaction {
918    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
919    pub objects: Vec<GenesisObject>,
920}
921
922/// A user transaction
923///
924/// Contains a series of native commands and move calls where the results of one command can be
925/// used in future commands.
926///
927/// # BCS
928///
929/// The BCS serialized form for this type is defined by the following ABNF:
930///
931/// ```text
932/// ptb = (vector input) (vector command)
933/// ```
934#[derive(Clone, Debug, PartialEq, Eq)]
935#[cfg_attr(
936    feature = "serde",
937    derive(serde_derive::Serialize, serde_derive::Deserialize)
938)]
939#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
940pub struct ProgrammableTransaction {
941    /// Input objects or primitive values
942    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=10).lift()))]
943    pub inputs: Vec<Input>,
944
945    /// The commands to be executed sequentially. A failure in any command will
946    /// result in the failure of the entire transaction.
947    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
948    pub commands: Vec<Command>,
949}
950
951/// An input to a user transaction
952///
953/// # BCS
954///
955/// The BCS serialized form for this type is defined by the following ABNF:
956///
957/// ```text
958/// input = input-pure / input-immutable-or-owned / input-shared / input-receiving
959///
960/// input-pure                  = %x00 bytes
961/// input-immutable-or-owned    = %x01 object-ref
962/// input-shared                = %x02 address u64 bool
963/// input-receiving             = %x04 object-ref
964/// ```
965#[derive(Clone, Debug, PartialEq, Eq)]
966#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
967#[non_exhaustive]
968pub enum Input {
969    /// A move value serialized as BCS.
970    ///
971    /// For normal operations this is required to be a move primitive type and not contain structs
972    /// or objects.
973    Pure(Vec<u8>),
974
975    /// A move object that is either immutable or address owned
976    ImmutableOrOwned(ObjectReference),
977
978    /// A move object whose owner is "Shared"
979    Shared(SharedInput),
980
981    /// A move object that is attempted to be received in this transaction.
982    Receiving(ObjectReference),
983
984    /// Reservation to withdraw balance from a funds accumulator. This will be converted into a
985    /// `sui::funds_accumulator::Withdrawal` struct and passed into Move.
986    /// It is allowed to have multiple withdraw arguments even for the same funds type.
987    FundsWithdrawal(FundsWithdrawal),
988}
989
990/// A move object whose owner is "Shared"
991#[derive(Clone, Debug, PartialEq, Eq)]
992#[cfg_attr(
993    feature = "serde",
994    derive(serde_derive::Serialize, serde_derive::Deserialize)
995)]
996#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
997pub struct SharedInput {
998    object_id: Address,
999    version: u64,
1000    mutability: Mutability,
1001}
1002
1003impl SharedInput {
1004    pub fn new<M: Into<Mutability>>(object_id: Address, version: u64, mutable: M) -> Self {
1005        Self {
1006            object_id,
1007            version,
1008            mutability: mutable.into(),
1009        }
1010    }
1011
1012    pub fn object_id(&self) -> Address {
1013        self.object_id
1014    }
1015
1016    pub fn version(&self) -> u64 {
1017        self.version
1018    }
1019
1020    pub fn mutability(&self) -> Mutability {
1021        self.mutability
1022    }
1023}
1024
1025#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1026#[cfg_attr(
1027    feature = "serde",
1028    derive(serde_derive::Serialize, serde_derive::Deserialize)
1029)]
1030#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1031pub enum Mutability {
1032    // The "classic" mutable/immutable modes.
1033    Immutable,
1034    Mutable,
1035    // Non-exclusive write is used to allow multiple transactions to
1036    // simultaneously add disjoint dynamic fields to an object.
1037    // (Currently only used by settlement transactions).
1038    NonExclusiveWrite,
1039}
1040
1041impl From<bool> for Mutability {
1042    fn from(mutable: bool) -> Self {
1043        if mutable {
1044            Self::Mutable
1045        } else {
1046            Self::Immutable
1047        }
1048    }
1049}
1050
1051impl Mutability {
1052    pub fn is_mutable(self) -> bool {
1053        match self {
1054            Mutability::Immutable => false,
1055            Mutability::Mutable => true,
1056            Mutability::NonExclusiveWrite => false,
1057        }
1058    }
1059}
1060
1061#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1062#[cfg_attr(
1063    feature = "serde",
1064    derive(serde_derive::Serialize, serde_derive::Deserialize)
1065)]
1066#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1067#[non_exhaustive]
1068enum Reservation {
1069    // Reserve a specific amount of the balance.
1070    Amount(u64),
1071}
1072
1073#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1074#[cfg_attr(
1075    feature = "serde",
1076    derive(serde_derive::Serialize, serde_derive::Deserialize)
1077)]
1078#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1079#[non_exhaustive]
1080enum WithdrawalType {
1081    Balance(TypeTag),
1082}
1083
1084#[derive(Debug, PartialEq, Eq, Hash, Clone)]
1085#[cfg_attr(
1086    feature = "serde",
1087    derive(serde_derive::Serialize, serde_derive::Deserialize)
1088)]
1089#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1090pub struct FundsWithdrawal {
1091    /// The reservation of the funds accumulator to withdraw.
1092    reservation: Reservation,
1093    /// The type argument of the funds accumulator to withdraw, e.g. `Balance<_>`.
1094    type_: WithdrawalType,
1095    /// The source of the funds to withdraw.
1096    source: WithdrawFrom,
1097}
1098
1099impl FundsWithdrawal {
1100    pub fn new(amount: u64, coin_type: TypeTag, source: WithdrawFrom) -> Self {
1101        Self {
1102            reservation: Reservation::Amount(amount),
1103            type_: WithdrawalType::Balance(coin_type),
1104            source,
1105        }
1106    }
1107
1108    pub fn amount(&self) -> Option<u64> {
1109        match self.reservation {
1110            Reservation::Amount(amount) => Some(amount),
1111        }
1112    }
1113
1114    pub fn coin_type(&self) -> &TypeTag {
1115        match &self.type_ {
1116            WithdrawalType::Balance(coin_type) => coin_type,
1117        }
1118    }
1119
1120    pub fn source(&self) -> WithdrawFrom {
1121        self.source
1122    }
1123}
1124
1125/// The source of the funds for a [`FundsWithdrawal`].
1126///
1127/// # BCS
1128///
1129/// The BCS serialized form for this type is defined by the following ABNF:
1130///
1131/// ```text
1132/// withdraw-from =  withdraw-from-sender
1133///               =/ withdraw-from-sponsor
1134///               =/ withdraw-from-sender-allowance
1135///
1136/// withdraw-from-sender           = %x00
1137/// withdraw-from-sponsor          = %x01
1138/// withdraw-from-sender-allowance = %x02 address address
1139/// ```
1140#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
1141#[cfg_attr(
1142    feature = "serde",
1143    derive(serde_derive::Serialize, serde_derive::Deserialize)
1144)]
1145#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1146#[non_exhaustive]
1147pub enum WithdrawFrom {
1148    /// Withdraw from the sender of the transaction.
1149    Sender,
1150    /// Withdraw from the sponsor of the transaction (gas owner).
1151    Sponsor,
1152    /// Withdraw from `funder`'s balance under an allowance granted to the sender of the transaction.
1153    SenderAllowance {
1154        /// The address whose balance is debited.
1155        funder: Address,
1156        /// The `ObjectId` of the allowance object authorizing the withdrawal.
1157        allowance: Address,
1158    },
1159}
1160
1161/// A single command in a programmable transaction.
1162///
1163/// # BCS
1164///
1165/// The BCS serialized form for this type is defined by the following ABNF:
1166///
1167/// ```text
1168/// command =  command-move-call
1169///         =/ command-transfer-objects
1170///         =/ command-split-coins
1171///         =/ command-merge-coins
1172///         =/ command-publish
1173///         =/ command-make-move-vector
1174///         =/ command-upgrade
1175///
1176/// command-move-call           = %x00 move-call
1177/// command-transfer-objects    = %x01 transfer-objects
1178/// command-split-coins         = %x02 split-coins
1179/// command-merge-coins         = %x03 merge-coins
1180/// command-publish             = %x04 publish
1181/// command-make-move-vector    = %x05 make-move-vector
1182/// command-upgrade             = %x06 upgrade
1183/// ```
1184#[derive(Clone, Debug, PartialEq, Eq)]
1185#[cfg_attr(
1186    feature = "serde",
1187    derive(serde_derive::Serialize, serde_derive::Deserialize)
1188)]
1189#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1190#[non_exhaustive]
1191pub enum Command {
1192    /// A call to either an entry or a public Move function
1193    MoveCall(MoveCall),
1194
1195    /// `(Vec<forall T:key+store. T>, address)`
1196    /// It sends n-objects to the specified address. These objects must have store
1197    /// (public transfer) and either the previous owner must be an address or the object must
1198    /// be newly created.
1199    TransferObjects(TransferObjects),
1200
1201    /// `(&mut Coin<T>, Vec<u64>)` -> `Vec<Coin<T>>`
1202    /// It splits off some amounts into a new coins with those amounts
1203    SplitCoins(SplitCoins),
1204
1205    /// `(&mut Coin<T>, Vec<Coin<T>>)`
1206    /// It merges n-coins into the first coin
1207    MergeCoins(MergeCoins),
1208
1209    /// Publishes a Move package. It takes the package bytes and a list of the package's transitive
1210    /// dependencies to link against on-chain.
1211    Publish(Publish),
1212
1213    /// `forall T: Vec<T> -> vector<T>`
1214    /// Given n-values of the same type, it constructs a vector. For non objects or an empty vector,
1215    /// the type tag must be specified.
1216    MakeMoveVector(MakeMoveVector),
1217
1218    /// Upgrades a Move package
1219    /// Takes (in order):
1220    /// 1. A vector of serialized modules for the package.
1221    /// 2. A vector of object ids for the transitive dependencies of the new package.
1222    /// 3. The object ID of the package being upgraded.
1223    /// 4. An argument holding the `UpgradeTicket` that must have been produced from an earlier command in the same
1224    ///    programmable transaction.
1225    Upgrade(Upgrade),
1226}
1227
1228/// Command to transfer ownership of a set of objects to an address
1229///
1230/// # BCS
1231///
1232/// The BCS serialized form for this type is defined by the following ABNF:
1233///
1234/// ```text
1235/// transfer-objects = (vector argument) argument
1236/// ```
1237#[derive(Clone, Debug, PartialEq, Eq)]
1238#[cfg_attr(
1239    feature = "serde",
1240    derive(serde_derive::Serialize, serde_derive::Deserialize)
1241)]
1242#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1243pub struct TransferObjects {
1244    /// Set of objects to transfer
1245    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1246    pub objects: Vec<Argument>,
1247
1248    /// The address to transfer ownership to
1249    pub address: Argument,
1250}
1251
1252/// Command to split a single coin object into multiple coins
1253///
1254/// # BCS
1255///
1256/// The BCS serialized form for this type is defined by the following ABNF:
1257///
1258/// ```text
1259/// split-coins = argument (vector argument)
1260/// ```
1261#[derive(Clone, Debug, PartialEq, Eq)]
1262#[cfg_attr(
1263    feature = "serde",
1264    derive(serde_derive::Serialize, serde_derive::Deserialize)
1265)]
1266#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1267pub struct SplitCoins {
1268    /// The coin to split
1269    pub coin: Argument,
1270
1271    /// The amounts to split off
1272    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1273    pub amounts: Vec<Argument>,
1274}
1275
1276/// Command to merge multiple coins of the same type into a single coin
1277///
1278/// # BCS
1279///
1280/// The BCS serialized form for this type is defined by the following ABNF:
1281///
1282/// ```text
1283/// merge-coins = argument (vector argument)
1284/// ```
1285#[derive(Clone, Debug, PartialEq, Eq)]
1286#[cfg_attr(
1287    feature = "serde",
1288    derive(serde_derive::Serialize, serde_derive::Deserialize)
1289)]
1290#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1291pub struct MergeCoins {
1292    /// Coin to merge coins into
1293    pub coin: Argument,
1294
1295    /// Set of coins to merge into `coin`
1296    ///
1297    /// All listed coins must be of the same type and be the same type as `coin`
1298    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1299    pub coins_to_merge: Vec<Argument>,
1300}
1301
1302/// Command to publish a new move package
1303///
1304/// # BCS
1305///
1306/// The BCS serialized form for this type is defined by the following ABNF:
1307///
1308/// ```text
1309/// publish = (vector bytes)        ; the serialized move modules
1310///           (vector address)    ; the set of package dependencies
1311/// ```
1312#[derive(Clone, Debug, PartialEq, Eq)]
1313#[cfg_attr(
1314    feature = "serde",
1315    derive(serde_derive::Serialize, serde_derive::Deserialize)
1316)]
1317#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1318pub struct Publish {
1319    /// The serialized move modules
1320    #[cfg_attr(
1321        feature = "serde",
1322        serde(
1323            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
1324        )
1325    )]
1326    pub modules: Vec<Vec<u8>>,
1327
1328    /// Set of packages that the to-be published package depends on
1329    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1330    pub dependencies: Vec<Address>,
1331}
1332
1333/// Command to build a move vector out of a set of individual elements
1334///
1335/// # BCS
1336///
1337/// The BCS serialized form for this type is defined by the following ABNF:
1338///
1339/// ```text
1340/// make-move-vector = (option type-tag) (vector argument)
1341/// ```
1342#[derive(Clone, Debug, PartialEq, Eq)]
1343#[cfg_attr(
1344    feature = "serde",
1345    derive(serde_derive::Serialize, serde_derive::Deserialize)
1346)]
1347#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1348pub struct MakeMoveVector {
1349    /// Type of the individual elements
1350    ///
1351    /// This is required to be set when the type can't be inferred, for example when the set of
1352    /// provided arguments are all pure input values.
1353    #[cfg_attr(feature = "serde", serde(rename = "type"))]
1354    pub type_: Option<TypeTag>,
1355
1356    /// The set individual elements to build the vector with
1357    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1358    pub elements: Vec<Argument>,
1359}
1360
1361/// Command to upgrade an already published package
1362///
1363/// # BCS
1364///
1365/// The BCS serialized form for this type is defined by the following ABNF:
1366///
1367/// ```text
1368/// upgrade = (vector bytes)        ; move modules
1369///           (vector address)    ; dependencies
1370///           address             ; package-id of the package
1371///           argument              ; upgrade ticket
1372/// ```
1373#[derive(Clone, Debug, PartialEq, Eq)]
1374#[cfg_attr(
1375    feature = "serde",
1376    derive(serde_derive::Serialize, serde_derive::Deserialize)
1377)]
1378#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1379pub struct Upgrade {
1380    /// The serialized move modules
1381    #[cfg_attr(
1382        feature = "serde",
1383        serde(
1384            with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
1385        )
1386    )]
1387    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
1388    pub modules: Vec<Vec<u8>>,
1389
1390    /// Set of packages that the to-be published package depends on
1391    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1392    pub dependencies: Vec<Address>,
1393
1394    /// Package id of the package to upgrade
1395    pub package: Address,
1396
1397    /// Ticket authorizing the upgrade
1398    pub ticket: Argument,
1399}
1400
1401/// An argument to a programmable transaction command
1402///
1403/// # BCS
1404///
1405/// The BCS serialized form for this type is defined by the following ABNF:
1406///
1407/// ```text
1408/// argument    =  argument-gas
1409///             =/ argument-input
1410///             =/ argument-result
1411///             =/ argument-nested-result
1412///
1413/// argument-gas            = %x00
1414/// argument-input          = %x01 u16
1415/// argument-result         = %x02 u16
1416/// argument-nested-result  = %x03 u16 u16
1417/// ```
1418#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1419#[cfg_attr(
1420    feature = "serde",
1421    derive(serde_derive::Serialize, serde_derive::Deserialize)
1422)]
1423#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1424pub enum Argument {
1425    /// The gas coin. The gas coin can only be used by-ref, except for with
1426    /// `TransferObjects`, which can use it by-value.
1427    Gas,
1428
1429    /// One of the input objects or primitive values (from
1430    /// `ProgrammableTransaction` inputs)
1431    Input(u16),
1432
1433    /// The result of another command (from `ProgrammableTransaction` commands)
1434    Result(u16),
1435
1436    /// Like a `Result` but it accesses a nested result. Currently, the only usage
1437    /// of this is to access a value from a Move call with multiple return values.
1438    // (command index, subresult index)
1439    NestedResult(u16, u16),
1440}
1441
1442impl Argument {
1443    /// Turn a Result into a NestedResult. If the argument is not a Result, returns None.
1444    pub fn nested(&self, ix: u16) -> Option<Argument> {
1445        match self {
1446            Argument::Result(i) => Some(Argument::NestedResult(*i, ix)),
1447            _ => None,
1448        }
1449    }
1450}
1451
1452/// Command to call a move function
1453///
1454/// Functions that can be called by a `MoveCall` command are those that have a function signature
1455/// that is either `entry` or `public` (which don't have a reference return type).
1456///
1457/// # BCS
1458///
1459/// The BCS serialized form for this type is defined by the following ABNF:
1460///
1461/// ```text
1462/// move-call = address           ; package id
1463///             identifier          ; module name
1464///             identifier          ; function name
1465///             (vector type-tag)   ; type arguments, if any
1466///             (vector argument)   ; input arguments
1467/// ```
1468#[derive(Clone, Debug, PartialEq, Eq)]
1469#[cfg_attr(
1470    feature = "serde",
1471    derive(serde_derive::Serialize, serde_derive::Deserialize)
1472)]
1473#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
1474pub struct MoveCall {
1475    /// The package containing the module and function.
1476    pub package: Address,
1477
1478    /// The specific module in the package containing the function.
1479    pub module: Identifier,
1480
1481    /// The function to be called.
1482    pub function: Identifier,
1483
1484    /// The type arguments to the function.
1485    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1486    pub type_arguments: Vec<TypeTag>,
1487
1488    /// The arguments to the function.
1489    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
1490    pub arguments: Vec<Argument>,
1491}