Managing Ethereum accounts programmatically is a foundational skill for blockchain developers. The eth-account library offers a robust, secure, and flexible toolkit for handling private keys, signing transactions, and working with cryptographic identities—all without requiring a live connection to an Ethereum node. This guide dives deep into the core features of eth-account, empowering developers to build secure and efficient decentralized applications.
Core Functionalities of the Account Class
The Account class is the primary interface for Ethereum account operations in the eth-account library. It enables developers to create, manage, and interact with Ethereum key pairs directly from Python code.
Creating New Accounts
To generate a new Ethereum account, use the create() method:
from eth_account import Account
acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530')
print(acct.address) # '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E'
print(acct.key) # HexBytes private keyThe optional extra_entropy parameter adds additional randomness during key generation, enhancing security by supplementing the OS-provided entropy.
👉 Discover how secure wallet integration can streamline your dApp development
Working with Mnemonics (Experimental)
For mnemonic-based account generation—commonly used in HD wallets—eth-account provides experimental support via BIP39 standards:
Account.enable_unaudited_hdwallet_features()
acct, mnemonic = Account.create_with_mnemonic()
print(acct.address)
print(mnemonic)You can later recover the same account using the mnemonic:
recovered_acct = Account.from_mnemonic(mnemonic)
assert acct == recovered_acctThis feature supports customizable word counts (12, 15, 18, 21, or 24 words), multiple languages, and custom derivation paths like m/44'/60'/0'/0/0.
Caution: These HD wallet features are marked as experimental and unaudited. Use them only in non-production environments.
Multiple Accounts from One Mnemonic
A single mnemonic can derive multiple accounts using different derivation paths:
for i in range(10):
acct = Account.from_mnemonic(
"health embark april buyer eternal leopard want before nominee head thing tackle",
account_path=f"m/44'/60'/0'/0/{i}"
)
print(acct.address)This enables deterministic wallet systems where users can manage several addresses from one recovery phrase.
Encrypting and Decrypting Private Keys
Security is paramount when handling private keys. The eth-account library includes built-in methods for encrypting keys using industry-standard algorithms.
Encrypting a Private Key
Use encrypt() to secure your private key with a password:
encrypted = Account.encrypt(private_key, 'my_secure_password')By default, it uses the scrypt key derivation function (KDF), though pbkdf2 is also supported. The resulting dictionary can be saved as a JSON file compatible with Ethereum clients like Geth or Parity.
Decrypting a Key File
To unlock an encrypted key:
private_key = Account.decrypt(encrypted_json, 'my_secure_password')This returns the raw private key as a HexBytes object, which can then be used to instantiate a local account.
Signing Transactions and Messages
One of the most critical functions in blockchain development is securely signing data. eth-account supports multiple signing standards.
Signing Transactions
Use sign_transaction() to sign Ethereum transactions locally:
tx = {
"to": "0xF0109fC8DF283027b6285cc889F5aA624EaC1F55",
"value": 1000000000,
"gas": 2000000,
"gasPrice": 234567897654321,
"nonce": 0,
"chainId": 1337
}
signed = Account.sign_transaction(tx, private_key)It supports all transaction types:
- Legacy (
gasPrice) - EIP-1559 (
maxFeePerGas,maxPriorityFeePerGas) - Access List (Type 1)
- Blob Transactions (Type 3)
The output includes the signed raw transaction ready for broadcasting via Web3.py.
Signing Messages
Securely sign arbitrary messages using EIP-191 or EIP-712 standards.
Basic Message Signing
from eth_account.messages import encode_defunct
msg = encode_defunct(text="I♥SF")
signed = Account.sign_message(msg, private_key)This format maintains compatibility with older systems like web3.eth.sign().
Structured Data Signing (EIP-712)
For signing typed data (e.g., off-chain orders), use sign_typed_data():
domain_data = {"name": "Ether Mail", "version": "1", "chainId": 1}
message_types = {"Mail": [{"name": "contents", "type": "string"}]}
message_data = {"contents": "Hello, Bob!"}
signed = Account.sign_typed_data(private_key, domain_data, message_types, message_data)This ensures users know exactly what they're signing, reducing phishing risks.
Recovering Signer Information
Verifying the authenticity of signed data is essential. eth-account allows you to recover the signer’s address from signatures.
Recovering from Message Signatures
signer = Account.recover_message(signed_message, vrs=vrs_tuple)You can pass either the (v, r, s) components or the full signature bytes.
Recovering from Transaction Signatures
Given a serialized transaction, extract the sender:
sender = Account.recover_transaction(raw_transaction_hex)This is useful for validating transaction origins in smart contracts or indexing services.
Advanced Features and Security Considerations
Unsafe Hash Signing (Use with Caution)
While unsafe_sign_hash() allows direct signing of message hashes, it should be avoided unless absolutely necessary:
# ⚠️ Dangerous – never sign untrusted hashes
Account.unsafe_sign_hash(hash_value, private_key)Signing raw hashes exposes users to transaction replay attacks and malicious payloads. Always prefer structured message encoding.
EIP-7702 Authorization Signing
For next-generation account abstraction features like EIP-7702, use sign_authorization():
auth = {"chainId": 1337, "address": contract_addr, "nonce": 1}
signed_auth = Account.sign_authorization(auth, private_key)This enables smart contract code association with EOAs (Externally Owned Accounts) within a transaction lifecycle.
Frequently Asked Questions
Is eth-account safe to use in production?
Yes, core functionalities like key generation, encryption, and transaction signing are well-tested and widely adopted. However, experimental features such as HD wallet support (create_with_mnemonic) are not audited and should not be used in production systems.
Can I connect eth-account to a hardware wallet?
No—eth-account manages software-based private keys only. For hardware wallet integration, consider libraries like Web3.py with backend providers that support Ledger or Trezor devices.
What’s the difference between sign_message and sign_typed_data?
sign_message uses EIP-191 and is suitable for simple text or byte messages. sign_typed_data implements EIP-712 and allows structured, human-readable data signing—ideal for signing off-chain trades or authentication tokens safely.
How do I handle different transaction types?
The library automatically detects transaction type based on included fields:
- Include
maxFeePerGas→ EIP-1559 (Type 2) - Include
accessListandgasPrice→ Access List (Type 1) - Include
maxFeePerBlobGas→ Blob Transaction (Type 3)
👉 Learn how modern wallet infrastructure powers scalable dApps today
Can I use eth-account without Web3.py?
Absolutely. While often used alongside Web3.py, eth-account operates independently. You can sign transactions offline and broadcast them later through any Ethereum node interface.
How does entropy affect key generation?
Higher entropy increases randomness during private key creation. While the OS typically provides sufficient entropy, adding extra input via create(extra_entropy=...) may improve security in constrained environments.
Final Thoughts
The eth-account library is an indispensable tool for Python developers building on Ethereum. Its clean API, strong cryptographic foundations, and support for modern signing standards make it ideal for creating wallets, signing services, and decentralized applications. By understanding its capabilities—and respecting its experimental boundaries—you can build secure, scalable blockchain solutions with confidence.
Whether you're generating new accounts, managing encrypted keys, or signing complex typed data, eth-account delivers enterprise-grade functionality with developer-friendly design.
👉 Explore advanced blockchain development tools trusted by top Web3 projects