def test_prefix(self): with self.assertRaises(ValueError): cashaddr.decode(":ppm2qsznhks23z7629mms6s4cwef74vcwvn0h82") with self.assertRaises(ValueError): cashaddr.decode("ppm2qsznhks23z7629mms6s4cwef74vcwvn0h82") with self.assertRaises(ValueError): cashaddr.decode( "bitcoin cash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h82") with self.assertRaises(ValueError): cashaddr.decode("bitcoin cash:ab") # b is invalid with self.assertRaises(ValueError): cashaddr.decode( "bitcoincash:ppm2qsznbks23z7629mms6s4cwef74vcwvn0h82")
def test_valid_pubkeys(self): """Test whether valid P2SH addresses decode to the correct output.""" for (address, hashbytes) in zip(VALID_PUBKEY_ADDRESSES, VALID_HASHES): rprefix, kind, addr_hash = cashaddr.decode(address) self.assertEqual(rprefix, BCH_PREFIX) self.assertEqual(kind, cashaddr.PUBKEY_TYPE) self.assertEqual(addr_hash, hashbytes)
def test_valid_scripthash(self): """Test whether valid P2PK addresses decode to the correct output.""" for (address, hashbytes) in zip(VALID_SCRIPT_ADDRESSES, VALID_HASHES): rprefix, kind, addr_hash = cashaddr.decode(address) self.assertEqual(rprefix, BCH_PREFIX) self.assertEqual(kind, cashaddr.SCRIPT_TYPE) self.assertEqual(addr_hash, hashbytes)
def test_bad_decode_size(self): """Test that addresses with invalid sizes fail to decode.""" for bits_size in self.valid_sizes: size = bits_size // 8 # Convert to a valid number of bytes for a hash hashbytes = bytes(random.randint(0, 255) for i in range(size)) payload = cashaddr._pack_addr_data(cashaddr.PUBKEY_TYPE, hashbytes) # Add some more 5-bit data after size has been encoded payload += bytes(random.randint(0, 15) for i in range(3)) # Add checksum payload += cashaddr._create_checksum(BCH_PREFIX, payload) addr = BCH_PREFIX + ':' + ''.join(cashaddr._CHARSET[d] for d in payload) # Check decode fails. This can trigger the length mismatch, # excess padding, or non-zero padding errors with self.assertRaises(ValueError): cashaddr.decode(addr)
def test_address_case(self): cashaddr.decode( "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq") cashaddr.decode( "BITCOINCASH:PPM2QSZNHKS23Z7629MMS6S4CWEF74VCWVN0H829PQ") with self.assertRaises(ValueError): cashaddr.decode( "bitcoincash:PPM2QSZNHKS23Z7629MMS6S4CWEF74VCWVN0H829PQ") with self.assertRaises(ValueError): cashaddr.decode( "bitcoincash:ppm2qsznhks23z7629mmS6s4cwef74vcwvn0h829pq")
def test_bad_decode_checksum(self): """Test whether addresses with invalid checksums fail to decode.""" for bits_size in self.valid_sizes: size = bits_size // 8 # Convert to a valid number of bytes for a hash hashbytes = bytes(random.randint(0, 255) for i in range(size)) addr = cashaddr.encode_full(BCH_PREFIX, cashaddr.PUBKEY_TYPE, hashbytes) addrlist = list(addr) # Inject an error values = list(cashaddr._CHARSET) while True: pos = random.randint(0, len(addr) - 1) choice = random.choice(values) if choice != addrlist[pos] and addrlist[pos] in values: addrlist[pos] = choice break mangled_addr = ''.join(addrlist) with self.assertRaises(ValueError) as e: cashaddr.decode(mangled_addr) self.assertTrue('invalid checksum' in e.exception.args[0])
def from_cashaddr_string(cls, string): '''Construct from a cashaddress string.''' if not string.startswith(NetworkConstants.CASHADDR_PREFIX): string = ':'.join([NetworkConstants.CASHADDR_PREFIX, string]) prefix, kind, addr_hash = cashaddr.decode(string) if prefix != NetworkConstants.CASHADDR_PREFIX: raise AddressError( 'address has unexpected prefix {}'.format(prefix)) if kind == cashaddr.PUBKEY_TYPE: return cls(addr_hash, cls.ADDR_P2PKH) else: assert kind == cashaddr.SCRIPT_TYPE return cls(addr_hash, cls.ADDR_P2SH)
def test_encode_decode(self): """Test whether valid addresses encode and decode properly, for all valid hash sizes. """ for prefix in (BCH_PREFIX, BCH_TESTNET_PREFIX): for bits_size in self.valid_sizes: size = bits_size // 8 # Convert to a valid number of bytes for a hash hashbytes = bytes(random.randint(0, 255) for i in range(size)) addr = cashaddr.encode_full(prefix, cashaddr.PUBKEY_TYPE, hashbytes) rprefix, kind, addr_hash = cashaddr.decode(addr) self.assertEqual(rprefix, prefix) self.assertEqual(kind, cashaddr.PUBKEY_TYPE) self.assertEqual(addr_hash, hashbytes)
def from_cashaddr_string(cls, string): '''Construct from a cashaddress string.''' prefix = NetworkConstants.CASHADDR_PREFIX if string.upper() == string: prefix = prefix.upper() if not string.startswith(prefix + ':'): string = ':'.join([prefix, string]) addr_prefix, kind, addr_hash = cashaddr.decode(string) if addr_prefix != prefix: raise AddressError('address has unexpected prefix {}' .format(addr_prefix)) if kind == cashaddr.PUBKEY_TYPE: return cls(addr_hash, cls.ADDR_P2PKH) else: assert kind == cashaddr.SCRIPT_TYPE return cls(addr_hash, cls.ADDR_P2SH)
def test_decode_bad_inputs(self): with self.assertRaises(TypeError): cashaddr.decode(b'foobar')