@@ -94,6 +94,8 @@ def __init__(self, contract_params: ContractCreateParams | None = None):
9494 super ().__init__ ()
9595
9696 params = contract_params or ContractCreateParams ()
97+ if params .gas is not None and params .gas < 0 :
98+ raise ValueError ("Gas cannot be negative" )
9799 self .bytecode_file_id : FileId | None = params .bytecode_file_id
98100 self .proxy_account_id : AccountId | None = params .proxy_account_id
99101 self .admin_key : Key | None = params .admin_key
@@ -115,6 +117,9 @@ def set_bytecode_file_id(self, bytecode_file_id: FileId | None) -> ContractCreat
115117 """
116118 Sets the FileID of the file containing the contract bytecode.
117119
120+ The two bytecode sources share the protobuf initcodeSource oneof, so a
121+ non-None value clears any inline bytecode.
122+
118123 Args:
119124 bytecode_file_id (FileId | None): The FileID of the
120125 bytecode file.
@@ -124,6 +129,8 @@ def set_bytecode_file_id(self, bytecode_file_id: FileId | None) -> ContractCreat
124129 """
125130 self ._require_not_frozen ()
126131 self .bytecode_file_id = bytecode_file_id
132+ if bytecode_file_id is not None :
133+ self .bytecode = None
127134 return self
128135
129136 def set_bytecode (self , code : bytes | None ) -> ContractCreateTransaction :
@@ -133,6 +140,9 @@ def set_bytecode(self, code: bytes | None) -> ContractCreateTransaction:
133140 If the bytecode is small enough, it may be stored directly in the
134141 transaction, otherwise it should be stored in a file.
135142
143+ The two bytecode sources share the protobuf initcodeSource oneof, so a
144+ non-None value clears any bytecode file ID.
145+
136146 Args:
137147 code (bytes | None): The contract bytecode.
138148
@@ -141,7 +151,8 @@ def set_bytecode(self, code: bytes | None) -> ContractCreateTransaction:
141151 """
142152 self ._require_not_frozen ()
143153 self .bytecode = code
144- self .bytecode_file_id = None
154+ if code is not None :
155+ self .bytecode_file_id = None
145156 return self
146157
147158 def set_proxy_account_id (self , proxy_account_id : AccountId | None ) -> ContractCreateTransaction :
@@ -181,8 +192,13 @@ def set_gas(self, gas: int | None) -> ContractCreateTransaction:
181192
182193 Returns:
183194 ContractCreateTransaction: This transaction instance.
195+
196+ Raises:
197+ ValueError: If gas is negative.
184198 """
185199 self ._require_not_frozen ()
200+ if gas is not None and gas < 0 :
201+ raise ValueError ("Gas cannot be negative" )
186202 self .gas = gas
187203 return self
188204
@@ -284,6 +300,9 @@ def set_staked_account_id(self, staked_account_id: AccountId | None) -> Contract
284300 """
285301 Sets the account ID to stake to.
286302
303+ The two staking targets share the protobuf staked_id oneof, so a
304+ non-None value clears any staked node ID.
305+
287306 Args:
288307 staked_account_id (AccountId | None): The staked account ID.
289308
@@ -292,12 +311,17 @@ def set_staked_account_id(self, staked_account_id: AccountId | None) -> Contract
292311 """
293312 self ._require_not_frozen ()
294313 self .staked_account_id = staked_account_id
314+ if staked_account_id is not None :
315+ self .staked_node_id = None
295316 return self
296317
297318 def set_staked_node_id (self , staked_node_id : int | None ) -> ContractCreateTransaction :
298319 """
299320 Sets the node ID to stake to.
300321
322+ The two staking targets share the protobuf staked_id oneof, so a
323+ non-None value clears any staked account ID.
324+
301325 Args:
302326 staked_node_id (int | None): The staked node ID.
303327
@@ -306,6 +330,8 @@ def set_staked_node_id(self, staked_node_id: int | None) -> ContractCreateTransa
306330 """
307331 self ._require_not_frozen ()
308332 self .staked_node_id = staked_node_id
333+ if staked_node_id is not None :
334+ self .staked_account_id = None
309335 return self
310336
311337 def set_decline_reward (self , decline_reward : bool | None ) -> ContractCreateTransaction :
@@ -323,26 +349,25 @@ def set_decline_reward(self, decline_reward: bool | None) -> ContractCreateTrans
323349 self .decline_reward = decline_reward
324350 return self
325351
326- def _validate_parameters (self ):
327- """Validates the parameters for the contract creation transaction."""
328- if self .bytecode_file_id is None and self .bytecode is None :
329- raise ValueError ("Either bytecode_file_id or bytecode must be provided" )
330-
331- if self .gas is None :
332- raise ValueError ("Gas limit must be provided" )
333-
334352 def _build_proto_body (self ):
335353 """
336354 Returns the protobuf body for the contract create transaction.
337355
356+ Missing fields are not validated client-side; the network reports
357+ errors such as CONTRACT_BYTECODE_EMPTY or INSUFFICIENT_GAS.
358+
338359 Returns:
339360 ContractCreateTransactionBody: The protobuf body for this transaction.
340361
341362 Raises:
342- ValueError: If required fields are missing.
343- """
344- self ._validate_parameters ()
345-
363+ ValueError: If both staked_account_id and staked_node_id are set,
364+ or both bytecode and bytecode_file_id are set; each pair shares
365+ a protobuf oneof that would silently drop one of them.
366+ """
367+ if self .staked_account_id is not None and self .staked_node_id is not None :
368+ raise ValueError ("Specify either staked_node_id or staked_account_id, not both." )
369+ if self .bytecode is not None and self .bytecode_file_id is not None :
370+ raise ValueError ("Specify either bytecode or bytecode_file_id, not both." )
346371 return ContractCreateTransactionBody (
347372 gas = self .gas ,
348373 initialBalance = self .initial_balance ,
0 commit comments