web-dev-qa-db-fra.com

Comment extraire toutes les adresses hash160 utilisées de Bitcoin blockchain

J'ai tous les blocs de 150 Go Bitcoin maintenant quoi? Comment les ouvrir et les lire en Python? Je dois extraire tous les hash160 utilisés jusqu'à présent

J'ai essayé de les ouvrir avec Berkeley DB, mais sans succès, il semble que ces fichiers ne sont pas Berkeley DB Et quelle est la différence entre les fichiers blkxxxxx.dat et revxxxxx.dat? il semble que la taille des fichiers revxxxxx.dat ait été légèrement améliorée

10
John Kotkin

Un petit script assez simple en python suffit pour extraire toutes les adresses via RPC à partir de bitcoin-core. Cela présente l’avantage que bitcoin-core traite toutes les questions liées à l’analyse syntaxique. Pour que cela fonctionne, bitcoin-core doit être exécuté avec txindex=1

Pour exécuter le script, veillez à installer les dépendances suivantes:

Sudo pip install python-bitcoinrpc

Le scénario:

import sys
from bitcoinrpc.authproxy import AuthServiceProxy

RPC_ADDRESS="127.0.0.1:8332"
RPC_USER="u"
RPC_PASSWORD="p"


def connect(address, user, password):
    return AuthServiceProxy("http://%s:%s@%s"%(user, password, address))

def extract_block_addresses(rpc, block_hash):
    block = rpc.getblock(block_hash)
    addresses = []
    for tx in block[u'tx']:
        raw_tx = rpc.getrawtransaction(tx, True)
        if not raw_tx.has_key('vout'):
            sys.stderr.write("Transaction %s has no 'vout': %s\n"%(tx, raw_tx))
            break
        for vout in raw_tx[u'vout']:
            if not vout.has_key("scriptPubKey"):
                sys.stderr.write("Vout %s of Transaction %s has no 'scriptPubKey'\n"%(vout, tx))
                break
            if vout["scriptPubKey"]["type"] == "nulldata":
                # arbitrary data
                break
            Elif vout['scriptPubKey'].has_key('addresses'):
                addresses.extend(vout['scriptPubKey']['addresses'])
            else:
                sys.stderr.write("Can't handle %s transaction output type in transaction %s\n"%(vout["scriptPubKey"]["type"], raw_tx))
    return addresses

if __== "__main__":
    if len(sys.argv) > 1:
        start_block = int(sys.argv[1])
    else:
        start_block = 1

    if len(sys.argv) > 2:
        end_block = int(sys.argv[2])
    else:
        end_block = 0

    rpc = connect(RPC_ADDRESS, RPC_USER, RPC_PASSWORD)
    if end_block == 0:
        end_block = rpc.getblockcount()

    b = start_block

    for b in xrange(start_block, end_block+1):
        try:
            block_hash = rpc.getblockhash(b)
            for addr in extract_block_addresses(rpc, block_hash):
                print addr
        except:
            rpc = connect(RPC_ADDRESS, RPC_USER, RPC_PASSWORD)
            block_hash = rpc.getblockhash(b)
            for addr in extract_block_addresses(rpc, block_hash):
                print addr

Par défaut, bitcoin-core fonctionne avec 4 threads RPC. Il est donc logique de démarrer plusieurs instances du script pour utiliser tous vos cœurs. De plus, il est judicieux de compresser la liste d'adresses générée:

time python bitcoin-addresses.py 1 100000 2> bad_transaction-1.log | gzip -9 > addresses-1.gz &
time python bitcoin-addresses.py 100000 200000 2> bad_transaction-2.log | gzip -9 > addresses-2.gz &
time python bitcoin-addresses.py 200000 300000 2> bad_transaction-3.log | gzip -9 > addresses-3.gz &
time python bitcoin-addresses.py 30000 2> bad_transaction-4.log | gzip -9 > addresses-4.gz &

Si - comme pour moi - votre disque dur s'avère être le goulot d'étranglement avec l'approche précédente, exécuter une seule instance est préférable:

time python bitcoin-addresses.py 2> bad.log | gzip -9 > addresses.gz

Attention, le script ne garde pas trace des adresses connues. Ainsi, la sortie contiendra des doublons. Nous pouvons résoudre ce problème avec sort -u:

zcat addresses.gz | sort -u
3
fzgregor

Ce logiciel semble faire exactement ce que vous voulez. Son README contient cet exemple:

. Compute and print the balance for all keys ever used since the beginning of time:

    ./parser all >all.txt

METTRE À JOUR:

Si j'exécute la commande précédente, j'obtiens le résultat suivant:

root@81d54ebe5b25:~/blockparser# ls -alh all.txt 
-rw-r--r-- 1 root root 900M Aug 25 09:33 all.txt
root@81d54ebe5b25:~/blockparser# head all.txt 
---------------------------------------------------------------------------
          State of the ledger at block 194124 (minted : Thu Aug 16 03:36:13 2012)
---------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
              Balance                      Hash160                             Base58                  nbIn        lastTimeIn          nbOut        lastTimeOut
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
         507335.01317523 8bf24a18a58ab500d30c73bf21dbf4703d31ad2c 1DkyBEKt5S2GDtv7aQw6rQepAvnsRyHoYM    152 Tue Aug 14 18:11:09 2012      17 Tue Jul 17 02:32:38 2012
         105555.03133700 582431b9e63d2394c8b224d1bc45d07ae95d2379 1933phfhK3ZgFQNLGSDXvqCn32k2buXY8a     48 Fri Jun 22 16:26:43 2012       0 Thu Jan  1 00:00:00 1970
          79957.03133700 a0b0d60e5991578ed37cbda2b17d8b2ce23ab295 1FeexV6bAHb8ybZjqQMjJrcCrHGW9sb6uF      4 Sun Jul 15 20:36:59 2012       0 Thu Jan  1 00:00:00 1970
          53000.03133700 3d9e561f21d312f9b8b46e74169263e2452d5591 16cou7Ht6WjTzuFyDBnht9hmvXytg6XdVT     16 Sun Jul 15 20:36:59 2012       9 Sun May 13 12:13:16 2012

Ceci est cependant sur un nœud bitcoin incomplètement synchronisé.

2
fzgregor