-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a new feature to validate ethereum address
- Loading branch information
Showing
6 changed files
with
167 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
"""Crypto addresses.""" | ||
|
||
# local | ||
from .btc_address import btc_address | ||
from .eth_address import eth_address | ||
|
||
__all__ = ("btc_address", "eth_address") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
"""ETH Address.""" | ||
|
||
# standard | ||
import re | ||
|
||
# external | ||
from eth_hash.auto import keccak | ||
|
||
# local | ||
from validators.utils import validator | ||
|
||
|
||
def _validate_eth_checksum_address(addr: str): | ||
"""Validate ETH type checksum address.""" | ||
addr = addr.replace("0x", "") | ||
addr_hash = keccak.new(addr.lower().encode("ascii")).digest().hex() | ||
|
||
if len(addr) != 40: | ||
return False | ||
|
||
for i in range(0, 40): | ||
if (int(addr_hash[i], 16) > 7 and addr[i].upper() != addr[i]) or ( | ||
int(addr_hash[i], 16) <= 7 and addr[i].lower() != addr[i] | ||
): | ||
return False | ||
return True | ||
|
||
|
||
@validator | ||
def eth_address(value: str, /): | ||
"""Return whether or not given value is a valid ethereum address. | ||
Full validation is implemented for ERC20 addresses. | ||
Examples: | ||
>>> eth_address('0x9cc14ba4f9f68ca159ea4ebf2c292a808aaeb598') | ||
# Output: True | ||
>>> eth_address('0x8Ba1f109551bD432803012645Ac136ddd64DBa72') | ||
# Output: ValidationError(func=eth_address, args=...) | ||
Args: | ||
value: | ||
Ethereum address string to validate. | ||
Returns: | ||
(Literal[True]): If `value` is a valid ethereum address. | ||
(ValidationError): If `value` is an invalid ethereum address. | ||
""" | ||
if not value: | ||
return False | ||
|
||
return re.compile(r"^0x[0-9a-f]{40}$|^0x[0-9A-F]{40}$").match( | ||
value | ||
) or _validate_eth_checksum_address(value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Test ETH address.""" | ||
|
||
# external | ||
import pytest | ||
|
||
# local | ||
from validators import ValidationError, eth_address | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"value", | ||
[ | ||
"0x8ba1f109551bd432803012645ac136ddd64dba72", | ||
"0x9cc14ba4f9f68ca159ea4ebf2c292a808aaeb598", | ||
"0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE", | ||
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", | ||
"0x742d35Cc6634C0532925a3b844Bc454e4438f44e", | ||
"0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984", | ||
"0x1234567890123456789012345678901234567890", | ||
"0x57Ab1ec28D129707052df4dF418D58a2D46d5f51", | ||
], | ||
) | ||
def test_returns_true_on_valid_eth_address(value: str): | ||
"""Test returns true on valid eth address.""" | ||
assert eth_address(value) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"value", | ||
[ | ||
"0x742d35Cc6634C0532925a3b844Bc454e4438f44g", | ||
"0x742d35Cc6634C0532925a3b844Bc454e4438f44", | ||
"0xAbcdefg1234567890Abcdefg1234567890Abcdefg", | ||
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c72", | ||
"0x80fBD7F8B3f81D0e1d6EACAb69AF104A6508AFB1", | ||
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c7g", | ||
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c", | ||
"0x7Fb21a171205f3B8d8E4d88A2d2f8A56E45DdB5c", | ||
"validators.eth", | ||
], | ||
) | ||
def test_returns_failed_validation_on_invalid_eth_address(value: str): | ||
"""Test returns failed validation on invalid eth address.""" | ||
assert isinstance(eth_address(value), ValidationError) |