\[BOUNTY CLAIMED\] Python conversion code for broken private keys
-
OK, so the original fork of bitcoinj that was litecoinj (then feathercoinj) didn’t properly version private key exports. As a result, old exports of private keys for the Feathercoin and Litecoin Android wallets will not import into the new client (because it validates the version information). I’ve written some code to convert between versions of keys, which can be found here:
https://github.com/hank/life/blob/master/code/python/cryptcoin_addr_convert/convert.py
The problem is that I can’t get the code to work. Thanks to Bushstar’s recent generous donation to FTC Android wallet development, I’m willing to put out a bounty to get this address converter working. A (theoretically) working converter written in powershell is available here:
https://github.com/hank/feathercoin-wallet/issues/3#issuecomment-21228771
As far as I can tell, I’m doing the conversion correctly according to this page:
https://en.bitcoin.it/wiki/Wallet_import_format
But the converted keys won’t import into the official client. If you get this working, post a link to the code here, and email me at [email protected]. Also, don’t forget to post an FTC address to claim the bounty. I’ll be testing the code here to ensure that it works for LTC and FTC addresses.
-
I’m trying to get this to work, hank, but I seem to be missing a variable declaration in the code.
[code]
Traceback (most recent call last):
File “C:\Users\savotr\Downloads\convert.py”, line 76, in
print(“Known input:”, known_input)
NameError: name ‘known_input’ is not defined
[/code]As you can see, known_input isn’t defined or initialized. Did you take something out and forget to fix this?
-
known_input is just a private key string. I removed the test private keys from the code there haphazardly so I could post it. You can probably remove anything that isn’t dealing with the arguments parsed with argparse - it was just test code.
-
If I remove the offending piece of code, I get this:
[code]
Traceback (most recent call last):
File “C:\Users\savotr\Downloads\convert.py”, line 80, in
print("Input: ", hex(decoded))
TypeError: ‘float’ object cannot be interpreted as an integer
[/code]Edit: looks like math changed in Python 2-3. So I’m downgrading to 2, will let you know what I find.
-
Your example was a little too complex for me to completely understand so I implemented my own version using the wiki page you linked to.
[code]
import hashlib
import argparseparser = argparse.ArgumentParser()
parser.add_argument(‘key’)
parser.add_argument(‘–tocustom’, nargs=1, help=“Custom version. Use 2 hex chars. Not compatible with other options”)
parser.add_argument(‘–toltc’, action=“store_true”, help=“Convert input to LTC private key”)
parser.add_argument(‘–toftc’, action=“store_true”, help=“Convert input to FTC private key”)
parser.add_argument(‘–tobtc’, action=“store_true”, help=“Convert input to BTC private key”)
args = parser.parse_args()if args.toltc:
args.version = “B0”
elif args.toftc:
args.version = “8E”
elif args.tobtc:
args.version = “80”
elif args.tocustom:
args.version = args.tocustom[0]__b58chars = ‘123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz’
__b58base = len(__b58chars)def b58encode(v):
long_value = int(v.encode(“hex_codec”), 16)
result = ‘’
while long_value >= __b58base:
div, mod = divmod(long_value, __b58base)
result = __b58chars[mod] + result
long_value = div
result = __b58chars[long_value] + result
# Bitcoin does a little leading-zero-compression:
# leading 0-bytes in the input become leading-1s
nPad = 0
for c in v:
if c == ‘\0’: nPad += 1
else: break
return (__b58chars[0]*nPad) + resultdef b58decode(v):
long_value = 0L
for (i, c) in enumerate(v[::-1]):
long_value += __b58chars.find© * (__b58base**i)
result = ‘’
while long_value >= 256:
div, mod = divmod(long_value, 256)
result = chr(mod) + result
long_value = div
result = chr(long_value) + result
nPad = 0
for c in v:
if c == __b58chars[0]: nPad += 1
else: break
result = chr(0)*nPad + result
return resultdef numtowif(numpriv):
step1 = args.version+numpriv
step2 = hashlib.sha256(step1).hexdigest()
step3 = hashlib.sha256(step2).hexdigest()
step4 = step1 + step3[:8]
step5 = b58encode(step4)
return step5def wiftonum(wifpriv):
step1 = b58decode(wifpriv)
step2 = step1[:-8]
step3 = step2[2:]
return step3print(numtowif(wiftonum(args.key)))
[/code]And that should do the trick.
I’ve got some example outputs:
[code]
----> FTC to FTC (input and output should match)
>convert.py --toftc 4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV
4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV----> FTC TO LTC (convert FTC WIF to LTC WIF)
>convert.py --toltc 4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV
4wWNH7k7JfcWwZRPKgo5n9LeHm32tHuhiMgDEHTxMrXQn3fWoirhyoaRYrYmsEt5AJYNj4rnVcVcyih3WwjnP----> LTC TO FTC (using the prior output from LTC, convert back to FTC, output should match first example)
>convert.py --toftc 4wWNH7k7JfcWwZRPKgo5n9LeHm32tHuhiMgDEHTxMrXQn3fWoirhyoaRYrYmsEt5AJYNj4rnVcVcyih3WwjnP
4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV
[/code]And here’s a github pull request with the diff for you, so you can just merge it in yourself without having to copy-pasta the code from here: https://github.com/hank/life/pull/1
My FTC address is: 6eXWJdPKMRpMG2b8Hv6bvEpXp5taThXBsS
-
I’ll check this out when I get home - thanks!
-
So, here I created a test address with no coins on it with the official client:
[code]
dumpprivkey 6rnc5LW1zi1QDH2fRzZLCXPu2wEDX6mGkp
N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
[/code]Here’s the result:
[code]hank$ python convert.py --tobtc N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
9K5tGttcjM981HU9fdASvek4Wce6234LhUDcmirK6c7t44CWJhcL
hank$ python convert.py --toftc 9K5tGttcjM981HU9fdASvek4Wce6234LhUDcmirK6c7t44CWJhcL
9Knhubm3QF5Km7hMUfLUugUemr326gr35ze72qzkvW3vsvjhLDVt[/code][code]
importprivkey 9KnbfzhQxPz1CnDhRDPYqGsMto8YD9sJzeypfdnC6WWjR5iMdNc2
{“code”:-5,“message”:“Invalid private key”}
[/code]I also tried one of your FTC address outputs:
[code]
importprivkey 4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV
{“code”:-5,“message”:“Invalid private key”}
[/code] -
[quote name=“hank” post=“31001” timestamp=“1381556248”]
So, here I created a test address with no coins on it with the official client:
[code]
dumpprivkey 6rnc5LW1zi1QDH2fRzZLCXPu2wEDX6mGkp
N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
[/code]Here’s the result:
[code]hank$ python convert.py --tobtc N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
9K5tGttcjM981HU9fdASvek4Wce6234LhUDcmirK6c7t44CWJhcL
hank$ python convert.py --toftc 9K5tGttcjM981HU9fdASvek4Wce6234LhUDcmirK6c7t44CWJhcL
9Knhubm3QF5Km7hMUfLUugUemr326gr35ze72qzkvW3vsvjhLDVt[/code][code]
importprivkey 9KnbfzhQxPz1CnDhRDPYqGsMto8YD9sJzeypfdnC6WWjR5iMdNc2
{“code”:-5,“message”:“Invalid private key”}
[/code]I also tried one of your FTC address outputs:
[code]
importprivkey 4MGS1y8YUYERWHgVDKfqv3NsvaBGVqGYEUiBAUmz9WA7hLJghzy9rB8FpQiF7XqEc3tLe6ZPyP4r14AYpVFqV
{“code”:-5,“message”:“Invalid private key”}
[/code]
[/quote]Hmm… that’s strange. Let me look into that.
-
Fixed.
https://github.com/hank/life/blob/master/code/python/cryptcoin_addr_convert/convert.py
[code]hank$ python convert.py --tobtc N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
Converting N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
L48R4PUJP4Kswr3GvKAp7tDrnb8Masqpmc4C4yTp6Cf7vJ36t2t9
hank$ python convert.py --toftc N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
Converting N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1
N8FF4eWtqD9ob6E2fNhKGKYgGfwVGje13nn1uLK8xuD5rvv2kZY1[/code]There were a couple things wrong. One was you had to encode the versions as ints and prepend them in binary instead of ascii. You were cutting too much off the end and the front (probably due to powershell insanity), which was a pretty easy fix. Try out verbose mode to see the full details.
As far as I can tell, this code works, so I think you’re still entitled to a bounty. I did have to fix it, so I don’t think the full 250 is fair - how does 150FTC sound?
-
Heh, I found the problem just now and was coming here to post the fix, but you had already found it.
I’ll take what I can get. Hope I helped ya… :)
-
You did help a lot - I’ll send the funds shortly.
-
[quote name=“hank” post=“31051” timestamp=“1381605534”]
You did help a lot - I’ll send the funds shortly.
[/quote]Sweet!
-
I’m trying to sync my wallet right now and I’m having some problems. Shouldn’t be too much longer though…
-
[b]Sent[/b]
[url=http://ftc.cryptocoinexplorer.com/tx/a225d549fff9f3a7617292ccef5aea5f3710fd5ae8d23f291154c4b90b21695c]http://ftc.cryptocoinexplorer.com/tx/a225d549fff9f3a7617292ccef5aea5f3710fd5ae8d23f291154c4b90b21695c[/url]
-
Great works guys :)