/**
 * # Contract Update
 * Modify a smart contract. Any change other than updating the expiration time
 * requires that the contract be modifiable (has a valid `adminKey`) and that
 * the transaction be signed by the `adminKey`
 *
 * ### Keywords
 * The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
 * "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
 * document are to be interpreted as described in
 * [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
 * [RFC8174](https://www.ietf.org/rfc/rfc8174).
 */
syntax = "proto3";

package proto;

// SPDX-License-Identifier: Apache-2.0
option java_package = "com.hederahashgraph.api.proto.java";
// <<<pbj.java_package = "com.hedera.hapi.node.contract">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

import "services_basic_types.proto";
import "services_duration.proto";
import "services_hook_types.proto";
import "services_timestamp.proto";
import "google/protobuf/wrappers.proto";

/**
 * Modify the current state of a smart contract.
 *
 * ### Requirements
 * - The `adminKey` MUST sign all contract update transactions except one
 *   that only updates the `expirationTime`.
 * - A transaction that modifies any field other than `expirationTime` for
 *   a contract without a valid `adminKey` set SHALL fail with response
 *   code `MODIFYING_IMMUTABLE_CONTRACT`.
 * - Fields set to non-default values in this transaction SHALL be updated on
 *   success. Fields not set to non-default values SHALL NOT be
 *   updated on success.
 *
 * ### Block Stream Effects
 * None
 */
message ContractUpdateTransactionBody {
    /**
     * The contact ID that identifies the smart contract to be updated.<br/>
     * This field MUST be set, and MUST NOT be a default ID (`0.0.0`).
     */
    ContractID contractID = 1;

    /**
     * If set, modify the time at which this contract will expire.<br/>
     * An expired contract requires a rent payment to "renew" the contract.
     * A transaction to update this field is how that rent payment is made.
     * <p>
     * This value MUST NOT be less than the current `expirationTime`
     * of the contract. If this value is earlier than the current
     * value, the transaction SHALL fail with response
     * code `EXPIRATION_REDUCTION_NOT_ALLOWED`.
     */
    Timestamp expirationTime = 2;

    /**
     * If set, modify the key that authorizes updates to the contract.
     * <p>
     * If this field is set to a valid Key, this key and the previously set key
     * MUST both sign this transaction.<br/>
     * If this value is an empty `KeyList`, the prior key MUST sign this
     * transaction, and the smart contract SHALL be immutable after this
     * transaction completes, except for expiration and renewal.<br/>
     * If this value is not an empty `KeyList`, but does not contain any
     * cryptographic keys, or is otherwise malformed, this transaction SHALL
     * fail with response code `INVALID_ADMIN_KEY`.
     */
    Key adminKey = 3;

    /**
     * Replaced with `staked_id` alternatives.
     * This field is unused and SHALL NOT modify the contract state.<br/>
     * The id of an account to which the contract is proxy staked
     */
    AccountID proxyAccountID = 6 [deprecated = true];

    /**
     * If set, modify the duration added to expiration time by each
     * auto-renewal to this value.
     */
    Duration autoRenewPeriod = 7;

    /**
     * This field is unused and SHALL NOT modify the contract state.<br/>
     * Previously, an ID of a file containing the bytecode of the Solidity
     * transaction that created this contract.
     */
    FileID fileID = 8 [deprecated = true];

    // This should be condensed to just a field instead of a oneof and field 9 reserved.
    oneof memoField {
        /**
         * This value could not accurately distinguish unset or deliberately
         * empty. memoWrapper should be used instead.<br/>
         */
        string memo = 9 [deprecated = true];

        /**
         * If set, modify the short memo for this smart contract.
         * <p>
         * This value, if set, MUST NOT exceed `transaction.maxMemoUtf8Bytes`
         * (default 100) bytes when encoded as UTF-8.
         */
        google.protobuf.StringValue memoWrapper = 10;
    }

    /**
     * If set, modify the maximum number of tokens that can be auto-associated with the
     * contract.
     * <p>
     * If this is set and less than or equal to `used_auto_associations`, or 0, then this contract
     * MUST manually associate with a token before transacting in that token.<br/>
     * This value MAY also be `-1` to indicate no limit.<br/>
     * This value MUST NOT be less than `-1`.
     */
    google.protobuf.Int32Value max_automatic_token_associations = 11;

    /**
     * If set, modify the account, in the same shard and realm as this smart
     * contract, that has agreed to allow the network to use its balance, when
     * needed, to automatically extend this contract's expiration time.
     * <p>
     * If this field is set to a non-default value, that Account MUST sign this
     * transaction.<br/>
     * If this field is set to a default AccountID value (`0.0.0`), any
     * pre-existing `auto_renew_account_id` value SHALL be removed on success.
     */
    AccountID auto_renew_account_id = 12;

    oneof staked_id {
        /**
         * An account identifier.<br/>
         * A staked account acts as a proxy, and this contract effectively
         * nominates the same node as the identified account.
         * <p>
         * If set, modify this smart contract such that it SHALL stake its HBAR
         * to the same node as the identified account.<br/>
         * If this field is set to a default AccountID value (`0.0.0`), any
         * pre-existing `staked_account_id` value SHALL be removed on success.
         */
        AccountID staked_account_id = 13;

        /**
         * A node identifier.<br/>
         * A staked node identifier indicates the consensus node that this
         * account nominates for staking.
         * <p>
         * If set, modify this smart contract such that it SHALL stake its HBAR
         * to this node.
         * If set to a the value `-1` any pre-existing `staked_node_id` value
         * SHALL be removed on success.
         * <p>
         * <blockquote>Note: node IDs do fluctuate as node operators change.
         * Most contracts are immutable, and a contract staking to an invalid
         * node ID SHALL NOT participate in staking. Immutable contracts may
         * find it more reliable to use a proxy account for staking (via
         * `staked_account_id`) to enable updating the _effective_ staking node
         * ID when necessary through updating the proxy account.</blockquote>
         */
        int64 staked_node_id = 14;
    }

    /**
     * A flag indicating if staking rewards are declined.<br/>
     * If set, modify the flag indicating if this contract declines to accept
     * rewards for staking its HBAR to secure the network.
     * <p>
     * If set to true, this smart contract SHALL NOT receive any reward for
     * staking its HBAR balance to help secure the network, regardless of
     * staking configuration, but MAY stake HBAR to support the network
     * without reward.
     */
    google.protobuf.BoolValue decline_reward = 15;

    /**
     * The ids the hooks to delete from the contract.
     */
    repeated int64 hook_ids_to_delete = 16;

    /**
     * The hooks to create for the contract.
     */
    repeated com.hedera.hapi.node.hooks.HookCreationDetails hook_creation_details = 17;
}
