forked from hiero-ledger/hiero-sdk-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode_delete.py
More file actions
133 lines (103 loc) · 7.81 KB
/
node_delete.py
File metadata and controls
133 lines (103 loc) · 7.81 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
"""
Example demonstrating node deletion on the network.
NOTE: This is a privileged transaction that can only be executed on solo but not on local-node.
Regular developers do not have the required permissions to create or delete
nodes on testnet or mainnet as this operation requires special authorization.
This example is provided to demonstrate the API for educational purposes or for use
in private network deployments where you have the necessary administrative privileges.
Solo is a local development network for Hedera that allows you to run a complete
Hedera network on your machine for testing and development purposes.
Setup options:
1. GitHub repository with full setup instructions: https://github.com/hiero-ledger/solo
2. Official documentation with step-by-step guide: https://solo.hiero.org/v0.43.0/docs/step-by-step-guide/
"""
import sys
from dotenv import load_dotenv
from hiero_sdk_python import AccountId, Client, Network, PrivateKey
from hiero_sdk_python.address_book.endpoint import Endpoint
from hiero_sdk_python.nodes.node_create_transaction import NodeCreateTransaction
from hiero_sdk_python.nodes.node_delete_transaction import NodeDeleteTransaction
from hiero_sdk_python.response_code import ResponseCode
# Gossip certificate is a DER-encoded x509 certificate used for secure communication between nodes.
# This certificate authenticates the node's identity during gossip protocol communication.
# Information about x509 certificates: https://www.ssl.com/faqs/what-is-an-x-509-certificate/
# This command creates a self-signed certificate suitable for development/testing:
# 1. Generate a self-signed certificate with RSA key
# 2. Convert it to DER format (required by Hedera)
# 3. Convert to hex format for use in code
# openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes -subj "/CN=solo" -keyout gossip.key -out gossip.pem && openssl x509 -in gossip.pem -outform DER | xxd -p -c 32 > gossip.hex
GOSSIP_CERTIFICATE = "3082052830820310a003020102020101300d06092a864886f70d01010c05003010310e300c060355040313056e6f6465333024170d3234313030383134333233395a181332313234313030383134333233392e3337395a3010310e300c060355040313056e6f64653330820222300d06092a864886f70d01010105000382020f003082020a0282020100af111cff0c4ad8125d2f4b8691ce87332fecc867f7a94ddc0f3f96514cc4224d44af516394f7384c1ef0a515d29aa6116b65bc7e4d7e2d848cf79fbfffedae3a6583b3957a438bdd780c4981b800676ea509bc8c619ae04093b5fc642c4484152f0e8bcaabf19eae025b630028d183a2f47caf6d9f1075efb30a4248679d871beef1b7e9115382270cbdb68682fae4b1fd592cadb414d918c0a8c23795c7c5a91e22b3e90c410825a2bc1a840efc5bf9976a7f474c7ed7dc047e4ddd2db631b68bb4475f173baa3edc234c4bed79c83e2f826f79e07d0aade2d984da447a8514135bfa4145274a7f62959a23c4f0fae5adc6855974e7c04164951d052beb5d45cb1f3cdfd005da894dea9151cb62ba43f4731c6bb0c83e10fd842763ba6844ef499f71bc67fa13e4917fb39f2ad18112170d31cdcb3c61c9e3253accf703dbd8427fdcb87ece78b787b6cfdc091e8fedea8ad95dc64074e1fc6d0e42ea2337e18a5e54e4aaab3791a98dfcef282e2ae1caec9cf986fabe8f36e6a21c8711647177e492d264415e765a86c58599cd97b103cb4f6a01d2edd06e3b60470cf64daca7aecf831197b466cae04baeeac19840a05394bef628aed04b611cfa13677724b08ddfd662b02fd0ef0af17eb7f4fb8c1c17fbe9324f6dc7bcc02449622636cc45ec04909b3120ab4df4726b21bf79e955fe8f832699d2196dcd7a58bfeafb170203010001a38186308183300f0603551d130101ff04053003020100300e0603551d0f0101ff0404030204b030200603551d250101ff0416301406082b0601050507030106082b06010505070302301d0603551d0e04160414643118e05209035edd83d44a0c368de2fb2fe4c0301f0603551d23041830168014643118e05209035edd83d44a0c368de2fb2fe4c0300d06092a864886f70d01010c05000382020100ad41c32bb52650eb4b76fce439c9404e84e4538a94916b3dc7983e8b5c58890556e7384601ca7440dde68233bb07b97bf879b64487b447df510897d2a0a4e789c409a9b237a6ad240ad5464f2ce80c58ddc4d07a29a74eb25e1223db6c00e334d7a27d32bfa6183a82f5e35bccf497c2445a526eabb0c068aba9b94cc092ea4756b0dcfb574f6179f0089e52b174ccdbd04123eeb6d70daeabd8513fcba6be0bc2b45ca9a69802dae11cc4d9ff6053b3a87fd8b0c6bf72fffc3b81167f73cca2b3fd656c5d353c8defca8a76e2ad535f984870a590af4e28fed5c5a125bf360747c5e7742e7813d1bd39b5498c8eb6ba72f267eda034314fdbc596f6b967a0ef8be5231d364e634444c84e64bd7919425171016fcd9bb05f01c58a303dee28241f6e860fc3aac3d92aad7dac2801ce79a3b41a0e1f1509fc0d86e96d94edb18616c000152490f64561713102128990fedd3a5fa642f2ff22dc11bc4dc5b209986a0c3e4eb2bdfdd40e9fdf246f702441cac058dd8d0d51eb0796e2bea2ce1b37b2a2f468505e1f8980a9f66d719df034a6fbbd2f9585991d259678fb9a4aebdc465d22c240351ed44abffbdd11b79a706fdf7c40158d3da87f68d7bd557191a8016b5b899c07bf1b87590feb4fa4203feea9a2a7a73ec224813a12b7a21e5dc93fcde4f0a7620f570d31fe27e9b8d65b74db7dc18a5e51adc42d7805d4661938"
def setup_client():
"""Initialize and set up the client with operator account"""
load_dotenv()
network = Network(network="solo")
client = Client(network)
# Account 0.0.2 is a special administrative account with
# elevated privileges for network management operations.
# This account has the necessary permissions to create/delete/update nodes
# The private key is intentionally public for local development.
# Note: This setup only works on solo network and will not work on testnet/mainnet.
original_operator_key = PrivateKey.from_string_der(
"302e020100300506032b65700422042091132178e7"
"2057a1d7528025956fe39b0b847f200ab59b2fdd367017f3087137"
)
client.set_operator(AccountId(0, 0, 2), original_operator_key)
return client
def create_node(client):
"""Create a node on the network and return its ID and admin key."""
# Node account ID - this should be an existing account
# that will be associated with the node
account_id = AccountId.from_string("0.0.4")
# Node description
description = "Example node for deletion"
# Create endpoints for node services
gossip_endpoint1 = Endpoint(domain_name="gossip1.example.com", port=50211)
gossip_endpoint2 = Endpoint(domain_name="gossip2.example.com", port=50212)
service_endpoint1 = Endpoint(domain_name="service1.example.com", port=50211)
service_endpoint2 = Endpoint(domain_name="service2.example.com", port=50212)
grpc_proxy_endpoint = Endpoint(domain_name="grpc.example.com", port=50213)
# Generate admin key for the node
admin_key = PrivateKey.generate_ed25519()
# DER encoded x509 certificate
gossip_ca_cert = bytes.fromhex(GOSSIP_CERTIFICATE)
# Create and execute the node creation transaction
receipt = (
NodeCreateTransaction()
.set_account_id(account_id)
.set_description(description)
.set_gossip_endpoints([gossip_endpoint1, gossip_endpoint2])
.set_service_endpoints([service_endpoint1, service_endpoint2])
.set_gossip_ca_certificate(gossip_ca_cert)
.set_admin_key(admin_key.public_key())
.set_grpc_web_proxy_endpoint(grpc_proxy_endpoint)
.set_decline_reward(True)
.freeze_with(client)
.sign(admin_key) # Sign with the admin key
.execute(client)
)
# Confirm successful execution
if receipt.status != ResponseCode.SUCCESS:
print(f"Node creation failed with status: {ResponseCode(receipt.status).name}")
sys.exit(1)
print(f"Node created successfully with ID: {receipt.node_id}")
return receipt.node_id
def node_delete():
"""
Demonstrates node deletion functionality by:
1. Setting up client with operator account
2. Creating a new node on the network
3. Deleting the node
"""
# Set up client with operator account
client = setup_client()
# Create a new node and get its ID
node_id = create_node(client)
# Delete the newly created node
receipt = NodeDeleteTransaction().set_node_id(node_id).execute(client)
# Confirm successful execution
if receipt.status != ResponseCode.SUCCESS:
print(f"Node deletion failed with status: {ResponseCode(receipt.status).name}")
sys.exit(1)
print(f"Node {node_id} deleted successfully!")
if __name__ == "__main__":
node_delete()