def get_service_status(): """ Retrieve user configuration, and status of wallet's rpc server, transaction index, and gpg's installation. """ conf = get_config() if 'rpcpassword' in conf and conf['rpcpassword']: conf['rpcpassword'] = "******" try: rpc_raw = AuthServiceProxy(get_rpc_url()) rpc_raw.getblockcount() conf['wallet_connected_status'] = "good" except: conf['wallet_connected_status'] = "bad" try: if not os.path.exists(peerapps.settings.BASE_DIR+"/test_gpg_setup"): os.mkdir(peerapps.settings.BASE_DIR+"/test_gpg_setup") gnupg.GPG(gnupghome=peerapps.settings.BASE_DIR+"/test_gpg_setup") shutil.rmtree(peerapps.settings.BASE_DIR+"/test_gpg_setup", ignore_errors=True) conf['gpg_suite_installed'] = "good" except: conf['gpg_suite_installed'] = "bad" return conf
def get_recent_data(rpc_connection: authproxy.AuthServiceProxy, amount: int, l_s: int, fuzzy: int) -> list: """Returns all data included in OP_RETURN transactions from last `amount` blocks Parameters ---------- rpc_connection : bitcoinrpc.authproxy.AuthServiceProxy The RPC connection to the bitcoind client amount : int Amount of recent blocks to search l_s : int Consider only blocks that have b mod modulo = 0 fuzzy : int Also consider a small intervall around above condition Returns ------- list A list of hex strings representing the data found in last amount blocks Raises ------ ValueError If `amount` is bigger than number of blockchain blocks """ block_max = rpc_connection.getblockcount() block_min = block_max - amount + 1 if block_min < 1: raise ValueError("Argument too big: There are not that many blocks.") return get_data_from_block_range(rpc_connection, block_min, block_max, l_s, fuzzy)
def query_transactions(ticker=None): if not ticker: for c in Currency.objects.all(): query_transactions.delay(c.ticker) return currency = Currency.objects.select_for_update().get(ticker=ticker) coin = AuthServiceProxy(currency.api_url) current_block = coin.getblockcount() processed_transactions = [] block_hash = coin.getblockhash(currency.last_block) transactions = coin.listsinceblock(block_hash)['transactions'] for tx in transactions: if tx['txid'] in processed_transactions: continue if tx['category'] not in ('receive', 'generate', 'immature'): continue process_deposite_transaction(tx, ticker) processed_transactions.append(tx['txid']) currency.last_block = current_block currency.save() for tx in Transaction.objects.filter(processed=False, currency=currency): query_transaction(ticker, tx.txid)
def query_transactions(ticker=None): if not ticker: for c in Currency.objects.all(): query_transactions.delay(c.ticker) return currency = Currency.objects.select_for_update().get(ticker=ticker) coin = AuthServiceProxy(currency.api_url) current_block = coin.getblockcount() processed_transactions = [] block_hash = coin.getblockhash(currency.last_block) transactions = coin.listsinceblock(block_hash)['transactions'] for tx in transactions: if tx['txid'] in processed_transactions: continue if tx['category'] not in ('receive', 'generate', 'immature'): continue process_deposite_transaction(tx, ticker) processed_transactions.append(tx['txid']) currency.last_block = current_block currency.save() for tx in Transaction.objects.filter(processed=False, currency=currency): query_transaction(ticker, tx.txid)
def query_transactions(): """query_transactions.""" node = AuthServiceProxy(settings.RPC_API_URL) currency = Currency.objects.select_for_update().get( ticker=settings.DEFAULT_CURRENCY) #get the block count from the node current_block = node.getblockcount() print(current_block) for product in Product.objects.all(): #get all transactions with minimum confs for each adress in products ##TODO print('Scanning transactions from address: ' + product.address) transactions = node.z_listreceivedbyaddress(product.address, settings.REQUIRED_CONFS) print('Number of tx recieved from node: ' + str(len(transactions))) for tx in transactions: #process transaction if the tx blockheight is less than the last block if tx['blockheight'] - settings.REQUIRED_CONFS < currency.last_block: print('transaction in block already scanned') continue tx['address'] = product.address process_tx(tx, product) #update the last block currency.update_last_block(current_block) currency.save()
def index(request): # Bitcoin RPC Credentials (you need to change these) rpc_port = "8332" rpc_user = "******" rpc_password = "******" # LIGHTNING NETWORK # Lightning Network Socket file (you might need to change this) ln = LightningRpc("/home/pi/.lightning/lightning-rpc") try: l_info = ln.getinfo() l = LightningViewData(True) l.block_height = l_info["blockheight"] l.version = l_info["version"] l.version = l.version.replace("v", "") l_peers = ln.listpeers() l.peer_count = len(l_peers["peers"]) l_funds = ln.listfunds() l.channel_count = len(l_funds["channels"]) except: l = LightningViewData(False) # BITCOIN b = BitcoinViewData(True) try: rpc_connection = AuthServiceProxy("http://%s:%[email protected]:%s" % (rpc_user, rpc_password, rpc_port)) b_conn_count = rpc_connection.getconnectioncount() if b_conn_count > 0: b.online = True except Exception as e: b.running = False if b.running == True: try: b.block_height = rpc_connection.getblockcount() b_network_info = rpc_connection.getnetworkinfo() b.peer_count = b_network_info["connections"] b.version = b_network_info["subversion"] b.version = b.version.replace("/", "") b.version = b.version.replace("Satoshi:", "") except Exception as e: b.message = str(e) # RETURN VIEW DATA return render(request, 'dashboard/index.html', { 'lightning': l, 'bitcoin': b })
def sync(): print("trying sync") try: rpc_connect = AuthServiceProxy("http://{}:{}@{}:{}".format(rpc_user,rpc_password,nodeip,rpc_port)) blocks = rpc_connect.getblockcount() peers = rpc_connect.getconnectioncount() sync_prog = str(round(rpc_connect.getblockchaininfo()['verificationprogress']*100, 2)) + "%" return "👥 Peers: {}\n\n⏹ Block Height: {}\n\n🔄 Sync Progress: {}".format(peers, blocks, sync_prog) except: return "Something went wrong. Check your node is properly connected."
def main(): while True: try: access = AuthServiceProxy(authserv) function = access.getnettotals() funcname = str("getnettotals") for subkey in ['totalbytesrecv', 'totalbytessent']: value = function[subkey] printValue("counter", funcname, funcname, subkey, value) function = access.getnetworkinfo() funcname = str("getnetworkinfo") subkey = str("connections") value = function[subkey] printValue("gauge", subkey, funcname, subkey, value) function = access.getmempoolinfo() funcname = str("getmempoolinfo") for subkey in ['size', 'bytes']: value = function[subkey] #without this it will appear "stacked" in CGP Panel funccat = (str(funcname) + "_" + str(subkey)) printValue("gauge", funccat, funcname, subkey, value) #since 0.12 estimatefee 1 fails. Use estimatefee 2 instead. #see https://github.com/bitcoin/bitcoin/issues/7545 function = access.estimatefee(2) funcname = str("estimatefee") value = function printValue("gauge", funcname, funcname, funcname, value) #get size, height, diff of the last block function = access.getblockcount() blockcount = function #get hash of last block function = access.getblockhash(blockcount) blockhash = function #get info from blockhash function = access.getblock(blockhash) funcname = str("getblock") for subkey in ['size', 'height', 'difficulty']: funccat = (str(funcname) + "_" + str(subkey)) value = function[subkey] printValue("gauge", funccat, funcname, subkey, value) #network hashrate function = access.getnetworkhashps() funcname = str("getnetworkhashps") value = function printValue("gauge", funcname, funcname, funcname, value) except: pass sys.stdout.flush() time.sleep(interval)
class ParsingBlock(Parsing_block): def __init__(self, from_block=0, db_name="pars", collection="data3", to_block=-1): self.client = ClientHistory() self.from_block = from_block self.to_block = to_block self.qtum = AuthServiceProxy(qtum_server) self.db_wallet = Table_new(db_name, collection) def check(self, vout): try: for vout_i in vout: try: script_pub_key = vout_i["scriptPubKey"] addresses = script_pub_key["addresses"] value = vout_i["value"] value_float = float(value) value_int = int(value * (10**8)) for adr in addresses: data = self.client.getbalance(adr) if data == {'error': 404}: pass else: db_coin = self.db_wallet.insert_new( **{ "adr": adr, "value": value_int }) update_data_1 = self.client.incbalance( adr, value_float) #logging.critical(update_data_1) except: pass except: pass def decode_raw_transaction_vout(self, encoded_datas=None): try: if not encoded_datas: encoded_datas = self.get_raw_transaction() for encoded_data in encoded_datas: transaction_data = self.qtum.decoderawtransaction(encoded_data) vin = transaction_data["vin"] vout = transaction_data["vout"] self.check(vout) self.show_db() except: pass def getblockcount(self): return self.qtum.getblockcount()
def index(): try: rpc_connect = AuthServiceProxy("http://{}:{}@{}:{}".format(rpc_user,rpc_password,allowed_ip,rpc_port)) current_block_height = rpc_connect.getblockcount() onchain_peers = rpc_connect.getconnectioncount() onchain_balance = rpc_connect.getbalance() bitcoin_version = (rpc_connect.getnetworkinfo()['subversion'])[1:-1].replace("Satoshi:","") sync_prog = str(round(rpc_connect.getblockchaininfo()['verificationprogress']*100, 2)) + "%" chain_type = rpc_connect.getblockchaininfo()['chain'] if onchain_balance > 0 and chain_type == "main": onchain_balance = u"₿ " + str(onchain_balance) elif onchain_balance == 0: onchain_balance = u"₿ " + str(0) elif onchain_balance > 0 and chain_type == "test": onchain_balance = u"t₿ " + str(onchain_balance) else: onchain_balance = u"t₿ " + str(0) if chain_type == "test": chaintype_ln = "testnet" else: chaintype_ln = "mainnet" except: current_block_height = onchain_peers = onchain_balance = bitcoin_version = sync_prog = chain_type = "Offline!" try: os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA' with open(os.path.expanduser(lnd_dir_location + 'data/chain/bitcoin/{}/admin.macaroon'.format(chaintype_ln)), 'rb') as f: macaroon_bytes = f.read() macaroon = codecs.encode(macaroon_bytes, 'hex') cert = open(os.path.expanduser(lnd_dir_location + 'tls.cert'), 'rb').read() creds = grpc.ssl_channel_credentials(cert) channel = grpc.secure_channel('localhost:10009', creds) stub = lnrpc.LightningStub(channel) response = stub.GetInfo(ln.GetInfoRequest(), metadata=[('macaroon', macaroon)]) satbalance = stub.ChannelBalance(ln.ChannelBalanceRequest(), metadata=[('macaroon', macaroon)]) lightning_channels_act = response.num_active_channels lightning_peers = response.num_peers offchain_balance = u"ş " + str(format(satbalance.balance,',')) lightning_version = response.version[:5] alias = response.alias except: lightning_channels_act = lightning_peers = offchain_balance = lightning_version = alias = "Offline!" return render_template('index.html', current_block_height=current_block_height, onchain_peers=onchain_peers, onchain_balance=onchain_balance, bitcoin_version=bitcoin_version, sync_prog=sync_prog, chain_type=chain_type, lightning_channels_act=lightning_channels_act, lightning_peers=lightning_peers, offchain_balance=offchain_balance, lightning_version=lightning_version, alias=alias)
def check_btc(url, port): try: if "http" in url: node_url = url + port else: node_url = "http://%s:%s@%s:%s" % ("RPCuser", "RPCpasswd", url, port) rpc_connection = AuthServiceProxy(node_url) _ = rpc_connection.getblockcount() except Exception as e: return False, str(e) return rpc_connection, None
def get_block_height(): """ Method used to get block height Returns: Block height (int) """ rpc = AuthServiceProxy( ("http://%s:%[email protected]:%s/") % (config['RPC_USER'], config['RPC_PASS'], config['RPC_PORT'])) return rpc.getblockcount()
def monitor(verbose=False): url = "http://{0}:{1}@127.0.0.1:8332".format( USERNAME, PASSWORD ) btcd = AuthServiceProxy(url) peerheight = max_peer_height(btcd) blockheight = btcd.getblockcount() # wait until the our local copy of the chain has caught up before notifying # of changes to the blockchain while blockheight < peerheight: if verbose: print "waiting for rpc bitcoind at height {0} to reach height {1}" \ .format(blockheight, peerheight) blockheight = btcd.getblockcount() time.sleep(10) while True: for name in CHECKPOINT: current = getattr(btcd, name)() action, last = CHECKPOINT[name] if verbose: print name, " last: ", last, " current: ", current if last is not None and last != current: print action(btcd, current) CHECKPOINT[name] = (action, current) if verbose: print "sleeping for ten seconds" time.sleep(10)
def listen(path): mongo = MongoClient() rpc = AuthServiceProxy("http://%s:%[email protected]:8332" % (RPC_USER, RPC_PASSWORD)) db = DatabaseGateway(database=mongo.exploder) syncer = ExploderSyncer(database=db, blocks_dir=path, rpc_client=rpc, rpc_sync_percent=98) while True: time.sleep(5) if db.highest_block is None or rpc.getblockcount( ) > db.highest_block.height: syncer.sync() sys.stdout.flush()
class BitcoinCLI: def __init__(self): self.rpc_connection = AuthServiceProxy(config.endpoint) def get_best_block_hash(self): return self.rpc_connection.getbestblockhash() def get_block_count(self): return self.rpc_connection.getblockcount() def get_best_block(self): return self.rpc_connection.getblock(self.rpc_connection.getbestblockhash()) def get_block_hash(self, height): return self.rpc_connection.getblockhash(height) def get_block(self, hash): return self.rpc_connection.getblock(hash) def get_transaction(self, hash): return self.rpc_connection.gettransaction(hash) def get_txn_list_from_block(self, hash): block = self.get_block(hash) if 'tx' in block: return block['tx'] else: raise KeyError('Block {0} has no attribute tx'.format(hash)) def get_raw_transaction(self, tx_id): out = self.rpc_connection.getrawtransaction(tx_id, 1) return out def decoderawtransaction(self, tx_id): out = self.rpc_connection.decoderawtransaction(raw) return out def get_tx_outputs(self, tx_id): tx = self.rpc_connection.getrawtransaction(tx_id, 1) outputs = [float(i['value']) for i in tx['vout']] return outputs def get_tx_details(self, tx_id): tx = self.rpc_connection.getrawtransaction(tx_id, 1) outputs = [float(i['value']) for i in tx['vout']] return outputs
class DucatuscoreInterface: endpoint = None settings = None def __init__(self): self.settings = NETWORK_SETTINGS['DUC'] self.setup_endpoint() self.rpc = AuthServiceProxy(self.endpoint) self.check_connection() def setup_endpoint(self): self.endpoint = 'http://{user}:{pwd}@{host}:{port}'.format( user=self.settings['user'], pwd=self.settings['password'], host=self.settings['host'], port=self.settings['port']) return def check_connection(self): block = self.rpc.getblockcount() if block and block > 0: return True else: raise DucatuscoreInterfaceException('Ducatus node not connected') @retry_on_http_disconnection def node_transfer(self, address, amount): try: value = amount / DECIMALS['DUC'] print('try sending {value} DUC to {addr}'.format(value=value, addr=address), flush=True) self.rpc.walletpassphrase(self.settings['wallet_password'], 30) res = self.rpc.sendtoaddress(address, value) print(res, flush=True) return res except JSONRPCException as e: err = 'DUCATUS TRANSFER ERROR: transfer for {amount} DUC for {addr} failed' \ .format(amount=amount, addr=address) print(err, flush=True) print(e, flush=True) raise DucatuscoreInterfaceException(err + '\n' + str(e))
def query_transactions(ticker=None): # logger.info("Execute Query Transactions") if not ticker: #logger.warning("No ticker found. Performing Currency lookup.") for c in Currency.objects.all(): #logger.info("Deffered Query Transactions: {}".format(c.ticker)) query_transactions.delay(c.ticker) return # logger.info("Ticker found: {}".format(ticker)) currency = Currency.objects.select_for_update().get(ticker=ticker) coin = AuthServiceProxy(currency.api_url) # logger.info("RPC Call to {}".format(currency.api_url)) current_block = coin.getblockcount() # logger.info("Current Block: {}".format(current_block)) processed_transactions = [] block_hash = coin.getblockhash(currency.last_block) # logger.info("Block Hash: {}".format(block_hash)) blocklist = coin.listsinceblock(block_hash) # logger.info("Block List since {0} : {1}".format(block_hash, blocklist)) transactions = blocklist['transactions'] # logger.info("Transactions: {}".format(transactions)) for tx in transactions: if tx['txid'] in processed_transactions: continue if tx['category'] not in ('receive', 'generate', 'immature'): continue # logger.info("Processing Transactions: {}".format(tx)) process_deposite_transaction(tx, ticker) processed_transactions.append(tx['txid']) currency.last_block = current_block # log.info("Latest block: {}".format(current_block)) currency.save() for tx in Transaction.objects.filter(processed=False, currency=currency): # logger.info("Querying Tx: {0} -> {1}".format(ticker, tx.txid)) query_transaction(ticker, tx.txid)
class Coind: def __init__(self): # connect to the local coin daemon. self.access = AuthServiceProxy("http://%s:%[email protected]:12341" % ('RPCuser', 'RPCpassword')) def getblockhash(self, idx): b_hash = self.access.getblockhash(idx) return (b_hash) def getblock(self, b_hash): block = self.access.getblock(b_hash) #{ u'merkleroot': u'74a2d1db8db7dc5e65d3d6f2058a6f1b5e893ddaf87c4c98d1a008e406b9beae', # u'nonce': 122400, # u'previousblockhash': u'6850dc01c014a262018fe2e29c299fc33dfe6d47fe5ef2f7cfa5f51f10bc61b3', # u'hash': u'642b7b504b315dd12683eb132e9a536958a89c03638ebc7582ef4d50893f0b89', # u'version': 2, # u'tx': [ # u'46eb85610e8260a5eeccdfb14bf393b83ff704ccaca08e2dc639c2ebd9cdff57', # u'dd28e708147c66b2ebaa23bfcce436afddfcdd1a268867465389c8c6d114cf82' # ], # u'height': 176058, # u'difficulty': Decimal('587.97880435'), # u'nextblockhash': u'530761664af30cc6e119cef47222ff179982cdc6e5f1fd70d06bb72bafde649c', # u'confirmations': 7, # u'time': 1419937013, # u'bits': u'1b6f7546', # u'size': 1227 # } return (block) def gettransaction(self, t_hash): try: trans = self.access.gettransaction(t_hash) except: return (False) return (trans) def getblockcount(self): return (self.access.getblockcount())
class Coind: def __init__(self): # connect to the local coin daemon. self.access = AuthServiceProxy("http://%s:%[email protected]:12341"%('RPCuser', 'RPCpassword')) def getblockhash(self, idx): b_hash = self.access.getblockhash(idx) return(b_hash) def getblock(self, b_hash): block = self.access.getblock(b_hash) #{ u'merkleroot': u'74a2d1db8db7dc5e65d3d6f2058a6f1b5e893ddaf87c4c98d1a008e406b9beae', # u'nonce': 122400, # u'previousblockhash': u'6850dc01c014a262018fe2e29c299fc33dfe6d47fe5ef2f7cfa5f51f10bc61b3', # u'hash': u'642b7b504b315dd12683eb132e9a536958a89c03638ebc7582ef4d50893f0b89', # u'version': 2, # u'tx': [ # u'46eb85610e8260a5eeccdfb14bf393b83ff704ccaca08e2dc639c2ebd9cdff57', # u'dd28e708147c66b2ebaa23bfcce436afddfcdd1a268867465389c8c6d114cf82' # ], # u'height': 176058, # u'difficulty': Decimal('587.97880435'), # u'nextblockhash': u'530761664af30cc6e119cef47222ff179982cdc6e5f1fd70d06bb72bafde649c', # u'confirmations': 7, # u'time': 1419937013, # u'bits': u'1b6f7546', # u'size': 1227 # } return(block) def gettransaction(self, t_hash): try: trans = self.access.gettransaction(t_hash) except: return(False) return(trans) def getblockcount(self): return(self.access.getblockcount())
def get_latest_block(host, port, user, password): try: rpc_connection = AuthServiceProxy("http://%s:%s@%s:%s" % (user, password, host, port)) block_count = rpc_connection.getblockcount() logger.debug("Block Count: " + block_count) return block_count except socket_error: logger.critical("Connection Refused!! \ Confirm the status of bitcoin RPC service.") quit() except JSONRPCException: try: # Use subprocess library to run bash command to get block count p = subprocess.Popen(["bitcoin-cli", "getblockcount"], stdout=subprocess.PIPE) output, err = p.communicate() block_count = int(output) logger.debug("Block Count: " + str(block_count)) return block_count except Exception as err: logger.critical(err) quit()
class UsdtWallet(): USDT_BLOCK_NUM = 'http://www.tokenview.com:8088/coin/latest/USDT' USDT_TX_API = 'https://api.omniexplorer.info/v1/transaction/address' USDT_URL_BALANCE = 'https://api.omniexplorer.info/v1/address/addr/' def __init__(self, consul_client=None): if consul_client: self.init_consul(consul_client) def init_consul(self, app, consul_client): self.propertyid = 31 # self.usdt_rpc_user = app.config["USDT_RPC_USER"] # self.usdt_rpc_password = app.config["USDT_RPC_PWD"] # self.usdt_passphrase = app.config.get('GETH_USDT_PASSPHRASE') # self.consul_client = consul_client # # self.wallet_url = self.consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.USDTEREUM_CLI) # self.wallet_url = '47.52.131.71:7332' # print(self.wallet_url) # self.usdtcoin_cli = AuthServiceProxy( # "http://%s:%s@" % (self.usdt_rpc_user, self.usdt_rpc_password) + self.wallet_url, timeout=10) # if not self.is_connected(): # logging.error('Connect USDT wallet node fial') self.usdtcoin_cli = AuthServiceProxy("http://%s:%[email protected]:7332" % ('xianda', 'ABQOqmPZ0tr95f5Z')) def is_connected(self): """获取钱包状态判读是否链接""" try: if self.usdtcoin_cli.getwalletinfo().get('walletversion'): return True return False except Exception as e: return False def is_syncing(self): """节点是否在同步中""" # 注意返回Flase表示节点同步完成 info = self.usdtcoin_cli.getblockchaininfo() # print(info['blocks'], info['headers']) if info['blocks'] != info['headers']: return False else: return True def accountCreate(self, accountName): # 否则,创建账户,并返回账户地址 address = self.usdtcoin_cli.getaccountaddress(accountName) privateKey = self.usdtcoin_cli.dumpprivkey(address) return privateKey, address # 檢驗賬戶是否有效 def is_valid_address(self, address): if address is None or address == '': return False else: try: # print(self.usdtcoin_cli.validateaddress(address)) return self.usdtcoin_cli.validateaddress(address).get( 'isvalid') except: return False # 獲取餘額 def get_balance(self, address): """获取余额,默认最新区块""" try: balance = str( self.usdtcoin_cli.omni_getbalance(address, self.propertyid)['balance']) except Exception as e: logging.error('USDT node get balance error:{}'.format(str(e))) raise Exception('USDT node get balance error') return Decimal(balance) def get_block_num(self): """获取最新区块数""" try: block_num = self.usdtcoin_cli.getblockcount() except Exception as e: logging.error('Get eth node block number error:{}'.format(str(e))) return return block_num def get_nonce(self, address): """获取账户nonce值""" try: # pending 获得最新已使用的nonce,对nonce进行加1 nonce = len( self.usdtcoin_cli.omni_listpendingtransactions(address)) except Exception as e: logging.error('USDT node get balance error:{}'.format(str(e))) raise Exception('USDT node get balance error') return nonce def get_mian_block_num(self): """获取公链上的最新区块数""" try: header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36', } ret = session_pool.get(self.USDT_BLOCK_NUM, headers=header, timeout=30).json() if ret is None: logging.error('Get usdt main chain block number error') return block_num = ret.get('data') except Exception as e: logging.error( 'Get usdt main chain block number error:{}'.format(e)) return return block_num # int def get_minerFee(self, address): data = {'addr': address} try: balance = None rets = session_pool.post(self.USDT_URL_BALANCE, data=data, timeout=50).json().get('balance') if rets or len(rets) != 0: for ret in rets: if ret.get('propertyinfo') and int( ret.get('propertyinfo').get('propertyid')) == 0: balance = ret.get('value') except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'.format( address, str(e), self.USDT_TX_API)) raise Exception('USDT node get balance error') return Decimal(balance) / 100000000 def usdt_transaction_record(self, address, last_timestamp, start_block=None, end_block=None): """查询账户交易记录""" if start_block is None: start_block = 0 if end_block is None: end_block = 99999999 # 可能会有重复记录,使用此方法 run_function = lambda x, y: x if y in x else x + [y] data = {'addr': address, 'page': 0} try: rets = session_pool.post(self.USDT_TX_API, data=data, timeout=50).json() except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'.format( address, str(e), self.USDT_TX_API)) rets = None new_records = [] ret = rets.get('transactions') if ret is None: return new_records ret_page_num = int(rets.get('pages')) if ret_page_num == 1: # print(ret_page_num) self.query_records(address, ret, new_records, last_timestamp, start_block, end_block) return (reduce(run_function, [ [], ] + new_records)) else: for i in range(0, ret_page_num): data = {'addr': address, 'page': i} try: ret = session_pool.post( self.USDT_TX_API, data=data, timeout=50).json().get('transactions') except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'. format(address, str(e), self.USDT_TX_API)) ret = None if ret is None: return new_records self.query_records(address, ret, new_records, last_timestamp, start_block, end_block) return (reduce(run_function, [ [], ] + new_records)) def query_records(self, address, records, new_records, last_timestamp, start_block, end_block): for record in records: propertyid = record.get('propertyid') valid = record.get('valid') block = record.get('block') if valid and int(propertyid) == 31 and int(start_block) <= int( block) and int(block) <= int(end_block): to_address = record['referenceaddress'] # 是否为收款记录 current_timestamp = int(record['blocktime']) # 当前记录时间戳 confirmations = int(record['confirmations']) # 交易记录确认数 record_hash = record['txid'] amount = Decimal(record['amount']) if to_address.lower() != address.lower(): continue if int(last_timestamp) > int(current_timestamp): continue if Order.hash_is_exist(record_hash): continue if amount < Decimal('0.0000001'): continue if confirmations < 2: break else: new_records.append(record) else: if records is None: logging.error( 'Request USDT_TX_API fail address:{} ret:{}, url:{}'. format(address, str(records), self.USDT_TX_API)) return new_records def hash_get_detail(self, tx_hash): """hash获取交易细节,用于确认链外交易是否被确认""" # 交易是否被确认.status=1(被确认) is_confirm = False # 是否确认 is_success = False # 如果已确认,交易是否成功 msg = None # 未被确认返回异常信息(一般超时),确认失败:失败的细节,确认成功:交易详情 fee = None # 确认成功交易的手续费 try: ret = self.usdtcoin_cli.omni_gettransaction(tx_hash) # 获取交易细节 except Exception as e: msg = str(e) return is_confirm, is_success, msg, fee confirm = ret.get('confirmations') if confirm < 1: # 确认交易失败 msg = dict(fail_detail=str(ret)) return is_confirm, is_success, msg, fee else: # 确认交易成功 is_confirm = True is_success = True fee = ret.get('fee') msg = dict(confirm=str(ret), tx_detail=str(ret)) return is_confirm, is_success, msg, fee def payment(self, addrfrom, addrto, amount): """普通付款""" # 单位换算 payload = {'from': addrfrom, 'to': addrto, 'value': str(amount)} try: # 钱包转账,返回交易哈希值 tx_hash = self.usdtcoin_cli.omni_send(addrfrom, addrto, self.propertyid, str(amount)) return True, tx_hash except Exception as e: payload.update(dict(errormsg=str(e))) logging.error('usdt payment error:{}'.format(str(payload))) return False, str(e) def raw_transaction(self, minerfee_address, fromAddr, toAddre, value, miner_minfee): # 查询USDT未使用的UTXO USDT_unspents = self.usdtcoin_cli.listunspent(1, 9999999, [fromAddr]) if not USDT_unspents: return False, str('No USDT UTXO model available') USDT_unspent = USDT_unspents[0] # 查询BTC未使用的UTXO(矿工费) BTC_unspents = self.usdtcoin_cli.listunspent(1, 9999999, [minerfee_address]) if not BTC_unspents: return False, str('No BTC UTXO model available') BTC_unspent = BTC_unspents[0] # 所用值 from_txid = USDT_unspent['txid'] from_scriptPubKey = USDT_unspent['scriptPubKey'] from_vout = USDT_unspent['vout'] from_amount = USDT_unspent['amount'] to_txid = BTC_unspent['txid'] to_scriptPubKey = BTC_unspent['scriptPubKey'] to_vout = BTC_unspent['vout'] to_amount = BTC_unspent['amount'] rawtransactionparams = [ dict(txid=from_txid, scriptPubKey=from_scriptPubKey, vout=from_vout), dict(txid=to_txid, scriptPubKey=to_scriptPubKey, vout=to_vout), ] # 创建原生BTC交易获取哈希值 RawTxChangeparams = [ # 转出地址必须放在第一个,矿工费地址放在下面 dict(txid=from_txid, scriptPubKey=from_scriptPubKey, vout=from_vout, value=from_amount), dict(txid=to_txid, scriptPubKey=to_scriptPubKey, vout=to_vout, value=to_amount), ] # 构造发送代币类型和代币数量数据 payload = self.usdtcoin_cli.omni_createpayload_simplesend( self.propertyid, str(value)) print('usdt交易', payload) # 构造交易基本数据 data = {} btc_txid = self.usdtcoin_cli.createrawtransaction( rawtransactionparams, data) # 在交易上绑定代币数据 rawtx = self.usdtcoin_cli.omni_createrawtx_opreturn(btc_txid, payload) print('usdt交易绑定到btc交易的哈希', rawtx) # 在交易上添加接收地址 rawtx = self.usdtcoin_cli.omni_createrawtx_reference(rawtx, toAddre) print('添加接受地址', rawtx) # 在交易数据上指定矿工费用 rawtx = self.usdtcoin_cli.omni_createrawtx_change( rawtx, RawTxChangeparams, minerfee_address, Decimal(miner_minfee)) print('设置手续的哈希', rawtx) # 签名 ret = self.usdtcoin_cli.signrawtransaction(rawtx) if not ret['complete']: return False, str('Incomplete signature') # 广播 tx_hash = self.usdtcoin_cli.sendrawtransaction(ret['hex']) print('交易哈希', tx_hash) if tx_hash: return True, tx_hash
from bitcoinrpc.authproxy import AuthServiceProxy from pydash import at import numpy as np import matplotlib.pylab as plt import time import sys JSON_username = "******" JSON_pass = "******" rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332" % (JSON_username, JSON_pass)) genesis_block_hash = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f' blockchain_length = rpc_connection.getblockcount() current_block = {} current_total_size = 0 total_size = [] list = [] # parameters for iteration printing digits = len(str(blockchain_length - 1)) delete = "\b" * digits start_time = time.time() for i in range(blockchain_length + 1): print("{0}{1:{2}}".format(delete, i, digits), end="") sys.stdout.flush() if i == 0: current_block_hash = genesis_block_hash
class BtcWallet(): """btc钱包""" BTC_BLOCK_API = 'https://blockchain.info/' def __init__(self, app=None, consul_client=None): if app and consul_client: self.init_consul(app, consul_client) def init_consul(self, app, consul_client): try: rpc_user = app.config.get('CONFIG_BITCOIND_RPC_USER') rpc_pwd = app.config.get('CONFIG_BITCOIND_RPC_PASSWORD') wallet_passphrase = app.config.get('CONFIG_BITCOIND_WALLET_PASSWORD') self.ipport = consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.BTC_CLI) # s = "http://%s:%s@" % (self.user, self.pwd) + self.ipport # print(s) self.bitcoin_cli = AuthServiceProxy( "http://%s:%s@" % (rpc_user, rpc_pwd) + self.ipport, timeout=10) print("Succeed to connect to the BTC node") except Exception as e: print(str(e)) print("Failed to connect to the BTC node") # 是否连接BTC节点 def is_connected(self): try: if self.bitcoin_cli.getwalletinfo().get('walletversion'): return True return False except Exception as e: print(str(e)) print("Failed to connect to the BTC node") # 节点是否同步 def is_sync(self): ret = self.bitcoin_cli.getblockchaininfo() if ret.get('blocks') != ret.get("headers"): return False else: return True # btc地址是否有效 def is_valid_address(self, coin_address): if coin_address is None or coin_address == '': return False else: ret = self.bitcoin_cli.validateaddress(coin_address).get('isvalid') print('账户检查结果:', ret) return ret # return self.bitcoin_cli.validateaddress(coin_address).get('isvalid') # 获取账户余额, 默认经过6个区块确认 def get_balance(self, coin_address): transaction_lists = self.bitcoin_cli.listunspent(1, 99999999, [coin_address]) print(transaction_lists) current_amount = 0 for transaction_list in transaction_lists: amount = transaction_list.get('amount') amount = float(amount) current_amount += amount return current_amount def get_balance_by_account(self, account): try: ret = self.bitcoin_cli.getbalance(account) return ret except Exception as e: logging.error('get balance error:{}'.format(str(e))) return None def estimate_fee(self): try: fee = self.bitcoin_cli.estimatefee(6) return fee except Exception as e: logging.error('get fee error:{}'.format(str(e))) return None def create_account(self, stellar_account): # private = random_key() # address = pubtoaddr(privtopub(private)) # print(address, private) # return address, private address = self.bitcoin_cli.getnewaddress(stellar_account) private_key = self.bitcoin_cli.dumpprivkey(address) return address, private_key def get_block_num(self): """获取最新区块数""" try: block_num = self.bitcoin_cli.getblockcount() return block_num except Exception as e: logging.error('Get btc node block number error:{}'.format(str(e))) return None def get_chain_info(self): ret = self.bitcoin_cli.getblockchaininfo() return ret def get_block_info(self, block_num): """获取区块的详细信息""" param = "block-height/{}?format=json".format(block_num) api_url = self.BTC_BLOCK_API + param # print(api_url) blocks = requests.get(api_url, timeout=500).json() # print(type(blocks)) return blocks # 链外转帐,普通交易 def payment(self, btc_base_account, address_to, amount): try: txid = self.bitcoin_cli.sendfrom(btc_base_account, address_to, amount) return True, txid except Exception as e: logging.error('btc payment error:{}'.format(str(e))) return False, str(e) def hash_get_detail(self, tx_id): """ Arguments: 1. "txid" (string, required) The transaction id """ # 根据txid获取确认链外交易信息 ret = self.bitcoin_cli.gettransaction(tx_id) abandoned = ret.get("details")[0].get("abandoned") # 获取abandon信息 confirmation_num = ret.get('confirmations') # 获取确认数 # 如果确认数小于1,则未确认 if confirmation_num < 1: msg = dict(confirm=str(ret)) # msg = ret.get("details")[0] return False, False, msg, None # 如果确认数大于1,则确认 else: msg = dict(confirm=str(ret)) # msg = ret fee = abs(ret.get("fee")) if abandoned: return True, False, msg, None else: return True, True, msg, fee def raw_payment(self, address_from, address_to, collect_amount): inputs = [] # 获取地址余额信息 try: unspend_lists = self.bitcoin_cli.listunspent(1, 9999999, [address_from]) for unspend_list in unspend_lists: # if unspend_list.get('amount') <= 0: # continue # else: txid = unspend_list.get('txid') vout = unspend_list.get('vout') inputs.append({'txid': txid, 'vout': vout}) outputs = {address_to: round(collect_amount, 8)} # 交易建立和签名时不用连接比特币网络,只有在执行交易时才需要将交易发送到网络 # 创建裸交易 transaction_hash = self.bitcoin_cli.createrawtransaction(inputs, outputs) # 使用私钥签名,获取16进制信息 hex = self.bitcoin_cli.signrawtransaction(transaction_hash).get('hex') # 广播到p2p网络,返回交易哈希 trading_hash = self.bitcoin_cli.sendrawtransaction(hex, False) return True, trading_hash, '' except Exception as e: print(e) return None, None, '' def btc_transaction_record(self, block_num): # 获取某一区块信息 block_info = self.get_block_info(block_num) blocks = block_info.get('blocks') txs = blocks[0].get('tx') records = [] for tx in txs: outs = tx.get('out') hash = tx.get('hash') inputs = tx.get('inputs') p_out = inputs[0].get('prev_out') if not p_out: continue else: addr_from = p_out.get('addr') for out in outs: re = [] addr_to = out.get('addr') value = out.get('value') / (10 ** 8) # addr_to与User表中绑定的地址进行对比,如果有,则说明此address_to有冲币记录 user = User.address_query_user('BTC', addr_to) if not user: continue else: re.append(addr_from) re.append(addr_to) re.append(value) re.append(hash) records.append(re) return records def get_accounts(self, addr): try: ad = self.bitcoin_cli.getaccount(addr) return ad except Exception as e: # logging.error('get btc_account error:{}'.format(str(e))) return None def get_address_byaccount(self, account): re = self.bitcoin_cli.getaddressesbyaccount(account) return re def test1(self): transaction_list = self.bitcoin_cli.listaccounts() # transaction_list = self.bitcoin_cli.getwalletinfo() print(transaction_list)
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException CSVFiles = "D:\BTC CSV" rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332"%("username", "password")) blockCount = rpc_connection.getblockcount() for i in range(100000, 100100):#blockCount): currentHash = rpc_connection.getblockhash(i) currentBlock = rpc_connection.getblock(currentHash) currentTime = currentBlock['time'] for transaction in currentBlock['tx']: txInfo = rpc_connection.getrawtransaction(transaction) txDecoded = rpc_connection.decoderawtransaction(txInfo) processed = [txDecoded['txid'], currentTime, txDecoded['weight']] for output in txDecoded['vout']: processed.append(str(output['value'])) print("Processed: " + str(processed)) print("Done with block " + str(i))
import httplib2 from bitcoinrpc.authproxy import AuthServiceProxy access = AuthServiceProxy('http://*****:*****@etukent.ddns.net:8338') try: blockCount = access.getblockcount() except Exception as e: print "Problems connecting to bitcoin wallet:" else: try: response, trueBlockCount = httplib2.Http().request("http://blockexplorer.com/q/getblockcount/") except Exception as e: print "Unable to get true blockcount from blockexplorer:"+str(e) else: if (int(trueBlockCount) - 5) > blockCount : print "blockchain not up to date: true block count is: "+str(trueBlockCount)+", while bitcoind is at: "+str(blockCount) else : print "Sync Completed Total Black Count:" , blockCount
# https://github.com/jgarzik/python-bitcoinrpc from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException rpc_connection = AuthServiceProxy("http://*****:*****@127.0.0.1:9245", timeout=120) print(rpc_connection.getblockcount())
class client(): def __init__(self, rpcuser, rpcpassword, rpcbindip, rpcport): serverURL = 'http://' + rpcuser + ':' + rpcpassword + '@' + rpcbindip + ':' + str( rpcport) self.access = AuthServiceProxy(serverURL) def checksynced(self): try: r = self.access.mnsync('status') return (r['IsSynced']) except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_governance(self): try: r = self.access.getgovernanceinfo() ginfo = { "proposalfee": r.get('proposalfee'), "superblockcycle": r.get('superblockcycle'), "nextsuperblock": r.get('nextsuperblock') } return ginfo except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_getblockcount(self): try: r = self.access.getblockcount() return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_prepare(self, preparetime, proposalhex): try: r = self.access.gobject('prepare', str(0), str(1), str(preparetime), proposalhex) return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_submit(self, preparetime, proposalhex, feetxid): try: r = self.access.gobject('submit', str(0), str(1), str(preparetime), proposalhex, feetxid) return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_submit_sb(self, preparetime, triggerhex): try: r = self.access.gobject('submit', str(0), str(1), str(preparetime), triggerhex) return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_vote(self, proposalhash): try: r = self.access.gobject('vote-many', proposalhash, 'funding', 'yes') return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_rawtxid(self, txid): try: r = self.access.getrawtransaction(txid, 1) confirmations = r.get('confirmations') if confirmations: print('confirmations : ', confirmations) return confirmations else: print('confirmations : 0') return 0 except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit() def get_getnewaddress(self): try: r = self.access.getnewaddress() return r except JSONRPCException as e: print(e.args) sys.exit() except Exception as e: print(e.args) sys.exit()
def do(self): rpc = AuthServiceProxy('http://' + settings.BITCOIN_RPC_USERNAME + ':' + settings.BITCOIN_RPC_PASSWORD + '@' + settings.BITCOIN_RPC_IP + ':' + str(settings.BITCOIN_RPC_PORT)) # Total number of blocks blocks = rpc.getblockcount() blocks_processed_queryset = CurrentBlockHeight.objects.order_by('-block_height') blocks_processed = blocks_processed_queryset[0].block_height if blocks_processed_queryset.count() else 0 # Now incoming transactions will be processed and added to database. Transactions # from new blocks are selected, but also transactions from several older blocks. # These extra transactions are updated in case something (for example fork?) is # able to modify transactions in old blocks. EXTRA_BLOCKS_TO_PROCESS = 6 process_since = max(0, blocks_processed - EXTRA_BLOCKS_TO_PROCESS) process_since_hash = rpc.getblockhash(process_since) # Get all old transactions, that require updating old_txs = Transaction.objects.filter(incoming_txid__isnull=False, block_height__gt=process_since) old_txs = [old_tx for old_tx in old_txs] txs = rpc.listsinceblock(process_since_hash)['transactions'] for tx in txs: # Skip other than receiving transactions if tx['category'] != 'receive': continue # Skip unconfirmed transactions for now # TODO: Show these too! if 'blockhash' not in tx: continue # Get required info txid = tx['txid'] address = tx['address'] amount = tx['amount'] block_height = rpc.getblock(tx['blockhash'])['height'] created_at = datetime.datetime.utcfromtimestamp(tx['timereceived']).replace(tzinfo=pytz.utc) # Skip transaction if it doesn't belong to any Wallet try: address = Address.objects.get(address=address) except Address.DoesNotExist: continue # Check if transaction already exists already_found = False for old_tx in old_txs: if old_tx.incoming_txid == txid: # Transaction already exists, so do not care about it any more old_txs.remove(old_tx) already_found = True break # If transaction is new one if not already_found: new_tx = Transaction.objects.create( wallet=address.wallet, amount=amount, description='Received', incoming_txid=txid, block_height=block_height, receiving_address=address, ) new_tx.created_at = created_at new_tx.save(update_fields=['created_at']) # Clean remaining old transactions for old_tx in old_txs: old_tx.delete() # Mark down what the last processed block was blocks = rpc.getblockcount() if blocks_processed_queryset.count() > 0: blocks_processed_queryset.update(block_height=blocks) else: CurrentBlockHeight.objects.create(block_height=blocks)
class Bitcoind: """ Connection to a Bitcoin daemon process. """ def __init__(self, settings): """ Arguments: settings: a settings object; must contain the attribute bitcoinRPCURL. Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL. If settings.bitcoinRPCURL is empty, this object will not be connected. """ if settings.bitcoinRPCURL != "": log.log("Making connection to Bitcoin daemon...") self.access = AuthServiceProxy(settings.bitcoinRPCURL) log.log("...done") else: log.log("Bitcoin-RPC URL is not set: not connecting") self.access = None def isConnected(self): """ Return value: bool Returns whether this object is connected. """ return self.access != None def getBalance(self): """ Return value: int, in Satoshi Returns the balance. """ return self.DecimaltoAmount(self.access.getbalance()) def getBlockCount(self): """ Return value: int Returns the block count. """ return self.access.getblockcount() def getPrivateKey(self, address): """ Arguments: address: str, Base58Check-encoded address Return value: str, Base58Check-encoded private key Returns the private key corresponding to the given address. """ return self.access.dumpprivkey(address) def getTransactionHashesByBlockHeight(self, height): """ Arguments: height: int Return value: list of str, hexadecimal, Bitcoin hash byte order Returns the transaction hashes in the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) block = self.access.getblock(bhash) return block["tx"] def getTransaction(self, thash): """ Arguments: thash: str, hexadecimal, Bitcoin hash byte order Return value: dict, containing: vin: list of dict, each element containing: coinbase [only for coinbase transactions] txid [only for non-coinbase transactions]: str, hexadecimal, Bitcoin hash byte order hash of input transaction Returns information about the transaction indicated by the given hash. """ return self.access.getrawtransaction(thash, 1) def listUnspent(self): """ Return value: list of dict, each element containing: address: str, Base58Check-encoded address amount: int, in Satoshi scriptPubKey: str, binary txid: str, binary, OpenSSL byte order vout: int Returns information about the available unspent transaction outputs. """ ret = self.access.listunspent() for vout in ret: vout["txid"] = binascii.unhexlify(vout["txid"])[::-1] #reversed; TODO: is this the right place? vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"]) vout["amount"] = self.DecimaltoAmount(vout["amount"]) return ret def sendRawTransaction(self, txData): """ Arguments: txData: str, binary Send the given serialized transaction over the Bitcoin network. """ self.access.sendrawtransaction(txData.encode("hex")) def DecimaltoAmount(self, value): return int(value*100000000)
SCL = BDB.StatusCollection MCL = BDB.MotionCollection VCL = BDB.VoteCollection SACL = BDB.SharesAddressCollection BACL = BDB.BitsAddressCollection access = AuthServiceProxy("http://*****:*****@127.0.0.1:14001") #AUTHOR: JOHNY GEORGES #DATE: 29/04/2014 # HEXHASHREVERSER IS USED FOR PREV.BLOCK[v] HASH, MERKLE ROOT, BITS, RAW BLOCK[v] HASH ETC. # GETDIFFICULT WILL SPIT OUT THE DIFFICULTY OF THE BLOCK start_time = time.time() blk01 = "C:/users/home/appdata/roaming/nu/blk0001.dat" blk02 = "C:/users/home/appdata/roaming/nu/blk0002.dat" blk = "" start_time = time.time() print "BlockChain Parsing in Progress..." start = 42000 end = access.getblockcount() for x in xrange(start,end): check = BCT.find({"blockHeight":x}).count() if check > 1: print "Double!", cursor.fetchone() elif check == 0: print "Missing block",x
def verify_app_pre_reqs(splashScreen, app): def progress_ui(status_update): splashScreen.showMessage(status_update) app.processEvents() progress_ui("Performing required startup tasks") client = AuthServiceProxy(url_for_client(), timeout=BTC_CONNECTION_TIMEOUT) try: current_count = client.getblockcount() except Exception as e: return ("Could not connect to bitcoind", traceback.format_exc()) progress_ui("bitcoind connection established") # splashScreen.bar.setValue(25) # step 1 of 5 complete if config.TESTNET: url = 'http://blockexplorer.com/testnet/q/getblockcount' else: url = 'https://blockchain.info/q/getblockcount' def get_last_block(): return urllib.request.urlopen(url).read().decode('utf-8') last_block = get_last_block() if current_count != last_block: progress_ui("Bitcoind blockchain %d blocks behind" % (int(last_block) - int(current_count))) else: progress_ui("Bitcoind blockchain up to date") while current_count != last_block: try: current_count = client.getblockcount() last_block = int(get_last_block()) if current_count == last_block: progress_ui("Bitcoind blockchain up to date") break progress_ui("Current blockchain progress: %s/%s" % (current_count, last_block)) time.sleep(3) except Exception as e: return 'Lost bitcoind connection', traceback.format_exc() if config.START_RPC_SERVER: progress_ui("Launching counterpartyd") db = util.connect_to_db() api_server = api.APIServer() api_server.daemon = True api_server.start() api_server.join(4) # wait 3 seconds, if the thread is dead that means an exception was thrown if api_server.isAlive(): # fork off in another thread t = threading.Thread(target=lambda: blocks.follow(db)) t.daemon = True t.start() else: return "Cannot start the API subsystem. Is counterpartyd already running, or is " \ "something else listening on port %s?" % config.RPC_PORT, '' # splashScreen.bar.setValue(75) # we've now started up the webserver, finally just wait until the db is in a good state client = XCPClient() while True: try: response = client.get_running_info() if response['db_caught_up']: progress_ui("Counterpartyd finished parsing blockchain") break else: current_block = response['last_block']['block_index'] or 0 current_block = int(current_block) progress_ui("Current counterpartyd progress: %d/%s" % (current_block, current_count)) time.sleep(3) except Exception as e: return 'Lost counterpartyd RPC connection', traceback.format_exc() return None
rpcpass = '' #main loop, catch exceptions print '' oldhash = '' txiter=[] txmemory=[] primenumber = '030331ef01000000001976a914' rpcpipe = AuthServiceProxy('http://' + rpcuser + ':' + rpcpass + '@' + rpchost + ':11000') while True: try: #heartbeat comms = rpcpipe.getbestblockhash() if comms not in oldhash: oldhash = comms print oldhash + ' ' + str(rpcpipe.getblockcount()) time.sleep(5) #check for tx incmd = rpcpipe.listtransactions() for tx in incmd: if tx not in txmemory: if 'receive' in str(tx): fields = str(tx).split(',') for field in fields: if 'txid' in field: temptxid = field.split('u')[2].replace('{','').replace('}','').replace('\'','').strip() bypass=False if temptxid not in txiter: txiter.append(temptxid) #in the case this doesnt exist yet try:
rpchost = '127.0.0.1' rpcuser = '******' rpcpass = '******' txnconf = 6 if os.path.isfile('progress.dat'): with open('progress.dat', 'r') as progress: curblock = int(progress.read()) progress.closed else: curblock = 0 rpcpipe = AuthServiceProxy('http://' + rpcuser + ':' + rpcpass + '@' + rpchost + ':44663') while (1 != 2): curblock = curblock + 1 totalblk = rpcpipe.getblockcount() if (curblock > totalblk - txnconf): with open('/root/moonaudit/progress.dat', 'w') as progress: progress.write(str(curblock - 1)) progress.closed exit() rawblockhash = rpcpipe.getblockhash(curblock) rawblockdata = rpcpipe.getblock(rawblockhash) print 'checking block %08d' % (curblock) timestamp = find_between(str(rawblockdata), 'time\': ', ', u\'bits') sendnum = 0 for txhash in rawblockdata['tx']: sendnum = sendnum + 1 txraw = rpcpipe.getrawtransaction(txhash) txdata = rpcpipe.decoderawtransaction(txraw) curvout = -1
# remove 3 datapoints to be extra safe data["lastBlockNum"] -= 300 data["lastBlockHash"] = conn.getblockhash(data["lastBlockNum"]) data["denom_1"] = data["denom_1"][:-3] data["denom_5"] = data["denom_5"][:-3] data["denom_10"] = data["denom_10"][:-3] data["denom_50"] = data["denom_50"][:-3] data["denom_100"] = data["denom_100"][:-3] data["denom_500"] = data["denom_500"][:-3] data["denom_1000"] = data["denom_1000"][:-3] data["denom_5000"] = data["denom_5000"][:-3] data["total"] = data["total"][:-3] data["blocks_axis"] = data["blocks_axis"][:-3] # Add new data points blockCount = conn.getblockcount() while data["lastBlockNum"] + 100 <= blockCount: data["lastBlockNum"] += 100 data["lastBlockHash"] = conn.getblockhash(data["lastBlockNum"]) print("Getting block %d..." % data["lastBlockNum"]) block = conn.getblock(data["lastBlockHash"], True) data["denom_1"].append(int(block["zPIVsupply"]["1"])) data["denom_5"].append(int(block["zPIVsupply"]["5"])) data["denom_10"].append(int(block["zPIVsupply"]["10"])) data["denom_50"].append(int(block["zPIVsupply"]["50"])) data["denom_100"].append(int(block["zPIVsupply"]["100"])) data["denom_500"].append(int(block["zPIVsupply"]["500"])) data["denom_1000"].append(int(block["zPIVsupply"]["1000"])) data["denom_5000"].append(int(block["zPIVsupply"]["5000"])) data["total"].append(int(block["zPIVsupply"]["total"])) data["blocks_axis"].append(data["lastBlockNum"])
class LocalBlockchainRPCReader(BlockExplorerReader): rpc_connection = None #transaction_output_cache = None ''' deprecated ''' def __init__(self, database_connector = None): BlockExplorerReader.__init__(self, database_connector) #super self.rpc_connection = AuthServiceProxy( "http://%s:%s@%s:%s" % (self.config.RPC_USERNAME, self.config.RPC_PASSWORD, self.config.RPC_HOST, self.config.RPC_PORT)) def get_current_blockchain_block_height(self): return self.rpc_connection.getblockcount() #TODO: Error checking? - This should already be an integer. #Retreives a list of transactions at specified block height. Each tx # will be formatted as a BCI-like tuple per # get_bci_like_tuple_for_tx_id(). #param0: block_height: Height at which to get a list of txs for. #param1: use_tx_out_addr_cache_only (Optional): When looking up addresses # for previous transactions, ONLY refer to cache in SQLite database, # rather than slower option of using RPC interface. If set to True, # process will sleep until the data is available in the cache. Default: # False. def get_tx_list(self, block_height, use_tx_out_addr_cache_only = False): ids = self.get_tx_ids_at_height(block_height) txs = [] for tx_id in ids: bci_like_tuple = self.get_bci_like_tuple_for_tx_id( tx_id, use_tx_out_addr_cache_only) txs.append(bci_like_tuple) return txs #Checks if the specified transaction is the first time the specified address # has received funds. If it is, it will cache this for the specified # block height in the database so subsequent lookups will answer # correctly. IMPORTANT: This function assumes that that blocks are being # processed in a complete, monotonically-increasing fashion from the # genesis block. Otherwise, correct results not guaranteed! It is the # caller's responsibility to ensure that enough blocks have been # processed. def is_first_transaction_for_address(self, addr, tx_id, block_height, benchmarker = None): if self.database_connector.has_address_been_seen_cache_if_not(addr, block_height): dprint("Address %s at block height %d was already seen." % (addr, block_height)) return False else: dprint("Address %s at block height %d has no prior tx history." % (addr, block_height)) return True def get_block_hash_at_height(self, block_height): return self.rpc_connection.getblockhash(block_height) def get_tx_json_for_block_hash(self, block_hash): return self.rpc_connection.getblock(block_hash) def get_tx_ids_at_height(self, block_height): block_hash = self.get_block_hash_at_height(block_height) tx_json = self.get_tx_json_for_block_hash(block_hash) tx_ids = [] for tx_id in tx_json['tx']: tx_ids.append(tx_id) return tx_ids #Returns the transaction in raw format. If the requested transaction is # the sole transaction of the genesis block, bitcoind's RPC interface # will throw an error 'No information available about transaction # (code -5)' so we preempt this by raising a custom error that callers # should handle; iterating callers should just move onto the next tx. #throws: NoDataAvailableForGenesisBlockError def get_raw_tx(self, tx_id): if tx_id == ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7af' 'deda33b'): raise custom_errors.NoDataAvailableForGenesisBlockError() else: return self.rpc_connection.getrawtransaction(tx_id) #Gets a human-readable string of the transaction in JSON format. def get_decoded_tx(self, tx_id): try: return self.rpc_connection.decoderawtransaction( self.get_raw_tx(tx_id)) except custom_errors.NoDataAvailableForGenesisBlockError: #bitcoind won't generate this, but here's what it would look like genesis_json = { 'txid': ('4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2' '127b7afdeda33b'), 'version': 1, 'locktime': 0, 'vin': [{ "sequence":4294967295, 'coinbase': ('04ffff001d0104455468652054696d65732030332f4a6' '16e2f32303039204368616e63656c6c6f72206f6e2062' '72696e6b206f66207365636f6e64206261696c6f75742' '0666f722062616e6b73') }], 'vout': [ { 'value': 50.00000000, 'n': 0, 'scriptPubKey': { 'asm': ('04678afdb0fe5548271967f1a67130b7105cd6a828' 'e03909a67962e0ea1f61deb649f6bc3f4cef38c4f3' '5504e51ec112de5c384df7ba0b8d578a4c702b6bf1' '1d5f OP_CHECKSIG'), 'hex': ('4104678afdb0fe5548271967f1a67130b7105cd6a8' '28e03909a67962e0ea1f61deb649f6bc3f4cef38c4' 'f35504e51ec112de5c384df7ba0b8d578a4c702b6b' 'f11d5fac'), 'reqSigs': 1, 'type': 'pubkey', 'addresses': ['1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'] } } ] } return genesis_json #Converts required infromation from local bitcoind RPC into a format similar # to that returned by Blockchain.info's API. This helps to make the code # more agnostic as to the source of blockchain data. #Note: When an output address cannot be decoded, BCI excludes the "addr" # field from the JSON returned. Therefore, this function will do the same. # See: # https://blockchain.info/tx/cee16a9b222f636cd27d734da0a131cee5dd7a1d09cb5f14f4d1330b22aaa38e #Note: When a previous output address for an input cannot be decoded, BCI # excludes the "addr" field from the JSON returned. Therefore, this # function will do the same. See: # https://blockchain.info/tx/8ebe1df6ebf008f7ec42ccd022478c9afaec3ca0444322243b745aa2e317c272 #param0: tx_id: Specified transaction hash #param1: use_tx_out_addr_cache_only (Optional): When looking up addresses # for previous transactions, ONLY refer to cache in SQLite database, # rather than slower option of using RPC interface. If set to True, # process will sleep until the data is available in the cache. Default: # False. def get_bci_like_tuple_for_tx_id(self, tx_id, use_tx_out_addr_cache_only = False): json_tuple = {} json_tuple['hash'] = tx_id json_tuple['inputs'] = [] json_tuple['out'] = [] subscription = None if use_tx_out_addr_cache_only: subscription = data_subscription.TxOutputAddressCacheSubscriber( database = self.database_connector) tx_json = self.get_decoded_tx(tx_id) #populate input addresses for vin in tx_json['vin']: #look up address based on its previous transaction prev_txid = None if 'txid' in vin: prev_txid = vin['txid'] prev_vout = None if 'vout' in vin: prev_vout_num = vin['vout'] #yes, this RPC field is poorly named prev_out = {'n': prev_vout_num} try: if use_tx_out_addr_cache_only: #flag specifies that we will wait for cache to catch up # before continuing this operation. Process/thread # will sleep until then. subscription.next_tx_id_needed = prev_txid subscription.next_prev_tx_ouput_pos_needed = prev_vout_num dprint(("get_bci_like_tuple_for_tx_id: May sleep until " "tx output address is cached...")) subscription.do_sleep_until_producers_ready() address = self.get_output_address(prev_txid, prev_vout_num) prev_out['addr'] = address except custom_errors.PrevOutAddressCannotBeDecodedError: pass current_input = {'prev_out': prev_out} json_tuple['inputs'].append(current_input) else: #If there's no index specifying the txo from prev tx, there's # probably nothing to do here. Should only come up for # coinbase transactions. continue #populate output addresses for vout in tx_json['vout']: output_index = vout['n'] current_output = {'n':output_index} if 'scriptPubKey' in vout and 'addresses' in vout['scriptPubKey']: address = vout['scriptPubKey']['addresses'][0] current_output['addr'] = address json_tuple['out'].append(current_output) return json_tuple #Returns an ordered list of output addresses for the specified transaction # JSON as returned by the bitcoind RPC interface. If an address cannot be # decoded for one of the outputs, a value of None will be inserted # at that position in the list. #TODO: This does not properly handle multisig outputs that list multiple # addresses per output. See: # http://bitcoin.stackexchange.com/questions/4687/can-a-scriptpubkey-have-multiple-addresses # When support for this is added, make sure to add a test case. def get_output_addresses(self, tx_json): assert 'vout' in tx_json output_addresses = [] for vout in tx_json['vout']: assert 'scriptPubKey' in vout if 'addresses' in vout['scriptPubKey']: ouput_address = vout['scriptPubKey']['addresses'][0] output_addresses.append(ouput_address) else: output_addresses.append(None) return output_addresses #Raises: custom_errors.PrevOutAddressCannotBeDecoded #TODO: This does not properly handle multisig outputs that list multiple # addresses per output. def get_output_address(self, tx_id, output_index, tx_json = None): if USE_TX_OUTPUT_ADDR_CACHE_FIRST: addr = self.database_connector.get_output_address(tx_id, output_index) if addr is not None: return addr #not in cache, fall back to querying RPC interface if tx_json is None: tx_json = self.get_decoded_tx(tx_id) if 'vout' in tx_json and len(tx_json['vout']) > output_index and \ 'scriptPubKey' in tx_json['vout'][output_index]: if 'addresses' not in tx_json['vout'][output_index]['scriptPubKey']: raise custom_errors.PrevOutAddressCannotBeDecodedError else: return tx_json['vout'][output_index]['scriptPubKey'][ 'addresses'][0] else: msg = ("Missing element for vout in get_output_address() with tx " "id %s and output index %d") % (tx_id, output_index) logger.log_and_die(msg)
def getblockcount(): bitcoind=AuthServiceProxy("http://%s:%[email protected]:8332" % (config.rpc_user, config.rpc_password), timeout=600) count=bitcoind.getblockcount() return {'result': count}
try: tx = btdc.getrawtransaction(txid, 1) return tx except: return None if __name__ == '__main__': db = MySQLdb.connect(host="localhost", user="******", passwd="j5YWfMw32wsA7ZEMHxzLw95c", db="mbtx") btdc = AuthServiceProxy("http://*****:*****@127.0.0.1:8332") cursor = db.cursor() cursor.execute("select id_trans,wallet_address,txtid from tbl_transaction where type = 2 and status = 0 and UNIX_TIMESTAMP() - create_time > 300") numrows = int(cursor.rowcount) if numrows == 0: sys.exit(0) curr = get_json_bc(None) if curr['height'] == btdc.getblockcount(): use_local_btc = True print "Using Local Daemon" else: use_local_btc = False print "Warning!! the local daemon is out of sync." if curr is None: sys.exit(0) for r in range(0,numrows): row = cursor.fetchone() sql = "" if use_local_btc: data = get_json_local(row[2]) if data is not None and 'confirmations' in data : if data['confirmations'] > 5: sql = 'update tbl_transaction set status = 1 where id_trans = %s' % (row[0])
def main(): logger = logging.getLogger('charts') conf = get_settings() access = AuthServiceProxy("http://{}:{}@127.0.0.1:2240".format( conf['daemon_rpc']['username'], conf['daemon_rpc']['password'])) logger.info("Current block count: ", access.getblockcount()) postgres = psycopg2.connect(database=conf['database']['database_name'], user=conf['database']['username'], port=5432, password=conf['database']['password']) cursor = postgres.cursor() cursor.execute("SELECT data from chart_info where id='diff_chart';") get_data = cursor.fetchall()[0][0] if len(get_data) == 0: # first time running this script chain_start = 1435118400 # JUNE 24 2015 12:00 AM else: # last_data holds the values for the last entry in the data array last_data = get_data[len(get_data) - 1] chain_start = int(last_data[0]) logger.info(chain_start) d_cursor = postgres.cursor(cursor_factory=psycopg2.extras.RealDictCursor) d_cursor.execute( "SELECT size,difficulty,numtx,coinagedestroyed,mint,timestamp,height " "FROM blocks WHERE timestamp >= %s ORDER BY height ASC;", (chain_start, )) get = d_cursor.fetchall() w = 86400 # ONE DAY OF SECONDS # height 401 = 1435995300 timestamp one_day = chain_start + w size_count = 0.0 diff_count = 0.0 blocks_count = 0 numtx_count = 0 cd_count = 0.0 mint_count = 0.0 num_blocks = len(get) size_list = [] diff_list = [] block_list = [] numtx_list = [] cd_list = [] mint_list = [] for x in get: height = x["height"] timestamp = x["timestamp"] size = x["size"] difficulty = float(x["difficulty"]) numtx = x["numtx"] coinagedestroyed = x["coinagedestroyed"] mint = float(x["mint"]) if timestamp <= one_day: # print "working on day worth of blocks" num_blocks += 1 size_count += size diff_count += difficulty blocks_count += 1 numtx_count += numtx cd_count += coinagedestroyed mint_count += mint elif height == 401: logger.info("height is 401") avg_size = size_count // num_blocks avg_diff = diff_count / num_blocks avg_blocks = blocks_count avg_numtx = numtx_count // num_blocks avg_cd = cd_count / num_blocks avg_mint = mint_count / num_blocks logger.info(avg_size, avg_diff, avg_blocks, "avg_numtx->", avg_numtx, avg_cd, avg_mint, num_blocks, height) size_list.append([str(one_day), str(avg_size)]) diff_list.append([str(one_day), str(avg_diff)]) block_list.append([str(one_day), str(avg_blocks)]) numtx_list.append([str(one_day), str(avg_numtx)]) cd_list.append([str(one_day), str(avg_cd)]) mint_list.append([str(one_day), str(avg_mint)]) one_day = 1435982400 + w # JULY 4th timestamp, avg_size = 0.0 avg_diff = 0.0 avg_blocks = 0 avg_numtx = 0 avg_cd = 0.0 avg_mint = 0.0 size_count = 0.0 diff_count = 0.0 blocks_count = 0 numtx_count = 0 cd_count = 0.0 mint_count = 0.0 # print one_day,timestamp elif timestamp > one_day: # print "time for new block" avg_size = size_count // num_blocks avg_diff = diff_count / num_blocks avg_blocks = blocks_count avg_numtx = numtx_count // num_blocks avg_cd = cd_count / num_blocks avg_mint = mint_count / num_blocks logger.info(avg_size, avg_diff, avg_blocks, "avg_numtx->", avg_numtx, avg_cd, avg_mint, num_blocks, height) size_list.append([str(one_day), str(avg_size)]) diff_list.append([str(one_day), str(avg_diff)]) block_list.append([str(one_day), str(avg_blocks)]) numtx_list.append([str(one_day), str(avg_numtx)]) cd_list.append([str(one_day), str(avg_cd)]) mint_list.append([str(one_day), str(avg_mint)]) one_day += 86400 avg_size = 0.0 avg_diff = 0.0 avg_blocks = 0 avg_numtx = 0 avg_cd = 0.0 avg_mint = 0.0 size_count = 0.0 diff_count = 0.0 blocks_count = 0 numtx_count = 0 cd_count = 0.0 mint_count = 0.0 # print one_day,timestamp #print "size_list",size_list #print "diff_list",diff_list #print "block_list",block_list #print "numtx_list",numtx_list #print "cd_list",cd_list #print "mint_list",mint_list # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('size_chart',size_list, )) # postgres.commit() # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('diff_chart',diff_list, )) # postgres.commit() # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('block_chart',block_list, )) # postgres.commit() # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('numtx_chart',numtx_list, )) # postgres.commit() # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('cd_chart',cd_list, )) # postgres.commit() # cursor.execute("INSERT INTO chart_info (id,data) VALUES (%s,%s);",('mint_chart',mint_list, )) # postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( size_list, 'size_chart', )) postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( diff_list, 'diff_chart', )) postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( block_list, 'block_chart', )) postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( numtx_list, 'numtx_chart', )) postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( cd_list, 'cd_chart', )) postgres.commit() cursor.execute("UPDATE chart_info SET data = data || %s WHERE id = %s;", ( mint_list, 'mint_chart', )) postgres.commit()
class DucatuscoreInterface: endpoint = None settings = None def __init__(self): self.settings = NETWORK_SETTINGS['DUC'] self.setup_endpoint() self.rpc = AuthServiceProxy(self.endpoint) self.check_connection() def setup_endpoint(self): self.endpoint = 'http://{user}:{pwd}@{host}:{port}'.format( user=self.settings['user'], pwd=self.settings['password'], host=self.settings['host'], port=self.settings['port']) return def check_connection(self): block = self.rpc.getblockcount() if block and block > 0: return True else: raise Exception('Ducatus node not connected') def transfer(self, address, amount): #try: value = int(amount) / DECIMALS['DUC'] print('try sending {value} DUC to {addr}'.format(value=value, addr=address)) self.rpc.walletpassphrase(self.settings['wallet_password'], 30) res = self.rpc.sendtoaddress(address, value) print(res) return res '''except JSONRPCException as e: err = 'DUCATUS TRANSFER ERROR: transfer for {amount} DUC for {addr} failed' \ .format(amount=amount, addr=address) print(err, flush=True) print(e, flush=True) raise DucatuscoreInterfaceException(err)''' def validate_address(self, address): for attempt in range(10): print('attempt', attempt, flush=True) try: rpc_response = self.rpc.validateaddress(address) except RemoteDisconnected as e: print(e, flush=True) rpc_response = False if not isinstance(rpc_response, bool): print(rpc_response, flush=True) break else: raise Exception('cannot validate address with 10 attempts') return rpc_response['isvalid'] def get_unspent(self, tx_hash, count): return self.rpc.gettxout(tx_hash, count) def get_fee(self): return self.rpc.getinfo()['relayfee'] def get_unspent_input(self, tx_hash, payment_address): last_response = {} count = 0 while isinstance(last_response, dict): rpc_response = self.get_unspent(tx_hash, count) last_response = rpc_response input_addresses = rpc_response['scriptPubKey']['addresses'] if payment_address in input_addresses: return rpc_response, count count += 1 def internal_transfer(self, tx_list, address_from, address_to, amount, private_key): print('start raw tx build', flush=True) print('tx_list', tx_list, 'from', address_from, 'to', address_to, 'amount', amount, flush=True) try: input_params = [] for payment_hash in tx_list: unspent_input, input_vout_count = self.get_unspent_input( payment_hash, address_from) print('unspent input', unspent_input, flush=True) input_params.append({ 'txid': payment_hash, 'vout': input_vout_count }) transaction_fee = self.get_fee() * DECIMALS['DUC'] send_amount = (Decimal(amount) - transaction_fee) / DECIMALS['DUC'] print('input_params', input_params, flush=True) output_params = {address_to: send_amount} print('output_params', output_params, flush=True) tx = self.rpc.createrawtransaction(input_params, output_params) print('raw tx', tx, flush=True) signed = self.rpc.signrawtransaction(tx, None, [private_key]) print('signed tx', signed, flush=True) tx_hash = self.rpc.sendrawtransaction(signed['hex']) print('tx', tx_hash, flush=True) return tx_hash except JSONRPCException as e: print( 'DUCATUS TRANSFER ERROR: transfer for {amount} DUC for {addr} failed' .format(amount=amount, addr=address_to), flush=True) print(e, flush=True) raise DucatuscoreInterfaceException(e)
class QtumBlockchain(BlockchainHandler): def __init__(self, qtum_rpc): self.qtum_rpc = qtum_rpc self.decode_hex = codecs.getdecoder("hex_codec") self.encode_hex = codecs.getencoder("hex_codec") @classmethod def from_http_provider(cls, http_provider): return cls(AuthServiceProxy(http_provider)) def reload_http_provider(self, http_provider): self.qtum_rpc = AuthServiceProxy(http_provider) def get_block_count(self): return self.qtum_rpc.getblockcount() def get_balance(self): return self.qtum_rpc.getbalance() def get_last_block_hash(self): return self.qtum_rpc.getbestblockhash() def get_second_last_block_hash(self): return self.get_block_hash(self.get_block_count() - 1) def get_block_hash(self, height): return self.qtum_rpc.getblockhash(height) def get_block_id(self, height): block_hash = self.get_block_hash(height) l = sha256(self.decode_hex(block_hash)[0]).hexdigest() r = hex(height) return l[0:10] + r[2:].rjust(10, '0') def get_last_block_id(self): last_block_height = self.get_block_count() return self.get_block_id(last_block_height) def get_second_last_block_id(self): last_block_height = self.get_block_count() - 1 return self.get_block_id(last_block_height) def get_accounts(self): unspent = self.qtum_rpc.listunspent() res = [tx['address'] for tx in unspent] return res def get_unspent(self): unspent = self.qtum_rpc.listunspent() res = {tx['address']: tx['amount'] for tx in unspent} return res def from_hex_address(self, address): return self.qtum_rpc.fromhexaddress(address)
if __name__ == '__main__': # your bitcoin daemon on your server running full-node rpc_user = "******" rpc_password = "******" rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332" % (rpc_user, rpc_password), timeout=1200) best_block_hash = rpc_connection.getbestblockhash() blk = rpc_connection.getblock(best_block_hash) # dump current block count height print("getblockcount = %s" % rpc_connection.getblockcount()) txlist = [] alist = [] for txid in blk['tx']: txlist.append(txid) al = addrlistVout(txid) alist.append(al) # make list & remove duplicates in list newlist = [] for i in alist: for j in i: newlist.append(j)
class Bitcoind_Real: """ Connection to a Bitcoin daemon process. """ def __init__(self, settings): """ Arguments: settings: a settings object; must contain the attribute bitcoinRPCURL. Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL. If settings.bitcoinRPCURL is empty, this object will not be connected. """ if settings.bitcoinRPCURL != "": log.log("Making connection to Bitcoin daemon...") self.access = AuthServiceProxy(settings.bitcoinRPCURL) log.log("...done") else: log.log("Bitcoin-RPC URL is not set: not connecting") self.access = None def isConnected(self): """ Return value: bool Returns whether this object is connected. """ return self.access != None def getBalance(self): """ Return value: int, in Satoshi Returns the balance. """ return self.DecimaltoAmount(self.access.getbalance()) def getBlockCount(self): """ Return value: int Returns the block count. """ return self.access.getblockcount() def getNewAddress(self): """ Return value: str, Base58Check-encoded address Generates and returns a new address. """ return self.access.getnewaddress() def getPrivateKey(self, address): """ Arguments: address: str, Base58Check-encoded address Return value: str, Base58Check-encoded private key Returns the private key corresponding to the given address. """ return self.access.dumpprivkey(address) def getBlockInfoByBlockHeight(self, height): """ Arguments: height: int Return value: dict; containing: hash: str; the block hash (hexadecimal) merkleroot: str; the block Merkle root (hexadecimal, Bitcoin hash byte order) time: int; the block timestamp (UNIX time) Returns information about the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) binfo = self.access.getblock(bhash) return {"hash": binfo["hash"], "merkleroot": binfo["merkleroot"], "time": binfo["time"]} def getTransactionHashesByBlockHeight(self, height): """ Arguments: height: int Return value: list of str, hexadecimal, Bitcoin hash byte order Returns the transaction hashes in the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) block = self.access.getblock(bhash) return block["tx"] def getTransaction(self, thash): """ Arguments: thash: str, hexadecimal, Bitcoin hash byte order Return value: dict, containing: vin: list of dict, each element containing: coinbase [only for coinbase transactions] txid [only for non-coinbase transactions]: str, hexadecimal, Bitcoin hash byte order hash of input transaction hex: str, hexadecimal, serialization of the transaction confirmations: int, number of confirmations Returns information about the transaction indicated by the given hash. """ return self.access.getrawtransaction(thash, 1) def importprivkey(self, privateKey, description, rescan): return self.access.importprivkey(privateKey, description, rescan) def listUnspent(self): """ Return value: list of dict, each element containing: address: str, Base58Check-encoded address amount: int, in Satoshi scriptPubKey: str, binary txid: str, binary, OpenSSL byte order vout: int Returns information about the available unspent transaction outputs. """ ret = self.access.listunspent() for vout in ret: vout["txid"] = binascii.unhexlify(vout["txid"])[::-1] # reversed; TODO: is this the right place? vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"]) vout["amount"] = self.DecimaltoAmount(vout["amount"]) return ret def sendRawTransaction(self, txData): """ Arguments: txData: str, binary Send the given serialized transaction over the Bitcoin network. """ try: self.access.sendrawtransaction(txData.encode("hex")) except JSONRPCException as e: if e.error["code"] == RPC_TRANSACTION_ALREADY_IN_CHAIN: # It's perfectly fine (but very unlikely) that the transaction is # already in the block chain. # After all, we WANT it to end up in the block chain! pass else: raise def DecimaltoAmount(self, value): return int(value * 100000000) def handleMessage(self, msg): return [ messages.BitcoinReturnValue(value=msg.function(self), ID=msg.returnID, channelIndex=msg.returnChannelIndex) ]