forked from hiero-ledger/hiero-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontract_execute.py
More file actions
172 lines (135 loc) · 5.6 KB
/
contract_execute.py
File metadata and controls
172 lines (135 loc) · 5.6 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
161
162
163
164
165
166
167
168
169
170
171
172
"""
Example demonstrating contract execute on the network.
This module shows how to execute a contract 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. Executing a contract function
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.contract_execute
python -m examples.contract_execute
"""
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_execute_transaction import (
ContractExecuteTransaction,
)
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 = "This is the initial message!".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)
print(f"Contract created with ID: {receipt.contract_id}")
return receipt.contract_id
def get_contract_message(client, contract_id):
"""Get the message from the contract"""
# Query the contract function to verify that the message was set
result = (
ContractCallQuery()
.set_contract_id(contract_id)
.set_gas(2000000)
.set_function("getMessage")
.execute(client)
)
# The contract returns bytes32, which we decode to string
# This removes any padding and converts to readable text
return result.get_bytes32(0).decode("utf-8")
def execute_contract():
"""
Demonstrates executing a contract 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. Getting the current message from the contract
5. Executing a contract function to set the new message
6. Querying the contract function to verify that the message was set
"""
client = setup_client()
file_id = create_contract_file(client)
contract_id = create_contract(client, file_id)
# Get the current message from the contract
current_message = get_contract_message(client, contract_id)
print(f"Initial contract message (from constructor): '{current_message}'")
new_message_bytes = b"This is the updated message!"
new_message_string = new_message_bytes.decode("utf-8") # For display
# Set the new message from the contract
receipt = (
ContractExecuteTransaction()
.set_contract_id(contract_id)
.set_gas(2000000)
.set_function(
"setMessage",
ContractFunctionParameters().add_bytes32(new_message_bytes),
) # Call the contract's setMessage() function with the parameter b"New message to set"
.execute(client)
)
if receipt.status != ResponseCode.SUCCESS:
print(
f"Contract execution failed with status: {ResponseCode(receipt.status).name}"
)
sys.exit(1)
print(
f"Successfully executed setMessage() on {contract_id} with new message: "
f"'{new_message_string}'"
)
# Query the contract function to verify that the message was set
updated_message = get_contract_message(client, contract_id)
print(f"Retrieved message from contract getMessage(): '{updated_message}'")
if __name__ == "__main__":
execute_contract()