Ich versuche mich gerade daran, die Blockchain mit pyblockchain zu parsen . Mein Problem ist, dass ich das nicht richtig codieren kann scriptPubKey
- obwohl ich nicht weiß, was ich möglicherweise falsch machen könnte.
Unten sehen Sie, wie ich die Blockchain durchquere:
from blockchain.reader import BlockchainFileReader
import hashlib
import base58
block_reader = BlockchainFileReader('/media/Data/btc/blocks/blk00325.dat')
count = 0
for block in block_reader:
count +=1
for t in block.transactions:
for outp in t.outputs:
addr = base58.b58encode(outp.script_pub_key)
if addr.startswith('1'):
print(addr)
if count >= 5:
break
Wenn ich in meinem Jupyter-Notizbuch einen Blick auf werfe outp
, finde ich for
outp.script_pub_key
>> b'v\xa9\x14\x1e\xbev\x83\xceJd\xad\xc9\x17\xe9\xb1\x93\x7f\x12&Q\xcb\xab\xa1\x88\xac'
Das:
base58.b58encode(outp.script_pub_key)
>> 'pkJBVCg6k54E7ZiP7cvxbCvtN9aY9zEcgK'
und dies ist keine gültige Bitcoin-Adresse .
Anscheinend sollen Bitcoin-Adressen i Base58Check kodiert werden - das geht aber auch nicht:
base58.b58encode_check(outp.script_pub_key)
>> '6PSJQapdQn8VeG9SBuZdH8q2ysyP4ND6dmspzLZb'
Also was mache ich hier falsch?
Sie berücksichtigen nicht die Operationscodes in der Zeichenfolge pub_key. Beispielsweise könnte ein script_pub_key OP_DUP OP_HASH160 [pub_key] sein ... und Sie müssen den pub_key herausziehen.
Dieser Beispielcode zeigt die Adressen, Sie können sie mit einem Block-Explorer für dieselbe Transaktions-ID überprüfen. Beachten Sie, dass das Byte nach OP_HASH160 die Länge des pub_key in Bytes danach angibt, also muss es auch übersprungen werden, um die Adresse zu generieren.
import sys
import base58
import hashlib
import binascii
from blockchain.reader import BlockchainFileReader
block_reader=BlockchainFileReader('/var/data/bitcoin-data/blocks/blk00325.dat')
satochi_convert=1e8
def sha256(x):
h=hashlib.new('sha256')
h.update(x)
return h.digest()
def hashStr(buffer):
return binascii.hexlify(buffer)
for block in block_reader:
#block has .header, .transactions
for iter,tx in enumerate(block.transactions):
print(' Transaction (txn_hash):{} {}'.format(type(tx.txn_hash),tx.txn_hash))
for x in tx.outputs:
script_pub_key_str=hashStr(x.script_pub_key)
if script_pub_key_str[0:4]==b'76a9':
#This is a pubkeyhash
bytes=x.script_pub_key[2] #number of bytes in the pub_key
assert bytes==20
public_key = x.script_pub_key[3:3+bytes] #20 bytes
z=b'\00'+public_key
#checksum=sha256(sha256(z))[:4]
#address1=base58.b58encode(z + checksum)
address2=base58.b58encode_check(z) # adds checksum for you
print(' output value {:<20} address {}'.format(float(x.value)/satochi_convert,address2))
elif script_pub_key_str[0:2]==b'a9':
#this is a scripthash (pay-to-script address)
bytes=x.script_pub_key[1] #number of bytes in the pub_key
assert bytes==20
public_key = x.script_pub_key[2:2+bytes] #20 bytes
z=b'\05'+public_key #used for mainnet
address2=base58.b58encode_check(z)
print(' output value {:<20} address {}'.format(float(x.value)/satochi_convert,address2))
else:
print(' output value {:<20} other {}'.format(float(x.value)/satochi_convert,script_pub_key_str))
print()
Beispielausgabe für die erste Transaktion in Ihrer Blockdatei ist:
Transaction (txn_hash): cc728403552d5e1fddf06e6a7e8552353f315be6c1a43a8e64e4d11b081d4ca3
output value 25.17686501 address 1N6LrEDiHuFwSyJYj2GedZM2FGk7kkLjn
output value 0.22864963 address 1Hr9uwzwXWpjQDNUWdZ1i9qnoSpnniJe4U
....
OP-Codes hier: https://en.bitcoin.it/wiki/Script , scriptpubkey info: https://en.bitcoin.it/wiki/Transaction HINWEIS: Dies ist nur ein Beispiel für die Berechnung von Adressen, es ist nicht sehr robust, da es andere OP-Codes, andere mögliche Zahlungsskripte usw. nicht nachprüft.