eth-account: Ethereum Account Management
eth-account is a Python library for managing Ethereum private keys and signing transactions and messages locally, without requiring a connection to an Ethereum node. It provides functionality for creating accounts, signing raw transactions, and signing messages (EIP-191 and EIP-712). It is a core component of web3.py. The current stable version is 0.13.7, released on April 21, 2025. The library is actively maintained with frequent releases, often on a monthly or bi-monthly basis for bugfixes and features. [1, 8, 15]
Warnings
- breaking Support for Python 3.8 and 3.9 was dropped in version 0.14.0-beta.1. Users on these Python versions should remain on `eth-account <0.14.0` or upgrade their Python interpreter. [19]
- breaking When integrating with `web3.py`, note that `web3.eth.accounts.create` in `web3.py` v1.x had an `entropy` parameter which was removed in v4.x. `eth-account` relies on `ethereum-cryptography/secp256k1` for private key generation directly. [14]
- gotcha The method `Account.unsafe_sign_hash()` is primarily for backwards compatibility. For all new implementations, it is strongly recommended to use `encode_defunct()` or `encode_structured_data()` for message signing. [1]
- gotcha Securely managing private keys and seed phrases is critical. Loss or compromise of these credentials will result in irreversible loss of funds. `eth-account` provides the tools, but responsibility for secure storage lies with the developer/user. [5, 21]
- gotcha Incorrect handling of transaction nonces (e.g., skipping nonces or sending transactions with too low a gas price) can lead to stuck or failed transactions on the Ethereum network. [22]
- gotcha `eth-account` pins `eth-keyfile` to `<0.9.0` (and `>=0.7.0`) due to breaking changes to typing introduced in `eth-keyfile >=0.9.0`. This can lead to dependency conflicts if another library requires a newer `eth-keyfile` version. [19]
Install
-
pip install eth-account
Imports
- Account
from eth_account import Account
- messages
from eth_account.messages import encode_defunct, encode_structured_data, encode_typed_data, SignableMessage
Quickstart
from eth_account import Account
from eth_account.messages import encode_defunct
import os
# 1. Create a new account (generates a private key)
private_key_bytes = Account.create()._private_key
account = Account.from_key(private_key_bytes)
print(f"New Account Address: {account.address}")
# 2. Sign a message
msg_text = "Hello, Ethereum!"
message = encode_defunct(text=msg_text.encode('utf-8'))
signed_message = account.sign_message(message)
print(f"Signed Message Hash: {signed_message.messageHash.hex()}")
print(f"Signature: {signed_message.signature.hex()}")
# 3. Verify the signature
recovered_address = Account.recover_message(message, signature=signed_message.signature)
print(f"Recovered Address: {recovered_address}")
assert recovered_address == account.address
print("Signature verification successful!")