2424
2525using namespace Hiero ;
2626
27+ static const std::string kContractBytecodeHex =
28+ " 608060405234801561001057600080fd5b50600436106100365760003560e01c8063c29855781461003b578063f2fde38b14610059575b60"
29+ " 0080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61"
30+ " 007b565b005b60005481565b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffff"
31+ " ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722"
32+ " a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff0219"
33+ " 16908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000819050919050565b61009b81610088565b82525050"
34+ " 565b60006020820190506100b66000830184610092565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffff"
35+ " ff82169050919050565b60006100e7826100bc565b9050919050565b6100f7816100dc565b811461010257600080fd5b50565b6000813590"
36+ " 50610114816100ee565b92915050565b6000602082840312156101305761012f6100bc565b5b600061013e84828501610105565b91505092"
37+ " 91505056fea2646970667358221220" ;
38+
2739ContractId createHookContract (Client& client, const std::shared_ptr<PrivateKey>& operatorKey)
2840{
29- const std::vector<std::byte> contractBytecode = internal::HexConverter::hexToBytes (
30- " 608060405234801561001057600080fd5b50600436106100365760003560e01c8063c29855781461003b578063f2fde38b14610059575b60"
31- " 0080fd5b610043610075565b60405161005091906100a1565b60405180910390f35b610073600480360381019061006e91906100ed565b61"
32- " 007b565b005b60005481565b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffff"
33- " ffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722"
34- " a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff0219"
35- " 16908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000819050919050565b61009b81610088565b82525050"
36- " 565b60006020820190506100b66000830184610092565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffff"
37- " ff82169050919050565b60006100e7826100bc565b9050919050565b6100f7816100dc565b811461010257600080fd5b50565b6000813590"
38- " 50610114816100ee565b92915050565b6000602082840312156101305761012f6100bc565b5b600061013e84828501610105565b91505092"
39- " 91505056fea2646970667358221220" );
40-
4141 std::cout << " Creating hook contract..." << std::endl;
4242 const TransactionReceipt txReceipt = ContractCreateTransaction ()
4343 .setAdminKey (operatorKey->getPublicKey ())
4444 .setGas (500000ULL )
45- .setBytecode (contractBytecode )
45+ .setBytecode (internal::HexConverter::hexToBytes ( kContractBytecodeHex ) )
4646 .execute (client)
4747 .getReceipt (client);
4848
@@ -51,144 +51,134 @@ ContractId createHookContract(Client& client, const std::shared_ptr<PrivateKey>&
5151 throw std::runtime_error (" Failed to create hook contract!" );
5252 }
5353
54- const ContractId contractId = txReceipt.mContractId .value ();
55- std::cout << " Hook contract created with ID: " << contractId.toString () << std::endl;
56- return contractId;
54+ std::cout << " Hook contract created with ID: " << txReceipt.mContractId .value ().toString () << std::endl;
55+ return txReceipt.mContractId .value ();
5756}
5857
5958std::pair<AccountId, std::shared_ptr<PrivateKey>> createAccountWithHook (Client& client,
6059 const ContractId& contractId,
6160 const std::shared_ptr<PublicKey>& adminKey)
6261{
6362 const std::shared_ptr<PrivateKey> accountKey = ED25519PrivateKey::generatePrivateKey ();
64-
6563 EvmHookSpec evmHookSpec;
6664 evmHookSpec.setContractId (contractId);
6765 EvmHook evmHook;
6866 evmHook.setEvmHookSpec (evmHookSpec);
69-
7067 HookCreationDetails hookWithId1002;
7168 hookWithId1002.setExtensionPoint (HookExtensionPoint::ACCOUNT_ALLOWANCE_HOOK);
7269 hookWithId1002.setHookId (1002LL );
7370 hookWithId1002.setEvmHook (evmHook);
7471 hookWithId1002.setAdminKey (adminKey);
75-
7672 const TransactionReceipt txReceipt = AccountCreateTransaction ()
7773 .setKeyWithoutAlias (accountKey->getPublicKey ())
7874 .setInitialBalance (Hbar (1ULL ))
7975 .addHook (hookWithId1002)
8076 .execute (client)
8177 .getReceipt (client);
82-
8378 if (!txReceipt.mAccountId .has_value ())
8479 {
8580 throw std::runtime_error (" Failed to create account with hook!" );
8681 }
87-
8882 std::cout << " account id = " << txReceipt.mAccountId .value ().toString () << std::endl;
8983 std::cout << " Successfully created account with hook!" << std::endl;
9084 return { txReceipt.mAccountId .value (), accountKey };
9185}
9286
87+ void addHooksToAccount (Client& client,
88+ const AccountId& accountId,
89+ const std::shared_ptr<PrivateKey>& accountKey,
90+ const EvmHookSpec& evmHookSpec,
91+ const std::shared_ptr<PublicKey>& adminKey)
92+ {
93+ std::cout << " \n === Adding Hooks to Existing Account ===" << std::endl;
94+ EvmHook hook1;
95+ hook1.setEvmHookSpec (evmHookSpec);
96+ HookCreationDetails hookWithId1;
97+ hookWithId1.setExtensionPoint (HookExtensionPoint::ACCOUNT_ALLOWANCE_HOOK);
98+ hookWithId1.setHookId (1LL );
99+ hookWithId1.setEvmHook (hook1);
100+ hookWithId1.setAdminKey (adminKey);
101+ EvmHook hook2;
102+ hook2.setEvmHookSpec (evmHookSpec);
103+ HookCreationDetails hookWithId2;
104+ hookWithId2.setExtensionPoint (HookExtensionPoint::ACCOUNT_ALLOWANCE_HOOK);
105+ hookWithId2.setHookId (2LL );
106+ hookWithId2.setEvmHook (hook2);
107+ hookWithId2.setAdminKey (adminKey);
108+ try
109+ {
110+ AccountUpdateTransaction ()
111+ .setAccountId (accountId)
112+ .addHookToCreate (hookWithId1)
113+ .addHookToCreate (hookWithId2)
114+ .freezeWith (&client)
115+ .sign (accountKey)
116+ .execute (client)
117+ .getReceipt (client);
118+ std::cout << " Successfully added hooks to account!" << std::endl;
119+ }
120+ catch (const std::exception& error)
121+ {
122+ std::cerr << " Failed to execute hook transaction: " << error.what () << std::endl;
123+ }
124+ }
125+
126+ void deleteHooksFromAccount (Client& client, const AccountId& accountId, const std::shared_ptr<PrivateKey>& accountKey)
127+ {
128+ std::cout << " \n === Deleting Hooks from Account ===" << std::endl;
129+ try
130+ {
131+ AccountUpdateTransaction ()
132+ .setAccountId (accountId)
133+ .addHookToDelete (1LL )
134+ .addHookToDelete (2LL )
135+ .freezeWith (&client)
136+ .sign (accountKey)
137+ .execute (client)
138+ .getReceipt (client);
139+ std::cout << " Successfully deleted hooks (IDs: 1, 2)" << std::endl;
140+ }
141+ catch (const std::exception& error)
142+ {
143+ std::cerr << " Failed to execute hook deletion: " << error.what () << std::endl;
144+ }
145+ }
146+
147+ void run (Client& client, const std::shared_ptr<PrivateKey>& operatorKey)
148+ {
149+ std::cout << " Account Hooks Example Start!" << std::endl;
150+ const ContractId contractId = createHookContract (client, operatorKey);
151+ std::cout << " \n === Creating Account with Hooks ===" << std::endl;
152+ const std::shared_ptr<PublicKey> adminKey = client.getOperatorPublicKey ();
153+ const auto [accountId, accountKey] = createAccountWithHook (client, contractId, adminKey);
154+ EvmHookSpec evmHookSpec;
155+ evmHookSpec.setContractId (contractId);
156+ addHooksToAccount (client, accountId, accountKey, evmHookSpec, adminKey);
157+ deleteHooksFromAccount (client, accountId, accountKey);
158+ std::cout << " Account Hooks Example Complete!" << std::endl;
159+ }
160+
93161int main (int argc, char ** argv)
94162{
95163 dotenv::init ();
96-
97164 if (std::getenv (" OPERATOR_ID" ) == nullptr || std::getenv (" OPERATOR_KEY" ) == nullptr ||
98165 std::getenv (" NETWORK_NAME" ) == nullptr )
99166 {
100167 std::cerr << " Environment variables OPERATOR_ID, NETWORK_NAME, and OPERATOR_KEY are required." << std::endl;
101168 return 1 ;
102169 }
103-
104- const AccountId operatorAccountId = AccountId::fromString (std::getenv (" OPERATOR_ID" ));
105- const std::shared_ptr<PrivateKey> operatorPrivateKey = ED25519PrivateKey::fromString (std::getenv (" OPERATOR_KEY" ));
106- const std::string network = std::getenv (" NETWORK_NAME" );
107-
108- Client client = Client::forName (network);
109- client.setOperator (operatorAccountId, operatorPrivateKey);
110-
170+ Client client = Client::forName (std::getenv (" NETWORK_NAME" ));
171+ client.setOperator (AccountId::fromString (std::getenv (" OPERATOR_ID" )),
172+ ED25519PrivateKey::fromString (std::getenv (" OPERATOR_KEY" )));
111173 try
112174 {
113- std::cout << " Account Hooks Example Start!" << std::endl;
114-
115- const ContractId contractId = createHookContract (client, operatorPrivateKey);
116-
117- std::cout << " \n === Creating Account with Hooks ===" << std::endl;
118- const std::shared_ptr<PublicKey> adminKey = client.getOperatorPublicKey ();
119- const auto [accountId, accountKey] = createAccountWithHook (client, contractId, adminKey);
120-
121- EvmHookSpec evmHookSpec;
122- evmHookSpec.setContractId (contractId);
123-
124- /*
125- * Step 3: Demonstrate adding hooks to an existing account.
126- */
127- std::cout << " \n === Adding Hooks to Existing Account ===" << std::endl;
128-
129- EvmHook basicHook;
130- basicHook.setEvmHookSpec (evmHookSpec);
131- HookCreationDetails hookWithId1;
132- hookWithId1.setExtensionPoint (HookExtensionPoint::ACCOUNT_ALLOWANCE_HOOK);
133- hookWithId1.setHookId (1LL );
134- hookWithId1.setEvmHook (basicHook);
135- hookWithId1.setAdminKey (adminKey);
136-
137- EvmHook basicHook2;
138- basicHook2.setEvmHookSpec (evmHookSpec);
139- HookCreationDetails hookWithId2;
140- hookWithId2.setExtensionPoint (HookExtensionPoint::ACCOUNT_ALLOWANCE_HOOK);
141- hookWithId2.setHookId (2LL );
142- hookWithId2.setEvmHook (basicHook2);
143- hookWithId2.setAdminKey (adminKey);
144-
145- try
146- {
147- AccountUpdateTransaction ()
148- .setAccountId (accountId)
149- .addHookToCreate (hookWithId1)
150- .addHookToCreate (hookWithId2)
151- .freezeWith (&client)
152- .sign (accountKey)
153- .execute (client)
154- .getReceipt (client);
155- std::cout << " Successfully added hooks to account!" << std::endl;
156- }
157- catch (const std::exception& error)
158- {
159- std::cerr << " Failed to execute hook transaction: " << error.what () << std::endl;
160- }
161-
162- /*
163- * Step 4: Demonstrate hook deletion.
164- */
165- std::cout << " \n === Deleting Hooks from Account ===" << std::endl;
166-
167- try
168- {
169- AccountUpdateTransaction ()
170- .setAccountId (accountId)
171- .addHookToDelete (1LL )
172- .addHookToDelete (2LL )
173- .freezeWith (&client)
174- .sign (accountKey)
175- .execute (client)
176- .getReceipt (client);
177- std::cout << " Successfully deleted hooks (IDs: 1, 2)" << std::endl;
178- }
179- catch (const std::exception& error)
180- {
181- std::cerr << " Failed to execute hook deletion: " << error.what () << std::endl;
182- }
183-
184- std::cout << " Account Hooks Example Complete!" << std::endl;
175+ run (client, ED25519PrivateKey::fromString (std::getenv (" OPERATOR_KEY" )));
185176 }
186177 catch (const std::exception& error)
187178 {
188179 std::cerr << " Error occurred: " << error.what () << std::endl;
189180 return 1 ;
190181 }
191-
192182 client.close ();
193183 return 0 ;
194184}
0 commit comments