Skip to content

Instantly share code, notes, and snippets.

@kristovatlas
Created December 20, 2017 19:00
Show Gist options
  • Save kristovatlas/2c786f0bad1a825930b322110d05cb75 to your computer and use it in GitHub Desktop.
Save kristovatlas/2c786f0bad1a825930b322110d05cb75 to your computer and use it in GitHub Desktop.
"""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