如何用Python将无效EIP-55以太坊钱包地址转为有效地址
EIP-55以太坊地址转换解决方案
问题1:Web3库调用报错的解决
你遇到的module 'web3' has no attribute 'to_checksum_address'错误,是因为调用方式不对。在web3.py(v5及以上稳定版)中,to_checksum_address是Web3类的类方法,不是直接属于web3模块的属性。
正确用法示例
先确保安装web3库:pip install web3
代码实现:
from web3 import Web3 def get_valid_eip55_address(address): # 清理地址格式:去除空格、转为小写、移除0x前缀(如果有) cleaned_addr = address.strip().lower().lstrip('0x') if len(cleaned_addr) != 40: raise ValueError("地址格式无效,需为40位十六进制字符") # 调用类方法生成校验和地址 return Web3.to_checksum_address(f"0x{cleaned_addr}") # 测试示例 invalid_addr = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" print(get_valid_eip55_address(invalid_addr))
问题2:手动实现EIP-55的正确方式
如果不想依赖Web3库,以下是严格遵循EIP-55标准的手动实现代码,解决你之前自定义代码效果不佳的问题:
import hashlib def keccak_256_hash(data): # 计算Keccak-256哈希(EIP-55指定的哈希算法) return hashlib.sha3_256(data.encode('ascii')).hexdigest() def convert_to_eip55(address): # 清理地址:转为小写、去除0x前缀和多余空格 addr = address.strip().lower().replace('0x', '') if len(addr) != 40: raise ValueError("地址必须是40位十六进制字符") # 对小写地址字符串计算哈希 hash_hex = keccak_256_hash(addr) # 构建校验和地址 checksum_addr = '0x' for idx, char in enumerate(addr): # 若哈希对应位置的字符值≥8,原字符转为大写,否则保持小写 if int(hash_hex[idx], 16) >= 8: checksum_addr += char.upper() else: checksum_addr += char return checksum_addr # 测试示例 test_addr = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" print(convert_to_eip55(test_addr)) # 输出:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
手动实现的关键注意点
- 必须使用Keccak-256哈希算法(hashlib的
sha3_256符合要求,不要误用其他SHA-3变体) - 哈希计算的是不带0x的小写地址字符串的ASCII编码,而非字节形式的地址
- 遍历地址字符时,哈希的索引要与地址字符一一对应(0到39位)
内容的提问来源于stack exchange,提问作者Iman Majidi
相关产品推荐
相关产品推荐

