commit 5f6f7da2a1be473a34a125509413d95475011e6a
parent 8cf3587aeb0b1fb767aee84792e15f75f90e8f23
Author: SomberNight <somber.night@protonmail.com>
Date: Sun, 8 Dec 2019 06:56:19 +0100
bitcoin.py: base58 address: make sure all public methods test checksum
Note: the checksum was already being checked in practically all cases, by the caller.
Moved the check here, to the lower level (but still public) method for sanity.
Diffstat:
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/electrum/bitcoin.py b/electrum/bitcoin.py
@@ -328,7 +328,9 @@ def hash160_to_b58_address(h160: bytes, addrtype: int) -> str:
def b58_address_to_hash160(addr: str) -> Tuple[int, bytes]:
addr = to_bytes(addr, 'ascii')
- _bytes = base_decode(addr, base=58, length=25)
+ _bytes = DecodeBase58Check(addr)
+ if len(_bytes) != 21:
+ raise Exception(f'expected 21 payload bytes in base58 address. got: {len(_bytes)}')
return _bytes[0], _bytes[1:21]
@@ -638,12 +640,13 @@ def is_segwit_address(addr: str, *, net=None) -> bool:
def is_b58_address(addr: str, *, net=None) -> bool:
if net is None: net = constants.net
try:
+ # test length, checksum, encoding:
addrtype, h = b58_address_to_hash160(addr)
except Exception as e:
return False
if addrtype not in [net.ADDRTYPE_P2PKH, net.ADDRTYPE_P2SH]:
return False
- return addr == hash160_to_b58_address(h, addrtype)
+ return True
def is_address(addr: str, *, net=None) -> bool:
if net is None: net = constants.net
diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py
@@ -711,6 +711,16 @@ class Test_keyImport(ElectrumTestCase):
self.assertFalse(is_address("not an address"))
+ def test_is_address_bad_checksums(self):
+ self.assertTrue(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWx'))
+ self.assertFalse(is_address('1819s5TxxbBtuRPr3qYskMVC8sb1pqapWw'))
+
+ self.assertTrue(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUe'))
+ self.assertFalse(is_address('3LrjLVnngqnaJeo3BQwMBg34iqYsjZjQUd'))
+
+ self.assertTrue(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt6'))
+ self.assertFalse(is_address('bc1qxq64lrwt02hm7tu25lr3hm9tgzh58snfe67yt5'))
+
@needs_test_with_all_ecc_implementations
def test_is_private_key(self):
for priv_details in self.priv_pub_addr: