hedera/contract/
contract_update_transaction.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use hedera_proto::services;
4use hedera_proto::services::smart_contract_service_client::SmartContractServiceClient;
5use time::{
6    Duration,
7    OffsetDateTime,
8};
9use tonic::transport::Channel;
10
11use crate::ledger_id::RefLedgerId;
12use crate::protobuf::FromProtobuf;
13use crate::staked_id::StakedId;
14use crate::transaction::{
15    AnyTransactionData,
16    ChunkInfo,
17    ToSchedulableTransactionDataProtobuf,
18    ToTransactionDataProtobuf,
19    TransactionData,
20    TransactionExecute,
21};
22use crate::{
23    AccountId,
24    BoxGrpcFuture,
25    ContractId,
26    Error,
27    Key,
28    ToProtobuf,
29    Transaction,
30    ValidateChecksums,
31};
32
33/// Updates the fields of a smart contract to the given values.
34pub type ContractUpdateTransaction = Transaction<ContractUpdateTransactionData>;
35
36#[derive(Debug, Default, Clone)]
37pub struct ContractUpdateTransactionData {
38    contract_id: Option<ContractId>,
39
40    expiration_time: Option<OffsetDateTime>,
41
42    admin_key: Option<Key>,
43
44    auto_renew_period: Option<Duration>,
45
46    contract_memo: Option<String>,
47
48    max_automatic_token_associations: Option<i32>,
49
50    auto_renew_account_id: Option<AccountId>,
51
52    proxy_account_id: Option<AccountId>,
53
54    /// ID of the account or node to which this contract is staking, if any.
55    staked_id: Option<StakedId>,
56
57    decline_staking_reward: Option<bool>,
58}
59
60impl ContractUpdateTransaction {
61    /// Returns the contract to be updated.
62    #[must_use]
63    pub fn get_contract_id(&self) -> Option<ContractId> {
64        self.data().contract_id
65    }
66
67    /// Sets the contract to be updated.
68    pub fn contract_id(&mut self, contract_id: ContractId) -> &mut Self {
69        self.data_mut().contract_id = Some(contract_id);
70        self
71    }
72
73    /// Returns the new admin key.
74    #[must_use]
75    pub fn get_admin_key(&self) -> Option<&Key> {
76        self.data().admin_key.as_ref()
77    }
78
79    /// Sets the new admin key.
80    pub fn admin_key(&mut self, key: impl Into<Key>) -> &mut Self {
81        self.data_mut().admin_key = Some(key.into());
82        self
83    }
84
85    /// Returns the new expiration time to extend to (ignored if equal to or before the current one).
86    #[must_use]
87    pub fn get_expiration_time(&self) -> Option<OffsetDateTime> {
88        self.data().expiration_time
89    }
90
91    /// Sets the new expiration time to extend to (ignored if equal to or before the current one).
92    pub fn expiration_time(&mut self, at: OffsetDateTime) -> &mut Self {
93        self.data_mut().expiration_time = Some(at);
94        self
95    }
96
97    /// Returns the auto renew period for this smart contract.
98    #[must_use]
99    pub fn get_auto_renew_period(&self) -> Option<Duration> {
100        self.data().auto_renew_period
101    }
102
103    /// Sets the auto renew period for this smart contract.
104    pub fn auto_renew_period(&mut self, period: Duration) -> &mut Self {
105        self.data_mut().auto_renew_period = Some(period);
106        self
107    }
108
109    /// Returns the new memo for the smart contract.
110    #[must_use]
111    pub fn get_contract_memo(&self) -> Option<&str> {
112        self.data().contract_memo.as_deref()
113    }
114
115    /// Sets the new memo for the smart contract.
116    pub fn contract_memo(&mut self, memo: impl Into<String>) -> &mut Self {
117        self.data_mut().contract_memo = Some(memo.into());
118        self
119    }
120
121    /// Returns the maximum number of tokens that this contract can be automatically associated with.
122    #[must_use]
123    pub fn get_max_automatic_token_associations(&self) -> Option<i32> {
124        self.data().max_automatic_token_associations
125    }
126
127    /// Sets the maximum number of tokens that this contract can be automatically associated with.
128    pub fn max_automatic_token_associations(&mut self, max: i32) -> &mut Self {
129        self.data_mut().max_automatic_token_associations = Some(max);
130        self
131    }
132
133    /// Returns the account to be used at the contract's expiration time to extend the
134    /// life of the contract.
135    #[must_use]
136    pub fn get_auto_renew_account_id(&self) -> Option<AccountId> {
137        self.data().auto_renew_account_id
138    }
139
140    /// Sets the account to be used at the contract's expiration time to extend the
141    /// life of the contract.
142    pub fn auto_renew_account_id(&mut self, account_id: AccountId) -> &mut Self {
143        self.data_mut().auto_renew_account_id = Some(account_id);
144        self
145    }
146
147    /// Returns the ID of the account to which this contract is proxy staked.
148    #[must_use]
149    pub fn get_proxy_account_id(&self) -> Option<AccountId> {
150        self.data().proxy_account_id
151    }
152
153    /// Sets the ID of the account to which this contract is proxy staked.
154    pub fn proxy_account_id(&mut self, id: AccountId) -> &mut Self {
155        self.data_mut().proxy_account_id = Some(id);
156        self
157    }
158
159    /// Returns the ID of the account to which this contract is staking.
160    #[must_use]
161    pub fn get_staked_account_id(&self) -> Option<AccountId> {
162        self.data().staked_id.and_then(StakedId::to_account_id)
163    }
164
165    /// Sets the ID of the account to which this contract is staking.
166    /// This is mutually exclusive with `staked_node_id`.
167    pub fn staked_account_id(&mut self, id: AccountId) -> &mut Self {
168        self.data_mut().staked_id = Some(id.into());
169        self
170    }
171
172    /// Returns the ID of the node to which this contract is staking.
173    #[must_use]
174    pub fn get_staked_node_id(&self) -> Option<u64> {
175        self.data().staked_id.and_then(StakedId::to_node_id)
176    }
177
178    /// Sets the ID of the node to which this contract is staking.
179    /// This is mutually exclusive with `staked_account_id`.
180    pub fn staked_node_id(&mut self, id: u64) -> &mut Self {
181        self.data_mut().staked_id = Some(id.into());
182        self
183    }
184
185    /// Returns `true` if the contract will be updated decline staking rewards,
186    /// `false` if it will be updated to _not_,
187    /// and `None` if it will not be updated.
188    #[must_use]
189    pub fn get_decline_staking_reward(&self) -> Option<bool> {
190        self.data().decline_staking_reward
191    }
192
193    /// Sets to true, the contract declines receiving a staking reward. The default value is false.
194    pub fn decline_staking_reward(&mut self, decline: bool) -> &mut Self {
195        self.data_mut().decline_staking_reward = Some(decline);
196        self
197    }
198}
199
200impl TransactionData for ContractUpdateTransactionData {}
201
202impl TransactionExecute for ContractUpdateTransactionData {
203    fn execute(
204        &self,
205        channel: Channel,
206        request: services::Transaction,
207    ) -> BoxGrpcFuture<'_, services::TransactionResponse> {
208        Box::pin(async { SmartContractServiceClient::new(channel).update_contract(request).await })
209    }
210}
211
212impl ValidateChecksums for ContractUpdateTransactionData {
213    fn validate_checksums(&self, ledger_id: &RefLedgerId) -> Result<(), Error> {
214        self.contract_id.validate_checksums(ledger_id)?;
215        self.auto_renew_account_id.validate_checksums(ledger_id)?;
216        self.staked_id.validate_checksums(ledger_id)?;
217        self.proxy_account_id.validate_checksums(ledger_id)
218    }
219}
220
221impl ToTransactionDataProtobuf for ContractUpdateTransactionData {
222    fn to_transaction_data_protobuf(
223        &self,
224        chunk_info: &ChunkInfo,
225    ) -> services::transaction_body::Data {
226        let _ = chunk_info.assert_single_transaction();
227
228        services::transaction_body::Data::ContractUpdateInstance(self.to_protobuf())
229    }
230}
231
232impl ToSchedulableTransactionDataProtobuf for ContractUpdateTransactionData {
233    fn to_schedulable_transaction_data_protobuf(
234        &self,
235    ) -> services::schedulable_transaction_body::Data {
236        services::schedulable_transaction_body::Data::ContractUpdateInstance(self.to_protobuf())
237    }
238}
239
240impl FromProtobuf<services::ContractUpdateTransactionBody> for ContractUpdateTransactionData {
241    #[allow(deprecated)]
242    fn from_protobuf(pb: services::ContractUpdateTransactionBody) -> crate::Result<Self> {
243        use services::contract_update_transaction_body::MemoField;
244
245        Ok(Self {
246            contract_id: Option::from_protobuf(pb.contract_id)?,
247            expiration_time: pb.expiration_time.map(Into::into),
248            admin_key: Option::from_protobuf(pb.admin_key)?,
249            auto_renew_period: pb.auto_renew_period.map(Into::into),
250            contract_memo: pb.memo_field.map(|it| match it {
251                MemoField::Memo(it) | MemoField::MemoWrapper(it) => it,
252            }),
253            max_automatic_token_associations: pb.max_automatic_token_associations,
254            auto_renew_account_id: Option::from_protobuf(pb.auto_renew_account_id)?,
255            proxy_account_id: Option::from_protobuf(pb.proxy_account_id)?,
256            staked_id: Option::from_protobuf(pb.staked_id)?,
257            decline_staking_reward: pb.decline_reward,
258        })
259    }
260}
261
262impl ToProtobuf for ContractUpdateTransactionData {
263    type Protobuf = services::ContractUpdateTransactionBody;
264
265    fn to_protobuf(&self) -> Self::Protobuf {
266        let contract_id = self.contract_id.to_protobuf();
267        let expiration_time = self.expiration_time.map(Into::into);
268        let admin_key = self.admin_key.to_protobuf();
269        let auto_renew_period = self.auto_renew_period.map(Into::into);
270        let auto_renew_account_id = self.auto_renew_account_id.to_protobuf();
271
272        let staked_id = self.staked_id.map(|id| match id {
273            StakedId::NodeId(id) => {
274                services::contract_update_transaction_body::StakedId::StakedNodeId(id as i64)
275            }
276
277            StakedId::AccountId(id) => {
278                services::contract_update_transaction_body::StakedId::StakedAccountId(
279                    id.to_protobuf(),
280                )
281            }
282        });
283
284        let memo_field = self
285            .contract_memo
286            .clone()
287            .map(services::contract_update_transaction_body::MemoField::MemoWrapper);
288
289        #[allow(deprecated)]
290        services::ContractUpdateTransactionBody {
291            contract_id,
292            expiration_time,
293            admin_key,
294            proxy_account_id: self.proxy_account_id.to_protobuf(),
295            auto_renew_period,
296            max_automatic_token_associations: self
297                .max_automatic_token_associations
298                .map(|max| max as i32),
299            auto_renew_account_id,
300            decline_reward: self.decline_staking_reward,
301            staked_id,
302            file_id: None,
303            memo_field,
304        }
305    }
306}
307
308impl From<ContractUpdateTransactionData> for AnyTransactionData {
309    fn from(transaction: ContractUpdateTransactionData) -> Self {
310        Self::ContractUpdate(transaction)
311    }
312}
313
314#[cfg(test)]
315mod tests {
316
317    use expect_test::expect;
318    use hedera_proto::services;
319    use time::{
320        Duration,
321        OffsetDateTime,
322    };
323
324    use crate::contract::ContractUpdateTransactionData;
325    use crate::protobuf::{
326        FromProtobuf,
327        ToProtobuf,
328    };
329    use crate::transaction::test_helpers::{
330        check_body,
331        transaction_body,
332        unused_private_key,
333    };
334    use crate::{
335        AccountId,
336        AnyTransaction,
337        ContractId,
338        ContractUpdateTransaction,
339        PublicKey,
340    };
341
342    fn admin_key() -> PublicKey {
343        unused_private_key().public_key()
344    }
345
346    const CONTRACT_ID: ContractId = ContractId::new(0, 0, 5007);
347
348    const MAX_AUTOMATIC_TOKEN_ASSOCIATIONS: i32 = 101;
349    const AUTO_RENEW_PERIOD: Duration = Duration::days(1);
350    const CONTRACT_MEMO: &str = "3";
351    const EXPIRATION_TIME: OffsetDateTime =
352        match OffsetDateTime::from_unix_timestamp_nanos(4_000_000) {
353            Ok(it) => it,
354            Err(_) => panic!("Panic in `const` unwrap"),
355        };
356    const PROXY_ACCOUNT_ID: AccountId = AccountId::new(0, 0, 4);
357    const AUTO_RENEW_ACCOUNT_ID: AccountId = AccountId::new(0, 0, 30);
358    const STAKED_ACCOUNT_ID: AccountId = AccountId::new(0, 0, 3);
359    const STAKED_NODE_ID: u64 = 4;
360
361    fn make_transaction() -> ContractUpdateTransaction {
362        let mut tx = ContractUpdateTransaction::new_for_tests();
363
364        tx.contract_id(CONTRACT_ID)
365            .admin_key(admin_key())
366            .max_automatic_token_associations(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS)
367            .auto_renew_period(AUTO_RENEW_PERIOD)
368            .contract_memo(CONTRACT_MEMO)
369            .expiration_time(EXPIRATION_TIME)
370            .proxy_account_id(PROXY_ACCOUNT_ID)
371            .auto_renew_account_id(AUTO_RENEW_ACCOUNT_ID)
372            .staked_account_id(STAKED_ACCOUNT_ID)
373            .freeze()
374            .unwrap();
375
376        tx
377    }
378
379    fn make_transaction2() -> ContractUpdateTransaction {
380        let mut tx = ContractUpdateTransaction::new_for_tests();
381
382        tx.contract_id(CONTRACT_ID)
383            .admin_key(admin_key())
384            .max_automatic_token_associations(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS)
385            .auto_renew_period(AUTO_RENEW_PERIOD)
386            .contract_memo(CONTRACT_MEMO)
387            .expiration_time(EXPIRATION_TIME)
388            .proxy_account_id(PROXY_ACCOUNT_ID)
389            .auto_renew_account_id(AUTO_RENEW_ACCOUNT_ID)
390            .staked_node_id(STAKED_NODE_ID)
391            .freeze()
392            .unwrap();
393
394        tx
395    }
396
397    #[test]
398    fn serialize() {
399        let tx = make_transaction();
400
401        let tx = transaction_body(tx);
402
403        let tx = check_body(tx);
404
405        expect![[r#"
406            ContractUpdateInstance(
407                ContractUpdateTransactionBody {
408                    contract_id: Some(
409                        ContractId {
410                            shard_num: 0,
411                            realm_num: 0,
412                            contract: Some(
413                                ContractNum(
414                                    5007,
415                                ),
416                            ),
417                        },
418                    ),
419                    expiration_time: Some(
420                        Timestamp {
421                            seconds: 0,
422                            nanos: 4000000,
423                        },
424                    ),
425                    admin_key: Some(
426                        Key {
427                            key: Some(
428                                Ed25519(
429                                    [
430                                        224,
431                                        200,
432                                        236,
433                                        39,
434                                        88,
435                                        165,
436                                        135,
437                                        159,
438                                        250,
439                                        194,
440                                        38,
441                                        161,
442                                        60,
443                                        12,
444                                        81,
445                                        107,
446                                        121,
447                                        158,
448                                        114,
449                                        227,
450                                        81,
451                                        65,
452                                        160,
453                                        221,
454                                        130,
455                                        143,
456                                        148,
457                                        211,
458                                        121,
459                                        136,
460                                        164,
461                                        183,
462                                    ],
463                                ),
464                            ),
465                        },
466                    ),
467                    proxy_account_id: Some(
468                        AccountId {
469                            shard_num: 0,
470                            realm_num: 0,
471                            account: Some(
472                                AccountNum(
473                                    4,
474                                ),
475                            ),
476                        },
477                    ),
478                    auto_renew_period: Some(
479                        Duration {
480                            seconds: 86400,
481                        },
482                    ),
483                    file_id: None,
484                    max_automatic_token_associations: Some(
485                        101,
486                    ),
487                    auto_renew_account_id: Some(
488                        AccountId {
489                            shard_num: 0,
490                            realm_num: 0,
491                            account: Some(
492                                AccountNum(
493                                    30,
494                                ),
495                            ),
496                        },
497                    ),
498                    decline_reward: None,
499                    memo_field: Some(
500                        MemoWrapper(
501                            "3",
502                        ),
503                    ),
504                    staked_id: Some(
505                        StakedAccountId(
506                            AccountId {
507                                shard_num: 0,
508                                realm_num: 0,
509                                account: Some(
510                                    AccountNum(
511                                        3,
512                                    ),
513                                ),
514                            },
515                        ),
516                    ),
517                },
518            )
519        "#]]
520        .assert_debug_eq(&tx)
521    }
522
523    #[test]
524    fn to_from_bytes() {
525        let tx = make_transaction();
526
527        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
528
529        let tx = transaction_body(tx);
530
531        let tx2 = transaction_body(tx2);
532
533        assert_eq!(tx, tx2);
534    }
535
536    #[test]
537    fn serialize2() {
538        let tx = make_transaction2();
539
540        let tx = transaction_body(tx);
541
542        let tx = check_body(tx);
543
544        expect![[r#"
545            ContractUpdateInstance(
546                ContractUpdateTransactionBody {
547                    contract_id: Some(
548                        ContractId {
549                            shard_num: 0,
550                            realm_num: 0,
551                            contract: Some(
552                                ContractNum(
553                                    5007,
554                                ),
555                            ),
556                        },
557                    ),
558                    expiration_time: Some(
559                        Timestamp {
560                            seconds: 0,
561                            nanos: 4000000,
562                        },
563                    ),
564                    admin_key: Some(
565                        Key {
566                            key: Some(
567                                Ed25519(
568                                    [
569                                        224,
570                                        200,
571                                        236,
572                                        39,
573                                        88,
574                                        165,
575                                        135,
576                                        159,
577                                        250,
578                                        194,
579                                        38,
580                                        161,
581                                        60,
582                                        12,
583                                        81,
584                                        107,
585                                        121,
586                                        158,
587                                        114,
588                                        227,
589                                        81,
590                                        65,
591                                        160,
592                                        221,
593                                        130,
594                                        143,
595                                        148,
596                                        211,
597                                        121,
598                                        136,
599                                        164,
600                                        183,
601                                    ],
602                                ),
603                            ),
604                        },
605                    ),
606                    proxy_account_id: Some(
607                        AccountId {
608                            shard_num: 0,
609                            realm_num: 0,
610                            account: Some(
611                                AccountNum(
612                                    4,
613                                ),
614                            ),
615                        },
616                    ),
617                    auto_renew_period: Some(
618                        Duration {
619                            seconds: 86400,
620                        },
621                    ),
622                    file_id: None,
623                    max_automatic_token_associations: Some(
624                        101,
625                    ),
626                    auto_renew_account_id: Some(
627                        AccountId {
628                            shard_num: 0,
629                            realm_num: 0,
630                            account: Some(
631                                AccountNum(
632                                    30,
633                                ),
634                            ),
635                        },
636                    ),
637                    decline_reward: None,
638                    memo_field: Some(
639                        MemoWrapper(
640                            "3",
641                        ),
642                    ),
643                    staked_id: Some(
644                        StakedNodeId(
645                            4,
646                        ),
647                    ),
648                },
649            )
650        "#]]
651        .assert_debug_eq(&tx)
652    }
653
654    #[test]
655    fn to_from_bytes2() {
656        let tx = make_transaction2();
657
658        let tx2 = AnyTransaction::from_bytes(&tx.to_bytes().unwrap()).unwrap();
659
660        let tx = transaction_body(tx);
661
662        let tx2 = transaction_body(tx2);
663
664        assert_eq!(tx, tx2);
665    }
666
667    #[test]
668    fn from_proto_body() {
669        #[allow(deprecated)]
670        let tx = services::ContractUpdateTransactionBody {
671            contract_id: Some(CONTRACT_ID.to_protobuf()),
672            expiration_time: Some(EXPIRATION_TIME.to_protobuf()),
673            admin_key: Some(admin_key().to_protobuf()),
674            proxy_account_id: Some(PROXY_ACCOUNT_ID.to_protobuf()),
675            auto_renew_period: Some(AUTO_RENEW_PERIOD.to_protobuf()),
676            max_automatic_token_associations: Some(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS),
677            auto_renew_account_id: Some(AUTO_RENEW_ACCOUNT_ID.to_protobuf()),
678            decline_reward: None,
679            memo_field: Some(services::contract_update_transaction_body::MemoField::MemoWrapper(
680                CONTRACT_MEMO.to_owned(),
681            )),
682            staked_id: Some(services::contract_update_transaction_body::StakedId::StakedAccountId(
683                STAKED_ACCOUNT_ID.to_protobuf(),
684            )),
685            file_id: None,
686        };
687
688        let tx = ContractUpdateTransactionData::from_protobuf(tx).unwrap();
689
690        assert_eq!(tx.contract_id, Some(CONTRACT_ID));
691        assert_eq!(tx.admin_key, Some(admin_key().into()));
692        assert_eq!(tx.max_automatic_token_associations, Some(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS));
693        assert_eq!(tx.auto_renew_period, Some(AUTO_RENEW_PERIOD));
694        assert_eq!(tx.contract_memo, Some(CONTRACT_MEMO.to_owned()));
695        assert_eq!(tx.expiration_time, Some(EXPIRATION_TIME));
696        assert_eq!(tx.proxy_account_id, Some(PROXY_ACCOUNT_ID));
697        assert_eq!(tx.auto_renew_account_id, Some(AUTO_RENEW_ACCOUNT_ID));
698        assert_eq!(tx.staked_id, Some(crate::staked_id::StakedId::AccountId(STAKED_ACCOUNT_ID)));
699    }
700
701    mod get_set {
702        use super::*;
703
704        #[test]
705        fn contract_id() {
706            let mut tx = ContractUpdateTransaction::new();
707            tx.contract_id(CONTRACT_ID);
708
709            assert_eq!(tx.get_contract_id(), Some(CONTRACT_ID));
710        }
711
712        #[test]
713        #[should_panic]
714        fn contract_id_frozen_panics() {
715            make_transaction().contract_id(CONTRACT_ID);
716        }
717
718        #[test]
719        fn admin_key() {
720            let mut tx = ContractUpdateTransaction::new();
721            tx.admin_key(super::admin_key());
722
723            assert_eq!(tx.get_admin_key(), Some(&super::admin_key().into()));
724        }
725
726        #[test]
727        #[should_panic]
728        fn admin_key_frozen_panics() {
729            make_transaction().admin_key(super::admin_key());
730        }
731
732        #[test]
733        fn max_automatic_token_associations() {
734            let mut tx = ContractUpdateTransaction::new();
735            tx.max_automatic_token_associations(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS);
736
737            assert_eq!(
738                tx.get_max_automatic_token_associations(),
739                Some(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS)
740            );
741        }
742
743        #[test]
744        #[should_panic]
745        fn max_automatic_token_associations_frozen_panics() {
746            make_transaction().max_automatic_token_associations(MAX_AUTOMATIC_TOKEN_ASSOCIATIONS);
747        }
748
749        #[test]
750        fn auto_renew_period() {
751            let mut tx = ContractUpdateTransaction::new();
752            tx.auto_renew_period(AUTO_RENEW_PERIOD);
753
754            assert_eq!(tx.get_auto_renew_period(), Some(AUTO_RENEW_PERIOD));
755        }
756
757        #[test]
758        #[should_panic]
759        fn auto_renew_period_frozen_panics() {
760            make_transaction().auto_renew_period(AUTO_RENEW_PERIOD);
761        }
762
763        #[test]
764        fn contract_memo() {
765            let mut tx = ContractUpdateTransaction::new();
766            tx.contract_memo(CONTRACT_MEMO);
767
768            assert_eq!(tx.get_contract_memo(), Some(CONTRACT_MEMO));
769        }
770
771        #[test]
772        #[should_panic]
773        fn contract_memo_frozen_panics() {
774            make_transaction().contract_memo(CONTRACT_MEMO);
775        }
776
777        #[test]
778        fn expiration_time() {
779            let mut tx = ContractUpdateTransaction::new();
780            tx.expiration_time(EXPIRATION_TIME);
781
782            assert_eq!(tx.get_expiration_time(), Some(EXPIRATION_TIME));
783        }
784
785        #[test]
786        #[should_panic]
787        fn expiration_time_frozen_panics() {
788            make_transaction().expiration_time(EXPIRATION_TIME);
789        }
790
791        #[test]
792        fn proxy_account_id() {
793            let mut tx = ContractUpdateTransaction::new();
794            tx.proxy_account_id(PROXY_ACCOUNT_ID);
795
796            assert_eq!(tx.get_proxy_account_id(), Some(PROXY_ACCOUNT_ID));
797        }
798
799        #[test]
800        #[should_panic]
801        fn proxy_account_id_frozen_panics() {
802            make_transaction().proxy_account_id(PROXY_ACCOUNT_ID);
803        }
804
805        #[test]
806        fn auto_renew_account_id() {
807            let mut tx = ContractUpdateTransaction::new();
808            tx.auto_renew_account_id(AUTO_RENEW_ACCOUNT_ID);
809
810            assert_eq!(tx.get_auto_renew_account_id(), Some(AUTO_RENEW_ACCOUNT_ID));
811        }
812
813        #[test]
814        #[should_panic]
815        fn auto_renew_account_id_frozen_panics() {
816            make_transaction().auto_renew_account_id(AUTO_RENEW_ACCOUNT_ID);
817        }
818
819        #[test]
820        fn staked_account_id() {
821            let mut tx = ContractUpdateTransaction::new();
822            tx.staked_account_id(STAKED_ACCOUNT_ID);
823
824            assert_eq!(tx.get_staked_account_id(), Some(STAKED_ACCOUNT_ID));
825        }
826
827        #[test]
828        #[should_panic]
829        fn staked_account_id_frozen_panics() {
830            make_transaction().staked_account_id(STAKED_ACCOUNT_ID);
831        }
832
833        #[test]
834        fn staked_node_id() {
835            let mut tx = ContractUpdateTransaction::new();
836            tx.staked_node_id(STAKED_NODE_ID);
837
838            assert_eq!(tx.get_staked_node_id(), Some(STAKED_NODE_ID));
839        }
840
841        #[test]
842        #[should_panic]
843        fn staked_node_id_frozen_panics() {
844            make_transaction().staked_node_id(STAKED_NODE_ID);
845        }
846    }
847}