Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.

### Added

- Refactored `account_create_transaction_evm_alias.py` example by splitting monolithic function into modular functions: `generate_alias_key()`, `create_account_with_alias()`, `fetch_account_info()`, `print_account_summary()` (#1017)
- Modularized `transfer_transaction_fungible` example by introducing `account_balance_query()` & `transfer_transaction()`.Renamed `transfer_tokens()` → `main()`
- Phase 2 of the inactivity-unassign bot:Automatically detects stale open pull requests (no commit activity for 21+ days), comments with a helpful InactivityBot message, closes the stale PR, and unassigns the contributor from the linked issue.
- Added `__str__()` to CustomFixedFee and updated examples and tests accordingly.
Expand Down
142 changes: 99 additions & 43 deletions examples/account/account_create_transaction_evm_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
load_dotenv()
network_name = os.getenv('NETWORK', 'testnet').lower()


def setup_client():
"""Setup Client """
"""Setup Client."""
network = Network(network_name)
print(f"Connecting to Hedera {network_name} network!")
client = Client(network)
Expand All @@ -42,59 +43,114 @@ def setup_client():
print("Error: Please check OPERATOR_ID and OPERATOR_KEY in your .env file.")
sys.exit(1)

def create_account_with_alias(client):
"""Create an account with an alias transaction."""
try:
print("\nSTEP 1: Generating a new ECDSA key pair for the account alias...")
private_key = PrivateKey.generate('ecdsa')
public_key = private_key.public_key()
evm_address = public_key.to_evm_address()
if evm_address is None:
print("❌ Error: Failed to generate EVM address from public key.")
sys.exit(1)
print(f"✅ Generated new ECDSA key pair. EVM Address (alias): {evm_address}")
# Create the account with the alias
print("\nSTEP 2: Creating the account with the EVM address alias...")
transaction = (
AccountCreateTransaction()
.set_key(public_key)
.set_initial_balance(Hbar(5))
.set_alias(evm_address)
)

# Sign the transaction with both the new key and the operator key
transaction = transaction.freeze_with(client) \
.sign(private_key) \
.sign(client.operator_private_key)

# Execute the transaction
response = transaction.execute(client)
new_account_id = response.account_id
print(f"✅ Account created with ID: {new_account_id}\n")
# Fetch and display account info
account_info = AccountInfoQuery().set_account_id(new_account_id).execute(client)
# Print the account info
out = info_to_dict(account_info)
print("🧾 Account Info:")
print(json.dumps(out, indent=2) + "\n")
if account_info.contract_account_id is not None:
print(f"✅ Contract Account ID (alias): {account_info.contract_account_id}")
else:
print("❌ Error: Contract Account ID (alias) does not exist.")
def generate_alias_key() -> PrivateKey:
"""Generate an ECDSA key pair for the account alias.

except Exception as error:
print(f"❌ Error: {error}")
Returns:
PrivateKey: The generated ECDSA private key.
"""
print("\nSTEP 1: Generating a new ECDSA key pair for the account alias...")
private_key = PrivateKey.generate('ecdsa')
public_key = private_key.public_key()
evm_address = public_key.to_evm_address()

if evm_address is None:
print("❌ Error: Failed to generate EVM address from public key.")
sys.exit(1)

print(f"✅ Generated new ECDSA key pair. EVM Address (alias): {evm_address}")
return private_key


def create_account_with_alias(client: Client, private_key: PrivateKey) -> AccountId:
"""Create an account with an EVM address alias.

Args:
client: The Hedera client.
private_key: The ECDSA private key for the account.

Returns:
AccountId: The newly created account ID.
"""
print("\nSTEP 2: Creating the account with the EVM address alias...")

public_key = private_key.public_key()
evm_address = public_key.to_evm_address()

transaction = (
AccountCreateTransaction()
.set_key(public_key)
.set_initial_balance(Hbar(5))
.set_alias(evm_address)
)

# Sign the transaction with both the new key and the operator key
transaction = transaction.freeze_with(client) \
.sign(private_key) \
.sign(client.operator_private_key)

# Execute the transaction
response = transaction.execute(client)
new_account_id = response.account_id

if new_account_id is None:
raise RuntimeError(
"AccountID not found in receipt. Account may not have been created."
)

print(f"✅ Account created with ID: {new_account_id}\n")
return new_account_id


def fetch_account_info(client: Client, account_id: AccountId):
"""Fetch account information from the network.

Args:
client: The Hedera client.
account_id: The account ID to query.

Returns:
The account info object.
"""
print("STEP 3: Fetching account information...")
account_info = AccountInfoQuery().set_account_id(account_id).execute(client)
return account_info


def print_account_summary(account_info) -> None:
"""Print a summary of the account information.

Args:
account_info: The account info object to display.
"""
out = info_to_dict(account_info)
print("🧾 Account Info:")
print(json.dumps(out, indent=2) + "\n")

if account_info.contract_account_id is not None:
print(f"✅ Contract Account ID (alias): {account_info.contract_account_id}")
else:
print("❌ Error: Contract Account ID (alias) does not exist.")


def main():
"""Main function to create an account with an alias transaction.

1- Setup client
2- Generate ECDSA key pair and EVM address alias
3- Create account with alias
4- Print account info
"""
client = setup_client()
create_account_with_alias(client)
try:
client = setup_client()
private_key = generate_alias_key()
account_id = create_account_with_alias(client, private_key)
account_info = fetch_account_info(client, account_id)
print_account_summary(account_info)
except Exception as error:
print(f"❌ Error: {error}")
sys.exit(1)


if __name__ == "__main__":
Expand Down