@@ -684,6 +684,9 @@ def call_contract_function(contract_address: str, chain_id: str, function_name:
684684 raise Exception (
685685 f"Function '{ function_name } ' is not a read-only function and might modify state or require a transaction." )
686686
687+ # Get function outputs for later use
688+ function_outputs = function_entry .get ('outputs' , [])
689+
687690 # Call the function with provided parameters
688691 result = function_obj (* function_params ).call ()
689692
@@ -697,41 +700,44 @@ def call_contract_function(contract_address: str, chain_id: str, function_name:
697700 elif isinstance (result , bytes ):
698701 processed_result = web3 .to_hex (result )
699702 result_type = "bytes (hex)"
700- elif isinstance (result , tuple ):
701- # Handle named tuples (common in Solidity returns)
702- if hasattr (result , '_asdict' ):
703- processed_result = dict (result ._asdict ())
704- result_type = "struct"
705- else :
706- processed_result = list (result )
707- result_type = "tuple"
708-
709- # Convert any bytes in the result to hex
710- if isinstance (processed_result , dict ):
711- for key , value in processed_result .items ():
703+ # Handle both tuple and list results - Web3.py may return either depending on the version
704+ elif isinstance (result , (tuple , list )):
705+ # If we have output definitions, create a dictionary with proper names
706+ if function_outputs and len (function_outputs ) == len (result ):
707+ processed_result = {}
708+ for i , output in enumerate (function_outputs ):
709+ output_name = output .get ('name' )
710+ if not output_name : # If name is empty, use index
711+ output_name = f"output_{ i } "
712+
713+ value = result [i ]
714+ processed_result [output_name ] = value
715+
716+ # Handle special types
712717 if isinstance (value , bytes ):
713- processed_result [key ] = web3 .to_hex (value )
714- # Large ints might be wei values
718+ processed_result [output_name ] = web3 .to_hex (value )
719+ # For large integers, preserve the original value
720+ # but also provide the ether conversion for convenience
715721 elif isinstance (value , int ) and value > 10 ** 10 :
716- processed_result [f"{ key } _eth" ] = web3 .from_wei (
722+ processed_result [f"{ output_name } _eth" ] = web3 .from_wei (
717723 value , 'ether' )
718- elif isinstance (processed_result , list ):
724+
725+ result_type = "struct"
726+ else :
727+ # Fallback to list if we can't match outputs
728+ processed_result = list (result )
719729 processed_result = [web3 .to_hex (v ) if isinstance (
720730 v , bytes ) else v for v in processed_result ]
721- elif isinstance (result , list ):
722- processed_result = result
723- result_type = "array"
724- # Convert any bytes in the list to hex
725- for i , item in enumerate (processed_result ):
726- if isinstance (item , bytes ):
727- processed_result [i ] = web3 .to_hex (item )
731+ result_type = "tuple"
728732
729- return {
733+ response = {
730734 "success" : True ,
731735 "result" : processed_result ,
732- "result_type" : result_type
736+ "result_type" : function_outputs ,
733737 }
734738
739+ return response
740+
735741 except Exception as e :
736742 return {
737743 "success" : False ,
0 commit comments