Repository: richardkiss/pycoin

Issue:
Fixed in PR #88 - Key.is_private (which is always True) is used in some places instead of Key.is_private() (which is sometimes False)
See, e.g.:

https://github.com/richardkiss/pycoin/blob/5a3f30986dec6b4e82c45c0955c139891ce8ba0f/pycoin/key/Key.py#L223
https://github.com/richardkiss/pycoin/blob/5a3f30986dec6b4e82c45c0955c139891ce8ba0f/pycoin/scripts/genwallet.py#L87

Discussion:

Patch:
diff --git a/CREDITS b/CREDITS
index 55e4cc4..c21c03b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -14,7 +14,7 @@ Mike Owens https://github.com/mike0wens
 Todd Boland https://github.com/boland
 https://github.com/ap-m
 Roman Zeyde https://github.com/romanz
-Matthew Bogosian https://github.com/mbogosian
+Matt Bogosian https://github.com/posita
 JahPowerBit https://github.com/JahPowerBit
 https://github.com/fluxism
 BtcDrak https://github.com/btcdrak
diff --git a/pycoin/key/Key.py b/pycoin/key/Key.py
index 95ad838..809551c 100644
--- a/pycoin/key/Key.py
+++ b/pycoin/key/Key.py
@@ -220,6 +220,6 @@ class Key(object):
 
     def __repr__(self):
         r = self.public_copy().as_text()
-        if self.is_private:
+        if self.is_private():
             return "private_for <%s>" % r
         return "<%s>" % r
diff --git a/pycoin/scripts/genwallet.py b/pycoin/scripts/genwallet.py
index e9cacf7..ba1c0e2 100755
--- a/pycoin/scripts/genwallet.py
+++ b/pycoin/scripts/genwallet.py
@@ -72,7 +72,7 @@ def main():
             child_index = "%d" % wallet.child_index()
         if args.json:
             d = dict(
-                wallet_key=wallet.wallet_key(as_private=wallet.is_private),
+                wallet_key=wallet.wallet_key(as_private=wallet.is_private()),
                 public_pair_x=wallet.public_pair[0],
                 public_pair_y=wallet.public_pair[1],
                 tree_depth=wallet.depth,
@@ -84,7 +84,7 @@ def main():
                 bitcoin_addr_uncompressed=wallet.bitcoin_address(compressed=False),
                 network="test" if wallet.is_test else "main",
             )
-            if wallet.is_private:
+            if wallet.is_private():
                 d.update(dict(
                     key="private",
                     secret_exponent=wallet.secret_exponent,
@@ -95,9 +95,9 @@ def main():
                 d.update(dict(key="public"))
             print(json.dumps(d, indent=3))
         elif args.info:
-            print(wallet.wallet_key(as_private=wallet.is_private))
+            print(wallet.wallet_key(as_private=wallet.is_private()))
             print(full_network_name_for_netcode(wallet.netcode))
-            if wallet.is_private:
+            if wallet.is_private():
                 print("private key")
                 print("secret exponent: %d" % wallet.secret_exponent)
             else:
@@ -108,7 +108,7 @@ def main():
             print("parent f'print:  %s" % b2h(wallet.parent_fingerprint))
             print("child index:     %s" % child_index)
             print("chain code:      %s" % b2h(wallet.chain_code))
-            if wallet.is_private:
+            if wallet.is_private():
                 print("WIF:             %s" % wallet.wif())
                 print("  uncompressed:  %s" % wallet.wif(compressed=False))
             print("Bitcoin address: %s" % wallet.bitcoin_address())
@@ -118,7 +118,7 @@ def main():
         elif args.wif:
             print(wallet.wif(compressed=not args.uncompressed))
         else:
-            print(wallet.wallet_key(as_private=wallet.is_private))
+            print(wallet.wallet_key(as_private=wallet.is_private()))
     except PublicPrivateMismatchError as ex:
         print(ex.args[0])
 


Test patch:
diff --git a/tests/bip32_test.py b/tests/bip32_test.py
index fa2c37b..75bb2a9 100755
--- a/tests/bip32_test.py
+++ b/tests/bip32_test.py
@@ -151,6 +151,20 @@ class Bip0032TestCase(unittest.TestCase):
         uag = my_prv.subkey(i=0, is_hardened=True, as_private=True)
         self.assertEqual(None, uag.subkey(i=0, as_private=False).secret_exponent())
 
+    def test_repr(self):
+        from pycoin.key import Key
+        netcode = 'XTN'
+        key = Key(secret_exponent=273, netcode=netcode)
+        wallet = BIP32Node.from_master_secret(bytes(key.wif().encode('ascii')), netcode)
+
+        address = wallet.address()
+        pub_k = wallet.from_text(address)
+        self.assertEqual(repr(pub_k),  '<myb5gZNXePNf2E2ksrjnHRFCwyuvt7oEay>')
+
+        wif = wallet.wif()
+        priv_k = wallet.from_text(wif)
+        self.assertEqual(repr(priv_k), 'private_for <03ad094b1dc9fdce5d3648ca359b4e210a89d049532fdd39d9ccdd8ca393ac82f4>')
+
 if __name__ == '__main__':
     unittest.main()
 
diff --git a/tests/key_validate_test.py b/tests/key_validate_test.py
index cee20ce..7cabd8c 100755
--- a/tests/key_validate_test.py
+++ b/tests/key_validate_test.py
@@ -2,12 +2,10 @@
 
 import unittest
 
-from pycoin.block import Block
 from pycoin.encoding import hash160_sec_to_bitcoin_address
 from pycoin.key import Key
-from pycoin.key.bip32 import Wallet
-from pycoin.networks import pay_to_script_prefix_for_netcode, prv32_prefix_for_netcode, NETWORK_NAMES
-from pycoin.serialize import b2h_rev, h2b
+from pycoin.key.BIP32Node import BIP32Node
+from pycoin.networks import pay_to_script_prefix_for_netcode, NETWORK_NAMES
 
 from pycoin.key.validate import is_address_valid, is_wif_valid, is_public_bip32_valid, is_private_bip32_valid
 
@@ -69,7 +67,7 @@ class KeyUtilsTest(unittest.TestCase):
         # not all networks support BIP32 yet
         for netcode in "BTC XTN DOGE".split():
             for wk in WALLET_KEYS:
-                wallet = Wallet.from_master_secret(wk.encode("utf8"), netcode=netcode)
+                wallet = BIP32Node.from_master_secret(wk.encode("utf8"), netcode=netcode)
                 text = wallet.wallet_key(as_private=True)
                 self.assertEqual(is_private_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), netcode)
                 self.assertEqual(is_public_bip32_valid(text, allowable_netcodes=NETWORK_NAMES), None)
@@ -82,3 +80,17 @@ class KeyUtilsTest(unittest.TestCase):
                 a = text[:-1] + chr(ord(text[-1])+1)
                 self.assertEqual(is_private_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
                 self.assertEqual(is_public_bip32_valid(a, allowable_netcodes=NETWORK_NAMES), None)
+
+    def test_repr(self):
+        key = Key(secret_exponent=273, netcode='XTN')
+
+        address = key.address()
+        pub_k = Key.from_text(address)
+        self.assertEqual(repr(pub_k),  '<mhDVBkZBWLtJkpbszdjZRkH1o5RZxMwxca>')
+
+        wif = key.wif()
+        priv_k = Key.from_text(wif)
+        self.assertEqual(repr(priv_k), 'private_for <0264e1b1969f9102977691a40431b0b672055dcf31163897d996434420e6c95dc9>')
+
+if __name__ == '__main__':
+    unittest.main()