Description
When serializing a ContractFunctionResult object using _to_proto(), if the signer_nonce attribute is None (which is its default state), the SDK incorrectly wraps it in a protobuf Int64Value(value=None).
In modern Python protobuf libraries, this silently creates an Int64Value object with the default value of 0 instead of omitting the field entirely.
This breaks the distinction between signer_nonce=0 and "signer_nonce is not present", causing the SDK to silently send a nonce of 0 when no nonce was intended.
Root Cause
In src/hiero_sdk_python/contract/contract_function_result.py around line 510, the _to_proto() method unconditionally wraps self.signer_nonce in a Google Protobuf Int64Value:
def _to_proto(self) -> contract_types_pb2.ContractFunctionResult:
return contract_types_pb2.ContractFunctionResult(
...
signer_nonce=Int64Value(value=self.signer_nonce), # <-- Bug occurs here
...
)
Because self.signer_nonce defaults to None at initialization, Int64Value(value=None) is called. Instead of throwing an error, modern protobuf libraries silently construct an Int64Value populated with the default value (0).
The existing unit tests do not catch this because they explicitly set signer_nonce=10 in the test fixtures.
Fix
Update the _to_proto() method to conditionally wrap signer_nonce, similar to how other optional attributes are handled and matching the logic used in _from_proto().
File:
src/hiero_sdk_python/contract/contract_function_result.py
Before:
signer_nonce=Int64Value(value=self.signer_nonce),
After:
signer_nonce=Int64Value(value=self.signer_nonce)
if self.signer_nonce is not None else None,
Steps to Reproduce
Run the following command:
PYTHONPATH=src python3 -c "from hiero_sdk_python.contract.contract_function_result import ContractFunctionResult; print(ContractFunctionResult()._to_proto())"
Additional Context
Hedera Network
No response
Version
- SDK Version:
main branch
- Python Version:
3.10+
- Protobuf Version:
4.21.12+
Operating System
macOS
Description
When serializing a
ContractFunctionResultobject using_to_proto(), if thesigner_nonceattribute isNone(which is its default state), the SDK incorrectly wraps it in a protobufInt64Value(value=None).In modern Python protobuf libraries, this silently creates an
Int64Valueobject with the default value of0instead of omitting the field entirely.This breaks the distinction between
signer_nonce=0and"signer_nonce is not present", causing the SDK to silently send a nonce of0when no nonce was intended.Root Cause
In
src/hiero_sdk_python/contract/contract_function_result.pyaround line 510, the_to_proto()method unconditionally wrapsself.signer_noncein a Google ProtobufInt64Value:Because
self.signer_noncedefaults toNoneat initialization,Int64Value(value=None)is called. Instead of throwing an error, modern protobuf libraries silently construct anInt64Valuepopulated with the default value (0).The existing unit tests do not catch this because they explicitly set
signer_nonce=10in the test fixtures.Fix
Update the
_to_proto()method to conditionally wrapsigner_nonce, similar to how other optional attributes are handled and matching the logic used in_from_proto().File:
src/hiero_sdk_python/contract/contract_function_result.pyBefore:
After:
Steps to Reproduce
Run the following command:
PYTHONPATH=src python3 -c "from hiero_sdk_python.contract.contract_function_result import ContractFunctionResult; print(ContractFunctionResult()._to_proto())"Additional Context
refrence:- hashgraph/hedera-sdk-reference#149
Hedera Network
No response
Version
mainbranch3.10+4.21.12+Operating System
macOS