1
0
mirror of https://github.com/romanz/electrs.git synced 2024-11-19 01:43:29 +01:00

contrib/xpub.py support ypub/zpub

This commit is contained in:
Frederic Lepied 2021-10-15 08:56:53 +02:00 committed by Roman Zeyde
parent 98b3f21656
commit b114826725
4 changed files with 95 additions and 40 deletions

View File

@ -1,18 +0,0 @@
#!/bin/bash
set -eu
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
venv=false
if [ "$1" = "--venv" ];
then
shift
venv=true
fi
if [ $venv = true ] && [ ! -d .venv ]; then
virtualenv .venv
.venv/bin/pip install pycoin logbook prettytable
fi
exec .venv/bin/python history.py "$@"

1
contrib/history.sh Symbolic link
View File

@ -0,0 +1 @@
venv_wrapper.sh

18
contrib/venv_wrapper.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
set -e
cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
cmd="$(basename -- "${BASH_SOURCE[0]}" .sh)".py
if [ "$1" = "--venv" ]; then
shift
if [ ! -d .venv ]; then
virtualenv .venv
.venv/bin/pip install pycoin logbook prettytable base58
fi
PATH=$PWD/.venv/bin:$PATH
fi
exec python "$cmd" "$@"

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import base58
import hashlib import hashlib
import sys import sys
@ -10,10 +11,71 @@ import client
log = Logger("xpub") log = Logger("xpub")
prefix_dict = {
'mainnet': {
'xpub': '0488b21e', # P2PKH or P2SH - m/44'/0'
'ypub': '049d7cb2', # P2WPKH in P2SH - m/49'/0'
'zpub': '04b24746', # P2WPKH - m/84'/0'
},
'testnet': {
'tpub': '043587cf', # P2PKH or P2SH - m/44'/1'
'upub': '044a5262', # P2WPKH in P2SH - m/49'/1'
'vpub': '045f1cf6', # P2WPKH - m/84'/1'
},
'regtest': {
},
}
def convert_key(key, target_prefix, network_name):
decoded_key_bytes = base58.b58decode_check(key)
target_key_bytes = (
bytes.fromhex(prefix_dict[network_name][target_prefix]) +
decoded_key_bytes[4:])
return base58.b58encode_check(target_key_bytes).decode('ascii')
def compute_balance(xpub, conn, network):
total = 0
for change in (0, 1):
empty = 0
for n in range(1000):
address = xpub.subkey(change).subkey(n).address()
script = network.parse.address(address).script()
script_hash = hashlib.sha256(script).digest()[::-1].hex()
# conn.call([client.request('blockchain.scripthash.subscribe',
# script_hash)])
result, = conn.call(
[client.request('blockchain.scripthash.get_history',
script_hash)])
ntx = len(result)
if len(result):
log.debug(result)
result, = conn.call(
[client.request('blockchain.scripthash.get_balance',
script_hash)])
confirmed = result['confirmed'] / 1e8
total += confirmed
log.info(
'{}/{}: {} -> {} BTC confirmed, {} BTC unconfirmed, '
'{} txs balance = {} BTC', change, n, address,
result["confirmed"] / 1e8, result["unconfirmed"] / 1e8, ntx, total)
if confirmed or ntx:
empty = 0
else:
empty += 1
if empty >= 10:
break
return total
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--host', default='localhost') parser.add_argument('--host', default='localhost')
parser.add_argument('--network', default='mainnet') parser.add_argument('--network', default='mainnet',
choices=['mainnet', 'testnet', 'regtest'])
parser.add_argument('xpub') parser.add_argument('xpub')
args = parser.parse_args() args = parser.parse_args()
@ -31,32 +93,23 @@ def main():
conn = client.Client((args.host, port)) conn = client.Client((args.host, port))
total = 0 total = 0
xpub = network.parse.bip32(args.xpub) xpub = (network.parse.bip32(args.xpub) or network.parse.bip49(args.xpub) or
network.parse.bip84(args.xpub))
if xpub is None: if xpub is None:
log.error('Invalid BIP32 pub key %s' % args.xpub) log.error('Invalid BIP32/BIP49/BIP84 pub key %s' % args.xpub)
sys.exit(1) sys.exit(1)
for change in (0, 1): total = compute_balance(xpub, conn, network)
empty = 0
for n in range(1000): for prefix in prefix_dict[args.network]:
address = xpub.subkey(change).subkey(n).address() if args.xpub[:4] != prefix:
script = network.parse.address(address).script() key = convert_key(args.xpub, prefix, args.network)
script_hash = hashlib.sha256(script).digest()[::-1].hex() log.info('Trying with {}', key)
# conn.call([client.request('blockchain.scripthash.subscribe', script_hash)]) xpub = (network.parse.bip32(key) or network.parse.bip49(key)
result, = conn.call([client.request('blockchain.scripthash.get_history', script_hash)]) or network.parse.bip84(key))
ntx = len(result) total += compute_balance(xpub, conn, network)
result, = conn.call([client.request('blockchain.scripthash.get_balance', script_hash)])
log.info('{}/{}: {} -> {} BTC confirmed, {} BTC unconfirmed, {} txs', change, n, address, result["confirmed"], result["unconfirmed"], ntx)
confirmed = result['confirmed'] / 1e8
total += confirmed
if confirmed or ntx:
empty = 0
else:
empty += 1
if empty >= 20:
break
log.info('total balance: {} BTC', total) log.info('total balance: {} BTC', total)

1
contrib/xpub.sh Symbolic link
View File

@ -0,0 +1 @@
venv_wrapper.sh