forked from hiero-ledger/hiero-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathquery_contract_call.py
More file actions
160 lines (127 loc) · 5.31 KB
/
query_contract_call.py
File metadata and controls
160 lines (127 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
Example demonstrating contract call query on the network.
This module shows how to query a contract call on the network by:
1. Setting up a client with operator credentials
2. Creating a file containing contract bytecode
3. Creating a contract using the file
4. Querying the contract call
Usage:
# Due to the way the script is structured, it must be run as a module
# from the project root directory
# Run from the project root directory
uv run -m examples.query_contract_call
python -m examples.query_contract_call
"""
import os
import sys
from dotenv import load_dotenv
from hiero_sdk_python import AccountId, Client, Network, PrivateKey
from hiero_sdk_python.contract.contract_call_query import ContractCallQuery
from hiero_sdk_python.contract.contract_create_transaction import (
ContractCreateTransaction,
)
from hiero_sdk_python.contract.contract_function_parameters import (
ContractFunctionParameters,
)
from hiero_sdk_python.file.file_create_transaction import FileCreateTransaction
from hiero_sdk_python.response_code import ResponseCode
# Import the bytecode for a stateful smart contract (StatefulContract.sol) that can be deployed
# The contract bytecode is pre-compiled from Solidity source code
from .contracts import STATEFUL_CONTRACT_BYTECODE
load_dotenv()
def setup_client():
"""Initialize and set up the client with operator account"""
network = Network(os.getenv('NETWORK'))
client = Client(network)
operator_id = AccountId.from_string(os.getenv("OPERATOR_ID"))
operator_key = PrivateKey.from_string(os.getenv("OPERATOR_KEY"))
client.set_operator(operator_id, operator_key)
return client
def create_contract_file(client):
"""Create a file containing the stateful contract bytecode"""
file_receipt = (
FileCreateTransaction()
.set_keys(client.operator_private_key.public_key())
.set_contents(STATEFUL_CONTRACT_BYTECODE)
.set_file_memo("Stateful contract bytecode file")
.execute(client)
)
# Check if file creation was successful
if file_receipt.status != ResponseCode.SUCCESS:
print(
f"File creation failed with status: {ResponseCode(file_receipt.status).name}"
)
sys.exit(1)
return file_receipt.file_id
def create_contract(client, file_id):
"""Create a contract using the file with constructor parameters"""
initial_message = "Initial message from constructor".encode("utf-8")
constructor_params = ContractFunctionParameters().add_bytes32(initial_message)
receipt = (
ContractCreateTransaction()
.set_admin_key(client.operator_private_key.public_key())
.set_gas(2000000) # 2M gas
.set_bytecode_file_id(file_id)
.set_constructor_parameters(constructor_params)
.set_contract_memo("Stateful smart contract with constructor")
.execute(client)
)
# Check if contract creation was successful
if receipt.status != ResponseCode.SUCCESS:
print(
f"Contract creation failed with status: {ResponseCode(receipt.status).name}"
)
sys.exit(1)
return receipt.contract_id
def query_contract_call():
"""
Demonstrates querying a contract call by:
1. Setting up client with operator account
2. Creating a file containing stateful contract bytecode
3. Creating a contract using the file with constructor parameters
4. Querying the contract call
"""
client = setup_client()
file_id = create_contract_file(client)
contract_id = create_contract(client, file_id)
result = (
ContractCallQuery()
.set_contract_id(contract_id)
.set_gas(2000000)
.set_function(
"getMessageAndOwner"
) # Call the contract's getMessageAndOwner() function
.execute(client)
)
# You can also use set_function_parameters() instead of set_function() e.g.:
# .set_function_parameters(ContractFunctionParameters("getMessageAndOwner"))
# To get data from your contract function results, use the get_* methods
# with the index that matches the position of each return value.
#
# For our function: getMessageAndOwner() returns (bytes32, address)
# - Use index 0 for the first return value (bytes32 message)
# - Use index 1 for the second return value (address owner)
# Get the message (first return value)
# Use get_bytes32(0) for bytes32 values
message = result.get_bytes32(0)
print(f"Message: {message}")
# Get the owner (second return value)
# Use get_address(1) for address values
owner_address = result.get_address(1)
print(f"Owner: {owner_address}\n")
# Another way is get result function
result_function = result.get_result(["bytes32", "address"])
print(f"Message from get_result function: {result_function[0]}")
print(f"Owner from get_result function: {result_function[1]}")
# For different Solidity return types, use these methods:
#
# String values: result.get_string(0)
# Address values: result.get_address(1)
# Number values: result.get_uint256(2)
# Boolean values: result.get_bool(3)
# Bytes32 values: result.get_bytes32(4)
# Bytes values: result.get_bytes(5)
#
# Note: The index number matches the position in your Solidity return statement
if __name__ == "__main__":
query_contract_call()