def query_bitcoin(): if not core_enabled: body = json.dumps({"result": "error", "message": "Bitcoin Core not enabled for this server"}) return (body, 200, {'Content-length': len(body), 'Content-type': 'application/json', } ) rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) # to begin, get hash, block height, and time for latest, then n-blocks-ago, or for a block hash owner = request.args.get('owner') string = request.args.get('query') sales = db.session.query(Sale).filter(Sale.owner == owner).count() res = [] out = {} if sales == 0: body = json.dumps({"result": "error", "message": "Account required to make queries"}) return (body, 200, {'Content-length': len(body), 'Content-type': 'application/json', } ) elif string == 'getbydepth': depth = request.args.get('depth') res = rpc.get('getblockcount') if 'output' in res and 'result' in res['output']: height = res['output']['result'] - int(depth) elif string == 'getbyheight': height = request.args.get('height') elif string == 'getbyhash': res = rpc.get('getblockheader', [request.args.get('hash')]) height = res['output']['result']['height'] res = rpc.get('getblockhash', [int(height)]) out['height'] = height if 'output' in res and 'result' in res['output']: out['hash'] = res['output']['result'] res = rpc.get('getblockheader', [str(out['hash'])]) out['time'] = res['output']['result']['time'] out['height'] = height body = json.dumps(out) else: body = json.dumps({"result": "error", "message": "Invalid depth or RPC error"}) return (body, 200, {'Content-length': len(body), 'Content-type': 'application/json', } )
def get_by_depth(depth): rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) res = rpc.get('getblockcount') if 'output' in res and 'result' in res['output']: height = res['output']['result'] - int(depth) else: return None res = rpc.get('getblockhash', [height]) out = {} if 'output' in res and 'result' in res['output']: out['hash'] = res['output']['result'] res = rpc.get('getblockheader', [out['hash']]) out['time'] = res['output']['result']['time'] out['height'] = height return out
class Daemon: def __init__(self): self.bitcoind_command = ["bitcoind"] self.rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) def check(self): try: self.rpc.get("getinfo") except: os.system("kill -9 `ps -ef | grep bitcoind | grep -v grep | awk '{print $2}'`") logger.warning(json.dumps({"message": "unresponsive bitcoind killed"})) sleep(60) # give bitcoind time to die os.system("bitcoind &") logger.warning(json.dumps({"message": "bitcoind started"})) sleep(300) # wait a bit on the long side for more reliability def get_transactions(self, number): return self.rpc.get("listtransactions", ["*", int(number)]) def get_accountaddress(self, account): return self.rpc.get("getaccountaddress", [account]) def get_receivedbyaddress(self, address, minconf): res = self.rpc.get("getreceivedbyaddress", [address, int(minconf)]) return res["output"]["result"] def get_balance(self, minconf): res = self.rpc.get("getbalance", ["*", int(minconf)]) return Decimal(str(res)) def send(self, address, amount): pass
class Daemon(): def __init__(self): self.bitcoind_command = ['bitcoind'] self.rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) def check(self): try: self.rpc.get('getinfo') except: os.system( "kill -9 `ps -ef | grep bitcoind | grep -v grep | awk '{print $2}'`" ) logger.warning( json.dumps({'message': 'unresponsive bitcoind killed'})) sleep(60) # give bitcoind time to die os.system("bitcoind &") logger.warning(json.dumps({'message': 'bitcoind started'})) sleep(300) # wait a bit on the long side for more reliability def get_transactions(self, number): return self.rpc.get('listtransactions', ['*', int(number)]) def get_accountaddress(self, account): return self.rpc.get('getaccountaddress', [account]) def get_receivedbyaddress(self, address, minconf): res = self.rpc.get('getreceivedbyaddress', [address, int(minconf)]) return res['output']['result'] def get_balance(self, minconf): res = self.rpc.get('getbalance', ['*', int(minconf)]) return Decimal(str(res)) def send(self, address, amount): pass
def query_bitcoin(): if not core_enabled: body = json.dumps({ "result": "error", "message": "Bitcoin Core not enabled for this server" }) return (body, 200, { 'Content-length': len(body), 'Content-type': 'application/json', }) rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) # to begin, get hash, block height, and time for latest, then n-blocks-ago, or for a block hash owner = request.args.get('owner') string = request.args.get('query') sales = db.session.query(Sale).filter(Sale.owner == owner).count() res = [] out = {} if sales == 0: body = json.dumps({ "result": "error", "message": "Account required to make queries" }) return (body, 200, { 'Content-length': len(body), 'Content-type': 'application/json', }) elif string == 'getbydepth': depth = request.args.get('depth') res = rpc.get('getblockcount') if 'output' in res and 'result' in res['output']: height = res['output']['result'] - int(depth) elif string == 'getbyheight': height = request.args.get('height') elif string == 'getbyhash': res = rpc.get('getblockheader', [request.args.get('hash')]) height = res['output']['result']['height'] elif string == 'sendrawtransaction': tx = request.args.get('tx') res = rpc.get('sendrawtransaction', [str(tx)]) if 'output' in res and 'result' in res['output']: out['txid'] = res['output']['result'] body = json.dumps(out) return (body, 200, { 'Content-length': len(body), 'Content-type': 'application/json', }) res = rpc.get('getblockhash', [int(height)]) out['height'] = height if 'output' in res and 'result' in res['output']: out['hash'] = res['output']['result'] res = rpc.get('getblockheader', [str(out['hash'])]) out['time'] = res['output']['result']['time'] out['height'] = height body = json.dumps(out) else: body = json.dumps({ "result": "error", "message": "Invalid depth or RPC error" }) return (body, 200, { 'Content-length': len(body), 'Content-type': 'application/json', })
res = rpc.get('getblockcount') if 'output' in res and 'result' in res['output']: height = res['output']['result'] - int(depth) else: return None res = rpc.get('getblockhash', [height]) out = {} if 'output' in res and 'result' in res['output']: out['hash'] = res['output']['result'] res = rpc.get('getblockheader', [out['hash']]) out['time'] = res['output']['result']['time'] out['height'] = height return out if __name__ == '__main__': if DEBUG: app.debug = True rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) try: rpc.get('getblockcount') core_enabled = CORE_ENABLED except: core_enabled = False print("Core enabled: " + str(core_enabled)) app.run(host='0.0.0.0', port=(os.environ.get('SERVER_PORT', SERVER_PORT))) #app.run(host='127.0.0.1', port=SERVER_PORT)
def save_block_info(provider, live, blockindex, unconf): data = {} # obtain data to process if live or unconf: raw = '' if provider == 'blockchaininfo': if blockindex != "last": url = "https://blockchain.info/block-height/" + str( blockindex) + "?format=json" elif unconf: url = "https://blockchain.info/unconfirmed-transactions?format=json&offset=" else: url = "https://blockchain.info/latestblock" if not unconf: response = urllib.urlopen(url) raw = response.read() parsed = json.loads(raw) else: txs = [] response = urllib.urlopen( "https://blockchain.info/q/unconfirmedcount") unconf_count = int(response.read()) for i in range(unconf_count, 0, -50): response = urllib.urlopen(url + str(i)) raw = response.read() parsed = json.loads(raw) txs = txs + parsed['txs'] if blockindex != "last" or unconf: if not unconf: height = parsed['blocks'][0]['height'] block_hash = parsed['blocks'][0]['hash'] data = parsed['blocks'][0] else: height = "unconf" block_hash = "unconf" data = {} data['tx'] = txs else: height = parsed['height'] block_hash = parsed['hash'] url = "https://blockchain.info/rawblock/" + parsed['hash'] response = urllib.urlopen(url) raw = response.read() parsed = json.loads(raw) data = parsed f = open( "blocks/" + str(height) + "-" + provider + "-" + block_hash + ".txt", "w") f.write(json.dumps(raw)) f.close() else: from rpc import RPC rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) block_hash = best_block_hash = rpc.get( 'getbestblockhash')['output']['result'] block = rpc.get('getblock', [block_hash])['output']['result'] height = block['height'] if blockindex == 'unprocessed': con = mysql.connector.connect(user=MYSQL_USER, password=MYSQL_PASSWORD, database=MYSQL_DATABASE) cur = con.cursor() while 1: cur.execute('select * from block where height = %s' % height) if cur.fetchall(): height = height - 1 else: break block_hash = rpc.get('getblockhash', [height])['output']['result'] con.close() else: height = blockindex block_hash = rpc.get('getblockhash', [int(blockindex)])['output']['result'] block = rpc.get('getblock', [block_hash])['output']['result'] height = block['height'] block_hash = block['hash'] block_time = block['time'] data['tx'] = [] tx_cache = {} for txid in block['tx']: rawtx = rpc.get('getrawtransaction', [txid])['output']['result'] tx = rpc.get('decoderawtransaction', [rawtx])['output']['result'] if txid not in tx_cache: tx_cache[txid] = tx for txid in block['tx']: rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) tx = tx_cache[txid] for inp in tx['vin']: if 'txid' not in inp: continue if inp['txid'] not in tx_cache: rawtx = rpc.get('getrawtransaction', [inp['txid']])['output']['result'] inptx = rpc.get('decoderawtransaction', [rawtx])['output']['result'] tx_cache[inp['txid']] = inptx else: inptx = tx_cache[inp['txid']] #TODO: deal with nonstandard transaction inputs whose transactions don't seem to have enough outputs if inp['vout'] < len(inptx['vout']): inp['value'] = inptx['vout'][inp['vout']]['value'] data['tx'].append(tx) else: if provider == 'blockchaininfo': the_file = '000000000000000016bae92da911065f77e52e65c7c5d164ee12b57247176ab0.json' else: the_file = 'last' with open(the_file) as data_file: data = json.load(data_file) normalized_data = {'tx': []} for tx in data['tx']: normalized_data['tx'].append(read_transaction(tx, provider)) stats = process_block(normalized_data, provider) con = mysql.connector.connect(user=MYSQL_USER, password=MYSQL_PASSWORD, database=MYSQL_DATABASE) cur = con.cursor() insertstmt = ( "insert into block (created, time, height, hash) values (now(), FROM_UNIXTIME(%s), '%s', '%s')" % (block_time, height, block_hash)) cur.execute(insertstmt) for key in stats.keys(): val = stats[key] if isinstance(val, dict) and 'count' in val: val = val['count'] cur.execute( "insert into block_info (created, time, height, hash, metric, value) values (now(), FROM_UNIXTIME(%s), '%s', '%s', '%s', '%s')" % (block_time, height, block_hash, key, val)) con.commit() con.close() print json.dumps(stats) return height, block_hash
def get_by_depth(depth): rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) res = rpc.get('getblockcount') if 'output' in res and 'result' in res['output']: height = res['output']['result'] - int(depth) else: return None res = rpc.get('getblockhash', [height]) out = {} if 'output' in res and 'result' in res['output']: out['hash'] = res['output']['result'] res = rpc.get('getblockheader', [out['hash']]) out['time'] = res['output']['result']['time'] out['height'] = height return out if __name__ == '__main__': if DEBUG: app.debug = True rpc = RPC(RPCUSER, RPCPASS, SERVER, RPCPORT) try: rpc.get('getblockcount') core_enabled = CORE_ENABLED except: core_enabled = False print("Core enabled: " + str(core_enabled)) app.run(host='0.0.0.0', port=SERVER_PORT)