github.com/hashgraph/hedera-sdk-go/v2@v2.48.0/contract_update_transaction.go (about)

     1  package hedera
     2  
     3  /*-
     4   *
     5   * Hedera Go SDK
     6   *
     7   * Copyright (C) 2020 - 2024 Hedera Hashgraph, LLC
     8   *
     9   * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at
    12   *
    13   *      http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   *
    21   */
    22  
    23  import (
    24  	"time"
    25  
    26  	"google.golang.org/protobuf/types/known/wrapperspb"
    27  
    28  	"github.com/hashgraph/hedera-protobufs-go/services"
    29  )
    30  
    31  // ContractUpdateTransaction is used to modify a smart contract instance to have the given parameter values. Any nil
    32  // field is ignored (left unchanged). If only the contractInstanceExpirationTime is being modified, then no signature is
    33  // needed on this transaction other than for the account paying for the transaction itself. But if any of the other
    34  // fields are being modified, then it must be signed by the adminKey. The use of adminKey is not currently supported in
    35  // this API, but in the future will be implemented to allow these fields to be modified, and also to make modifications
    36  // to the state of the instance. If the contract is created with no admin key, then none of the fields can be changed
    37  // that need an admin signature, and therefore no admin key can ever be added. So if there is no admin key, then things
    38  // like the bytecode are immutable. But if there is an admin key, then they can be changed.
    39  //
    40  // For example, the admin key might be a threshold key, which requires 3 of 5 binding arbitration judges to agree before
    41  // the bytecode can be changed. This can be used to add flexibility to the management of smart contract behavior. But
    42  // this is optional. If the smart contract is created without an admin key, then such a key can never be added, and its
    43  // bytecode will be immutable.
    44  type ContractUpdateTransaction struct {
    45  	Transaction
    46  	contractID                    *ContractID
    47  	proxyAccountID                *AccountID
    48  	bytecodeFileID                *FileID
    49  	adminKey                      Key
    50  	autoRenewPeriod               *time.Duration
    51  	expirationTime                *time.Time
    52  	memo                          string
    53  	autoRenewAccountID            *AccountID
    54  	maxAutomaticTokenAssociations int32
    55  	stakedAccountID               *AccountID
    56  	stakedNodeID                  *int64
    57  	declineReward                 bool
    58  }
    59  
    60  // NewContractUpdateTransaction creates a ContractUpdateTransaction transaction which can be
    61  // used to construct and execute a Contract Update Transaction.
    62  // ContractUpdateTransaction is used to modify a smart contract instance to have the given parameter values. Any nil
    63  // field is ignored (left unchanged). If only the contractInstanceExpirationTime is being modified, then no signature is
    64  // needed on this transaction other than for the account paying for the transaction itself. But if any of the other
    65  // fields are being modified, then it must be signed by the adminKey. The use of adminKey is not currently supported in
    66  // this API, but in the future will be implemented to allow these fields to be modified, and also to make modifications
    67  // to the state of the instance. If the contract is created with no admin key, then none of the fields can be changed
    68  // that need an admin signature, and therefore no admin key can ever be added. So if there is no admin key, then things
    69  // like the bytecode are immutable. But if there is an admin key, then they can be changed.
    70  //
    71  // For example, the admin key might be a threshold key, which requires 3 of 5 binding arbitration judges to agree before
    72  // the bytecode can be changed. This can be used to add flexibility to the management of smart contract behavior. But
    73  // this is optional. If the smart contract is created without an admin key, then such a key can never be added, and its
    74  // bytecode will be immutable.
    75  func NewContractUpdateTransaction() *ContractUpdateTransaction {
    76  	tx := ContractUpdateTransaction{
    77  		Transaction: _NewTransaction(),
    78  	}
    79  	tx._SetDefaultMaxTransactionFee(NewHbar(2))
    80  
    81  	return &tx
    82  }
    83  
    84  func _ContractUpdateTransactionFromProtobuf(tx Transaction, pb *services.TransactionBody) *ContractUpdateTransaction {
    85  	key, _ := _KeyFromProtobuf(pb.GetContractUpdateInstance().AdminKey)
    86  	autoRenew := _DurationFromProtobuf(pb.GetContractUpdateInstance().GetAutoRenewPeriod())
    87  	expiration := _TimeFromProtobuf(pb.GetContractUpdateInstance().GetExpirationTime())
    88  	var memo string
    89  
    90  	switch m := pb.GetContractUpdateInstance().GetMemoField().(type) {
    91  	case *services.ContractUpdateTransactionBody_Memo:
    92  		memo = m.Memo // nolint
    93  	case *services.ContractUpdateTransactionBody_MemoWrapper:
    94  		memo = m.MemoWrapper.Value
    95  	}
    96  
    97  	stakedNodeID := pb.GetContractUpdateInstance().GetStakedNodeId()
    98  
    99  	var stakeNodeAccountID *AccountID
   100  	if pb.GetContractUpdateInstance().GetStakedAccountId() != nil {
   101  		stakeNodeAccountID = _AccountIDFromProtobuf(pb.GetContractUpdateInstance().GetStakedAccountId())
   102  	}
   103  
   104  	var autoRenewAccountID *AccountID
   105  	if pb.GetContractUpdateInstance().AutoRenewAccountId != nil {
   106  		autoRenewAccountID = _AccountIDFromProtobuf(pb.GetContractUpdateInstance().GetAutoRenewAccountId())
   107  	}
   108  
   109  	return &ContractUpdateTransaction{
   110  		Transaction:                   tx,
   111  		contractID:                    _ContractIDFromProtobuf(pb.GetContractUpdateInstance().GetContractID()),
   112  		adminKey:                      key,
   113  		autoRenewPeriod:               &autoRenew,
   114  		expirationTime:                &expiration,
   115  		memo:                          memo,
   116  		autoRenewAccountID:            autoRenewAccountID,
   117  		maxAutomaticTokenAssociations: pb.GetContractUpdateInstance().MaxAutomaticTokenAssociations.GetValue(),
   118  		stakedAccountID:               stakeNodeAccountID,
   119  		stakedNodeID:                  &stakedNodeID,
   120  		declineReward:                 pb.GetContractUpdateInstance().GetDeclineReward().GetValue(),
   121  	}
   122  }
   123  
   124  // SetContractID sets The Contract ID instance to update (this can't be changed on the contract)
   125  func (tx *ContractUpdateTransaction) SetContractID(contractID ContractID) *ContractUpdateTransaction {
   126  	tx.contractID = &contractID
   127  	return tx
   128  }
   129  
   130  func (tx *ContractUpdateTransaction) GetContractID() ContractID {
   131  	if tx.contractID == nil {
   132  		return ContractID{}
   133  	}
   134  
   135  	return *tx.contractID
   136  }
   137  
   138  // Deprecated
   139  func (tx *ContractUpdateTransaction) SetBytecodeFileID(bytecodeFileID FileID) *ContractUpdateTransaction {
   140  	tx._RequireNotFrozen()
   141  	tx.bytecodeFileID = &bytecodeFileID
   142  	return tx
   143  }
   144  
   145  // Deprecated
   146  func (tx *ContractUpdateTransaction) GetBytecodeFileID() FileID {
   147  	if tx.bytecodeFileID == nil {
   148  		return FileID{}
   149  	}
   150  
   151  	return *tx.bytecodeFileID
   152  }
   153  
   154  // SetAdminKey sets the key which can be used to arbitrarily modify the state of the instance by signing a
   155  // ContractUpdateTransaction to modify it. If the admin key was never set then such modifications are not possible,
   156  // and there is no administrator that can overrIDe the normal operation of the smart contract instance.
   157  func (tx *ContractUpdateTransaction) SetAdminKey(publicKey PublicKey) *ContractUpdateTransaction {
   158  	tx._RequireNotFrozen()
   159  	tx.adminKey = publicKey
   160  	return tx
   161  }
   162  
   163  func (tx *ContractUpdateTransaction) GetAdminKey() (Key, error) {
   164  	return tx.adminKey, nil
   165  }
   166  
   167  // Deprecated
   168  // SetProxyAccountID sets the ID of the account to which this contract is proxy staked. If proxyAccountID is left unset,
   169  // is an invalID account, or is an account that isn't a _Node, then this contract is automatically proxy staked to a _Node
   170  // chosen by the _Network, but without earning payments. If the proxyAccountID account refuses to accept proxy staking,
   171  // or if it is not currently running a _Node, then it will behave as if proxyAccountID was never set.
   172  func (tx *ContractUpdateTransaction) SetProxyAccountID(proxyAccountID AccountID) *ContractUpdateTransaction {
   173  	tx._RequireNotFrozen()
   174  	tx.proxyAccountID = &proxyAccountID
   175  	return tx
   176  }
   177  
   178  // Deprecated
   179  func (tx *ContractUpdateTransaction) GetProxyAccountID() AccountID {
   180  	if tx.proxyAccountID == nil {
   181  		return AccountID{}
   182  	}
   183  
   184  	return *tx.proxyAccountID
   185  }
   186  
   187  // SetAutoRenewPeriod sets the duration for which the contract instance will automatically charge its account to
   188  // renew for.
   189  func (tx *ContractUpdateTransaction) SetAutoRenewPeriod(autoRenewPeriod time.Duration) *ContractUpdateTransaction {
   190  	tx._RequireNotFrozen()
   191  	tx.autoRenewPeriod = &autoRenewPeriod
   192  	return tx
   193  }
   194  
   195  func (tx *ContractUpdateTransaction) GetAutoRenewPeriod() time.Duration {
   196  	if tx.autoRenewPeriod != nil {
   197  		return *tx.autoRenewPeriod
   198  	}
   199  
   200  	return time.Duration(0)
   201  }
   202  
   203  // SetExpirationTime extends the expiration of the instance and its account to the provIDed time. If the time provIDed
   204  // is the current or past time, then there will be no effect.
   205  func (tx *ContractUpdateTransaction) SetExpirationTime(expiration time.Time) *ContractUpdateTransaction {
   206  	tx._RequireNotFrozen()
   207  	tx.expirationTime = &expiration
   208  	return tx
   209  }
   210  
   211  func (tx *ContractUpdateTransaction) GetExpirationTime() time.Time {
   212  	if tx.expirationTime != nil {
   213  		return *tx.expirationTime
   214  	}
   215  
   216  	return time.Time{}
   217  }
   218  
   219  // SetContractMemo sets the memo associated with the contract (max 100 bytes)
   220  func (tx *ContractUpdateTransaction) SetContractMemo(memo string) *ContractUpdateTransaction {
   221  	tx._RequireNotFrozen()
   222  	tx.memo = memo
   223  	// if transaction.pb.GetMemoWrapper() != nil {
   224  	//	transaction.pb.GetMemoWrapper().Value = memo
   225  	// } else {
   226  	//	transaction.pb.MemoField = &services.ContractUpdateTransactionBody_MemoWrapper{
   227  	//		MemoWrapper: &wrapperspb.StringValue{Value: memo},
   228  	//	}
   229  	// }
   230  
   231  	return tx
   232  }
   233  
   234  // SetAutoRenewAccountID
   235  // An account to charge for auto-renewal of this contract. If not set, or set to an
   236  // account with zero hbar balance, the contract's own hbar balance will be used to
   237  // cover auto-renewal fees.
   238  func (tx *ContractUpdateTransaction) SetAutoRenewAccountID(id AccountID) *ContractUpdateTransaction {
   239  	tx._RequireNotFrozen()
   240  	tx.autoRenewAccountID = &id
   241  	return tx
   242  }
   243  
   244  func (tx *ContractUpdateTransaction) GetAutoRenewAccountID() AccountID {
   245  	if tx.autoRenewAccountID == nil {
   246  		return AccountID{}
   247  	}
   248  
   249  	return *tx.autoRenewAccountID
   250  }
   251  
   252  // SetMaxAutomaticTokenAssociations
   253  // The maximum number of tokens that this contract can be automatically associated
   254  // with (i.e., receive air-drops from).
   255  func (tx *ContractUpdateTransaction) SetMaxAutomaticTokenAssociations(max int32) *ContractUpdateTransaction {
   256  	tx._RequireNotFrozen()
   257  	tx.maxAutomaticTokenAssociations = max
   258  	return tx
   259  }
   260  
   261  func (tx *ContractUpdateTransaction) GetMaxAutomaticTokenAssociations() int32 {
   262  	return tx.maxAutomaticTokenAssociations
   263  }
   264  
   265  func (tx *ContractUpdateTransaction) GetContractMemo() string {
   266  	return tx.memo
   267  }
   268  
   269  func (tx *ContractUpdateTransaction) SetStakedAccountID(id AccountID) *ContractUpdateTransaction {
   270  	tx._RequireNotFrozen()
   271  	tx.stakedAccountID = &id
   272  	return tx
   273  }
   274  
   275  func (tx *ContractUpdateTransaction) GetStakedAccountID() AccountID {
   276  	if tx.stakedAccountID != nil {
   277  		return *tx.stakedAccountID
   278  	}
   279  
   280  	return AccountID{}
   281  }
   282  
   283  func (tx *ContractUpdateTransaction) SetStakedNodeID(id int64) *ContractUpdateTransaction {
   284  	tx._RequireNotFrozen()
   285  	tx.stakedNodeID = &id
   286  	return tx
   287  }
   288  
   289  func (tx *ContractUpdateTransaction) GetStakedNodeID() int64 {
   290  	if tx.stakedNodeID != nil {
   291  		return *tx.stakedNodeID
   292  	}
   293  
   294  	return 0
   295  }
   296  
   297  func (tx *ContractUpdateTransaction) SetDeclineStakingReward(decline bool) *ContractUpdateTransaction {
   298  	tx._RequireNotFrozen()
   299  	tx.declineReward = decline
   300  	return tx
   301  }
   302  
   303  func (tx *ContractUpdateTransaction) GetDeclineStakingReward() bool {
   304  	return tx.declineReward
   305  }
   306  
   307  func (tx *ContractUpdateTransaction) ClearStakedAccountID() *ContractUpdateTransaction {
   308  	tx._RequireNotFrozen()
   309  	tx.stakedAccountID = &AccountID{Account: 0}
   310  	return tx
   311  }
   312  
   313  func (tx *ContractUpdateTransaction) ClearStakedNodeID() *ContractUpdateTransaction {
   314  	tx._RequireNotFrozen()
   315  	*tx.stakedNodeID = -1
   316  	return tx
   317  }
   318  
   319  // ---- Required Interfaces ---- //
   320  
   321  // Sign uses the provided privateKey to sign the transaction.
   322  func (tx *ContractUpdateTransaction) Sign(
   323  	privateKey PrivateKey,
   324  ) *ContractUpdateTransaction {
   325  	tx.Transaction.Sign(privateKey)
   326  	return tx
   327  }
   328  
   329  // SignWithOperator signs the transaction with client's operator privateKey.
   330  func (tx *ContractUpdateTransaction) SignWithOperator(
   331  	client *Client,
   332  ) (*ContractUpdateTransaction, error) {
   333  	// If the transaction is not signed by the _Operator, we need
   334  	// to sign the transaction with the _Operator
   335  	_, err := tx.Transaction.signWithOperator(client, tx)
   336  	if err != nil {
   337  		return nil, err
   338  	}
   339  	return tx, nil
   340  }
   341  
   342  // SignWith executes the TransactionSigner and adds the resulting signature data to the Transaction's signature map
   343  // with the publicKey as the map key.
   344  func (tx *ContractUpdateTransaction) SignWith(
   345  	publicKey PublicKey,
   346  	signer TransactionSigner,
   347  ) *ContractUpdateTransaction {
   348  	tx.Transaction.SignWith(publicKey, signer)
   349  	return tx
   350  }
   351  
   352  // AddSignature adds a signature to the transaction.
   353  func (tx *ContractUpdateTransaction) AddSignature(publicKey PublicKey, signature []byte) *ContractUpdateTransaction {
   354  	tx.Transaction.AddSignature(publicKey, signature)
   355  	return tx
   356  }
   357  
   358  // When execution is attempted, a single attempt will timeout when tx deadline is reached. (The SDK may subsequently retry the execution.)
   359  func (tx *ContractUpdateTransaction) SetGrpcDeadline(deadline *time.Duration) *ContractUpdateTransaction {
   360  	tx.Transaction.SetGrpcDeadline(deadline)
   361  	return tx
   362  }
   363  
   364  func (tx *ContractUpdateTransaction) Freeze() (*ContractUpdateTransaction, error) {
   365  	return tx.FreezeWith(nil)
   366  }
   367  
   368  func (tx *ContractUpdateTransaction) FreezeWith(client *Client) (*ContractUpdateTransaction, error) {
   369  	_, err := tx.Transaction.freezeWith(client, tx)
   370  	return tx, err
   371  }
   372  
   373  // SetMaxTransactionFee sets the maximum transaction fee the operator (paying account) is willing to pay.
   374  func (tx *ContractUpdateTransaction) SetMaxTransactionFee(fee Hbar) *ContractUpdateTransaction {
   375  	tx._RequireNotFrozen()
   376  	tx.Transaction.SetMaxTransactionFee(fee)
   377  	return tx
   378  }
   379  
   380  // SetRegenerateTransactionID sets if transaction IDs should be regenerated when `TRANSACTION_EXPIRED` is received
   381  func (tx *ContractUpdateTransaction) SetRegenerateTransactionID(regenerateTransactionID bool) *ContractUpdateTransaction {
   382  	tx._RequireNotFrozen()
   383  	tx.Transaction.SetRegenerateTransactionID(regenerateTransactionID)
   384  	return tx
   385  }
   386  
   387  // SetTransactionMemo sets the memo for this ContractUpdateTransaction.
   388  func (tx *ContractUpdateTransaction) SetTransactionMemo(memo string) *ContractUpdateTransaction {
   389  	tx._RequireNotFrozen()
   390  	tx.Transaction.SetTransactionMemo(memo)
   391  	return tx
   392  }
   393  
   394  // SetTransactionValidDuration sets the valid duration for this ContractUpdateTransaction.
   395  func (tx *ContractUpdateTransaction) SetTransactionValidDuration(duration time.Duration) *ContractUpdateTransaction {
   396  	tx._RequireNotFrozen()
   397  	tx.Transaction.SetTransactionValidDuration(duration)
   398  	return tx
   399  }
   400  
   401  // ToBytes serialise the tx to bytes, no matter if it is signed (locked), or not
   402  func (tx *ContractUpdateTransaction) ToBytes() ([]byte, error) {
   403  	bytes, err := tx.Transaction.toBytes(tx)
   404  	if err != nil {
   405  		return nil, err
   406  	}
   407  	return bytes, nil
   408  }
   409  
   410  // SetTransactionID sets the TransactionID for this ContractUpdateTransaction.
   411  func (tx *ContractUpdateTransaction) SetTransactionID(transactionID TransactionID) *ContractUpdateTransaction {
   412  	tx._RequireNotFrozen()
   413  
   414  	tx.Transaction.SetTransactionID(transactionID)
   415  	return tx
   416  }
   417  
   418  // SetNodeAccountID sets the _Node AccountID for this ContractUpdateTransaction.
   419  func (tx *ContractUpdateTransaction) SetNodeAccountIDs(nodeID []AccountID) *ContractUpdateTransaction {
   420  	tx._RequireNotFrozen()
   421  	tx.Transaction.SetNodeAccountIDs(nodeID)
   422  	return tx
   423  }
   424  
   425  // SetMaxRetry sets the max number of errors before execution will fail.
   426  func (tx *ContractUpdateTransaction) SetMaxRetry(count int) *ContractUpdateTransaction {
   427  	tx.Transaction.SetMaxRetry(count)
   428  	return tx
   429  }
   430  
   431  // SetMaxBackoff The maximum amount of time to wait between retries.
   432  // Every retry attempt will increase the wait time exponentially until it reaches this time.
   433  func (tx *ContractUpdateTransaction) SetMaxBackoff(max time.Duration) *ContractUpdateTransaction {
   434  	tx.Transaction.SetMaxBackoff(max)
   435  	return tx
   436  }
   437  
   438  // SetMinBackoff sets the minimum amount of time to wait between retries.
   439  func (tx *ContractUpdateTransaction) SetMinBackoff(min time.Duration) *ContractUpdateTransaction {
   440  	tx.Transaction.SetMinBackoff(min)
   441  	return tx
   442  }
   443  
   444  func (tx *ContractUpdateTransaction) SetLogLevel(level LogLevel) *ContractUpdateTransaction {
   445  	tx.Transaction.SetLogLevel(level)
   446  	return tx
   447  }
   448  
   449  func (tx *ContractUpdateTransaction) Execute(client *Client) (TransactionResponse, error) {
   450  	return tx.Transaction.execute(client, tx)
   451  }
   452  
   453  func (tx *ContractUpdateTransaction) Schedule() (*ScheduleCreateTransaction, error) {
   454  	return tx.Transaction.schedule(tx)
   455  }
   456  
   457  // ----------- Overridden functions ----------------
   458  
   459  func (tx *ContractUpdateTransaction) getName() string {
   460  	return "ContractUpdateTransaction"
   461  }
   462  
   463  func (tx *ContractUpdateTransaction) validateNetworkOnIDs(client *Client) error {
   464  	if client == nil || !client.autoValidateChecksums {
   465  		return nil
   466  	}
   467  
   468  	if tx.contractID != nil {
   469  		if err := tx.contractID.ValidateChecksum(client); err != nil {
   470  			return err
   471  		}
   472  	}
   473  
   474  	if tx.proxyAccountID != nil {
   475  		if err := tx.proxyAccountID.ValidateChecksum(client); err != nil {
   476  			return err
   477  		}
   478  	}
   479  
   480  	return nil
   481  }
   482  
   483  func (tx *ContractUpdateTransaction) build() *services.TransactionBody {
   484  	return &services.TransactionBody{
   485  		TransactionFee:           tx.transactionFee,
   486  		Memo:                     tx.Transaction.memo,
   487  		TransactionValidDuration: _DurationToProtobuf(tx.GetTransactionValidDuration()),
   488  		TransactionID:            tx.transactionID._ToProtobuf(),
   489  		Data: &services.TransactionBody_ContractUpdateInstance{
   490  			ContractUpdateInstance: tx.buildProtoBody(),
   491  		},
   492  	}
   493  }
   494  
   495  func (tx *ContractUpdateTransaction) buildScheduled() (*services.SchedulableTransactionBody, error) {
   496  	return &services.SchedulableTransactionBody{
   497  		TransactionFee: tx.transactionFee,
   498  		Memo:           tx.Transaction.memo,
   499  		Data: &services.SchedulableTransactionBody_ContractUpdateInstance{
   500  			ContractUpdateInstance: tx.buildProtoBody(),
   501  		},
   502  	}, nil
   503  }
   504  
   505  func (tx *ContractUpdateTransaction) buildProtoBody() *services.ContractUpdateTransactionBody {
   506  	body := &services.ContractUpdateTransactionBody{
   507  		DeclineReward: &wrapperspb.BoolValue{Value: tx.declineReward},
   508  	}
   509  
   510  	if tx.maxAutomaticTokenAssociations != 0 {
   511  		body.MaxAutomaticTokenAssociations = &wrapperspb.Int32Value{Value: tx.maxAutomaticTokenAssociations}
   512  	}
   513  
   514  	if tx.expirationTime != nil {
   515  		body.ExpirationTime = _TimeToProtobuf(*tx.expirationTime)
   516  	}
   517  
   518  	if tx.autoRenewPeriod != nil {
   519  		body.AutoRenewPeriod = _DurationToProtobuf(*tx.autoRenewPeriod)
   520  	}
   521  
   522  	if tx.adminKey != nil {
   523  		body.AdminKey = tx.adminKey._ToProtoKey()
   524  	}
   525  
   526  	if tx.contractID != nil {
   527  		body.ContractID = tx.contractID._ToProtobuf()
   528  	}
   529  
   530  	if tx.autoRenewAccountID != nil {
   531  		body.AutoRenewAccountId = tx.autoRenewAccountID._ToProtobuf()
   532  	}
   533  
   534  	if body.GetMemoWrapper() != nil {
   535  		body.GetMemoWrapper().Value = tx.memo
   536  	} else {
   537  		body.MemoField = &services.ContractUpdateTransactionBody_MemoWrapper{
   538  			MemoWrapper: &wrapperspb.StringValue{Value: tx.memo},
   539  		}
   540  	}
   541  
   542  	if tx.adminKey != nil {
   543  		body.AdminKey = tx.adminKey._ToProtoKey()
   544  	}
   545  
   546  	if tx.contractID != nil {
   547  		body.ContractID = tx.contractID._ToProtobuf()
   548  	}
   549  
   550  	if tx.stakedAccountID != nil {
   551  		body.StakedId = &services.ContractUpdateTransactionBody_StakedAccountId{StakedAccountId: tx.stakedAccountID._ToProtobuf()}
   552  	} else if tx.stakedNodeID != nil {
   553  		body.StakedId = &services.ContractUpdateTransactionBody_StakedNodeId{StakedNodeId: *tx.stakedNodeID}
   554  	}
   555  
   556  	return body
   557  }
   558  
   559  func (tx *ContractUpdateTransaction) getMethod(channel *_Channel) _Method {
   560  	return _Method{
   561  		transaction: channel._GetContract().UpdateContract,
   562  	}
   563  }
   564  func (tx *ContractUpdateTransaction) _ConstructScheduleProtobuf() (*services.SchedulableTransactionBody, error) {
   565  	return tx.buildScheduled()
   566  }