You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

64 lines
2.7 KiB

"""
Module implementing actions that can be taken on
network-serialized bitcoin blocks.
"""
from jmbase import hextobin
from bitcointx.core import CBitcoinTransaction
from bitcointx.core.serialize import VarIntSerializer
def decode_varint(data):
n, tail = VarIntSerializer.deserialize_partial(data)
head = data[0: len(data) - len(tail)]
return n, len(head)
def get_transactions_in_block(block):
""" `block` is hex output from RPC `getblock`.
Return:
yields the block's transactions, type CBitcoinTransaction
"""
block = hextobin(block)
# Skipping the header
transaction_data = block[80:]
# Decoding the number of transactions, offset is the size of
# the varint (1 to 9 bytes)
n_transactions, offset = decode_varint(transaction_data)
for i in range(n_transactions):
# This 'strat' of reading in small chunks optimistically is taken from:
# https://github.com/alecalve/python-bitcoin-blockchain-parser/blob/7a9e15c236b10d2a6dff5e696801c0641af72628/blockchain_parser/utils.py
# Try from 1024 (1KiB) -> 1073741824 (1GiB) slice widths
for j in range(0, 20):
try:
offset_e = offset + (1024 * 2 ** j)
transaction = CBitcoinTransaction.deserialize(
transaction_data[offset:offset_e], allow_padding=True)
yield transaction
break
except:
continue
# Skipping to the next transaction
offset += len(transaction.serialize())
""" Example block from a regtest:
# Found using `getblockhash 222` followed by `getblock <resultinghash> 0`:
0000003066327ecf2f3e72ec43f358c9c7b34f47374f23f4fcce965d4e18273a5b98f325d11b3b9c3a592c830d49f6281d4055f5732a79a19f9bd8d4afad729772cbf393fa7bdf5fffff7f2000000000010200000
00001010000000000000000000000000000000000000000000000000000000000000000ffffffff0502de000101ffffffff0200f902950000000017a914d2e1d0ea5135f0cbeb4aef06e3cee785d394876a870000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000
Gives (x = above block):
y = list(btc.get_block_transactions(x))
>>> y[0]
CBitcoinTransaction([CBitcoinTxIn(CBitcoinOutPoint(), CBitcoinScript([x('de00'), x('01')]), 0xffffffff)],
[CBitcoinTxOut(25.0*COIN, CBitcoinScript([OP_HASH160, x('d2e1d0ea5135f0cbeb4aef06e3cee785d394876a'), OP_EQUAL])),
CBitcoinTxOut(0.0*COIN, CBitcoinScript([OP_RETURN, x('aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9')]))],
0, 2, CBitcoinTxWitness([CBitcoinTxInWitness(CScriptWitness([x('0000000000000000000000000000000000000000000000000000000000000000')]))]))
(coinbase transaction)
"""