Created
December 20, 2017 19:00
-
-
Save kristovatlas/2c786f0bad1a825930b322110d05cb75 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Find first block has a TXO created and spent in the same block | |
Using a remote API because this should be a fast search early in the blockchain | |
""" | |
import json | |
from time import sleep | |
import requests | |
BLOCK_HEIGHT_URL = "https://blockchain.info/block-height/{height}?format=json" | |
TX_INDEX_URL = "https://blockchain.info/tx-index/{tx_index}/{txo_n}?format=json" | |
TX_URL = "https://blockchain.info/tx/{txid}?format=json" | |
NUM_TRIES = 10 | |
class NoMoreTriesError(Exception): | |
"""Ran out of tries""" | |
pass | |
def _get_json(url): | |
tries = NUM_TRIES | |
while tries > 0: | |
resp = requests.get(url) | |
if hasattr(resp, 'status_code') and resp.status_code == 200 and hasattr(resp, 'text'): | |
return json.loads(resp.text) | |
print "\tFailed to fetch {url}".format(url=url) | |
sleep(1) | |
tries -= 1 | |
raise NoMoreTriesError('{tries} failures in a row. Stopping!'.format( | |
tries=NUM_TRIES)) | |
def _main(): | |
height = 0 | |
while True: | |
print "Checking block at height {height} for same-block spends".format( | |
height=height) | |
block_height_json = _get_json(BLOCK_HEIGHT_URL.format(height=height)) | |
assert 'blocks' in block_height_json | |
assert len(block_height_json['blocks']) == 1 | |
block = block_height_json['blocks'][0] #one authoritative block at each height | |
assert 'tx' in block | |
assert 'hash' in block | |
#block_hash = block['hash'] | |
for txn in block['tx']: | |
#go through each tx spent and see if prev_out mined in same block | |
if 'inputs' in txn: | |
for inpt in txn['inputs']: | |
if 'prev_out' in inpt: | |
tx_index = inpt['prev_out']['tx_index'] | |
txo_n = inpt['prev_out']['n'] | |
tx_index_json = _get_json(TX_INDEX_URL.format( | |
tx_index=tx_index, txo_n=txo_n)) | |
#sanity checks | |
assert 'out' in tx_index_json | |
assert len(tx_index_json['out']) >= txo_n + 1 | |
assert 'block_height' in tx_index_json | |
int(tx_index_json['block_height']) | |
if tx_index_json['block_height'] == height: | |
tx_hash = tx_index_json['hash'] | |
print("Found transaction created and spent at " | |
"block height {height}").format(height=height) | |
print "\tBlockchain.info tx_index: {index}".format( | |
index=tx_index) | |
print "\ttxid:{hash}".format(hash=tx_hash) | |
print "\ttxo_n:{txo_n}".format(txo_n=txo_n) | |
height += 1 | |
if __name__ == '__main__': | |
_main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment