add util contrib/zcash/btc2zcash.py
This commit is contained in:
parent
0c422d5ed9
commit
f051cdfbc4
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Search and replaces BTC addresses and private keys in WIF to Zcash variant"""
|
||||
|
||||
import click
|
||||
import imp
|
||||
import re
|
||||
|
||||
imp.load_module('lib', *imp.find_module('../../lib'))
|
||||
|
||||
from lib.bitcoin import (b58_address_to_hash160, hash160_to_b58_address,
|
||||
base_decode, serialize_privkey, DecodeBase58Check,
|
||||
SCRIPT_TYPES)
|
||||
from lib.util import inv_dict, to_bytes
|
||||
from lib.constants import net
|
||||
|
||||
|
||||
ADDR_PATTERN = re.compile(
|
||||
'([123456789ABCDEFGHJKLMNPQRSTUVWXYZ'
|
||||
'abcdefghijkmnopqrstuvwxyz]{20,180})')
|
||||
|
||||
|
||||
def b58_address_to_hash160_btc(addr):
|
||||
addr = to_bytes(addr, 'ascii')
|
||||
_bytes = base_decode(addr, 25, base=58)
|
||||
return _bytes[0], _bytes[1:21]
|
||||
|
||||
|
||||
def deserialize_btc_priv(val):
|
||||
try:
|
||||
vch = DecodeBase58Check(val)
|
||||
except:
|
||||
return None, None, None
|
||||
|
||||
if vch[0] != 0x80:
|
||||
return None, None, None
|
||||
|
||||
if len(vch) not in [33, 34]:
|
||||
return None, None, None
|
||||
|
||||
txin_type = inv_dict(SCRIPT_TYPES)[vch[0] - 0x80]
|
||||
compressed = len(vch) == 34
|
||||
|
||||
return txin_type, vch[1:33], compressed
|
||||
|
||||
|
||||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
||||
@click.command(context_settings=CONTEXT_SETTINGS)
|
||||
@click.option('-i', '--input-file', required=True,
|
||||
help='Input file')
|
||||
@click.option('-n', '--dry-run', is_flag=True,
|
||||
help='Only show what will be changed')
|
||||
@click.option('-o', '--output-file',
|
||||
help='Output file')
|
||||
@click.option('-p', '--inplace', is_flag=True,
|
||||
help='Replace data inplace')
|
||||
def main(**kwargs):
|
||||
input_file = kwargs.pop('input_file')
|
||||
output_file = kwargs.pop('output_file', None)
|
||||
inplace = kwargs.pop('inplace', False)
|
||||
dry_run = kwargs.pop('dry_run', False)
|
||||
if inplace:
|
||||
output_file = input_file
|
||||
|
||||
olines = []
|
||||
total_sub = 0
|
||||
for ln, l in enumerate(open(input_file, 'r').read().splitlines()):
|
||||
pos = 0
|
||||
ol = ''
|
||||
|
||||
while pos < len(l):
|
||||
m = ADDR_PATTERN.search(l, pos)
|
||||
if not m:
|
||||
ol += l[pos:]
|
||||
break
|
||||
|
||||
ol += l[pos:m.start()]
|
||||
val = m.group()
|
||||
|
||||
try:
|
||||
addrtype, h = b58_address_to_hash160_btc(val)
|
||||
except:
|
||||
h = None
|
||||
|
||||
if h and addrtype == 0:
|
||||
new_val = hash160_to_b58_address(h, net.ADDRTYPE_P2PKH)
|
||||
total_sub +=1
|
||||
elif h and addrtype == 5:
|
||||
new_val = hash160_to_b58_address(h, net.ADDRTYPE_P2SH)
|
||||
total_sub +=1
|
||||
else:
|
||||
new_val = None
|
||||
|
||||
|
||||
if not new_val:
|
||||
try:
|
||||
txin_type, privkey, compressed = deserialize_btc_priv(val)
|
||||
except Exception as e:
|
||||
privkey = None
|
||||
|
||||
if privkey:
|
||||
new_val = serialize_privkey(privkey, compressed, txin_type,
|
||||
internal_use=True)
|
||||
|
||||
if dry_run and new_val:
|
||||
print('line %s, col %s: %s => %s' % (
|
||||
ln, m.start(), val, new_val
|
||||
))
|
||||
|
||||
ol += new_val if new_val else val
|
||||
pos = m.end()
|
||||
|
||||
olines.append(ol)
|
||||
|
||||
out = '\n'.join(olines)
|
||||
if not output_file:
|
||||
print(out)
|
||||
elif not dry_run:
|
||||
with open(output_file, 'w') as wfd:
|
||||
wfd.write('%s\n' % out)
|
||||
else:
|
||||
print('Total sub count:', total_sub)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue