<s> from settings_local import ( <EOL> BITCOIND_TEST_MODE , <EOL> BITCOIND_RPC_USERNAME , <EOL> BITCOIND_RPC_PASSWORD , <EOL> BITCOIND_RPC_PORT , <EOL> BITCOIND_RPC_HOST , <EOL> BITCOIND_TEST_RPC_USERNAME , <EOL> BITCOIND_TEST_RPC_PASSWORD , <EOL> BITCOIND_TEST_RPC_HOST , <EOL> BITCOIND_TEST_RPC_PORT , <EOL> ORACLE_ADDRESS , <EOL> ORGANIZATION_ADDRESS , <EOL> ORACLE_FEE , <EOL> ORGANIZATION_FEE <EOL> ) <EOL> from shared . liburl_wrapper import safe_blockchain_multiaddress , safe_nonbitcoind_blockchain_getblock , safe_get_raw_transaction <EOL> import json <EOL> import jsonrpclib <EOL> from bitcoinrpc . authproxy import AuthServiceProxy <EOL> import time <EOL> from xmlrpclib import ProtocolError <EOL> from decimal import Decimal <EOL> import socket <EOL> import logging <EOL> logging . getLogger ( "<STR_LIT>" ) . setLevel ( logging . CRITICAL ) <EOL> TEST_MODE = BITCOIND_TEST_MODE <EOL> class UnknownServerError ( Exception ) : <EOL> pass <EOL> def slice_list ( list , chunk ) : <EOL> return [ list [ i * chunk : ( i + <NUM_LIT:1> ) * chunk ] for i in range ( <NUM_LIT:0> , int ( ( len ( list ) + chunk ) / chunk ) ) ] <EOL> class BitcoinClient : <EOL> def __init__ ( self , account = None ) : <EOL> self . account = account <EOL> self . connect ( ) <EOL> self . blockchain_connect ( ) <EOL> def _connect ( self , connection_function ) : <EOL> try_factor = <NUM_LIT:1> <EOL> while <NUM_LIT:1> : <EOL> try : <EOL> connection_function ( ) <EOL> return <EOL> except : <EOL> try_factor *= <NUM_LIT:2> <EOL> if try_factor > <NUM_LIT> : <EOL> logging . critical ( '<STR_LIT>' ) <EOL> return <EOL> logging . info ( '<STR_LIT>' . format ( try_factor ) ) <EOL> time . sleep ( try_factor ) <EOL> def connect ( self ) : <EOL> def server_connection ( ) : <EOL> self . server = jsonrpclib . Server ( '<STR_LIT>' . format ( <EOL> BITCOIND_RPC_USERNAME , <EOL> BITCOIND_RPC_PASSWORD , <EOL> BITCOIND_RPC_HOST , <EOL> BITCOIND_RPC_PORT ) ) <EOL> socket . setdefaulttimeout ( None ) <EOL> self . server . help ( ) <EOL> self . _connect ( server_connection ) <EOL> def blockchain_connect ( self ) : <EOL> """<STR_LIT>""" <EOL> def server_connection ( ) : <EOL> if TEST_MODE : <EOL> self . blockchain_server = jsonrpclib . Server ( '<STR_LIT>' . format ( <EOL> BITCOIND_TEST_RPC_USERNAME , <EOL> BITCOIND_TEST_RPC_PASSWORD , <EOL> BITCOIND_TEST_RPC_HOST , <EOL> BITCOIND_TEST_RPC_PORT ) ) <EOL> else : <EOL> self . blockchain_server = jsonrpclib . Server ( '<STR_LIT>' . format ( <EOL> BITCOIND_RPC_USERNAME , <EOL> BITCOIND_RPC_PASSWORD , <EOL> BITCOIND_RPC_HOST , <EOL> BITCOIND_RPC_PORT ) ) <EOL> socket . setdefaulttimeout ( None ) <EOL> self . server . help ( ) <EOL> self . _connect ( server_connection ) <EOL> def keep_alive ( server ) : <EOL> def wrapper ( fun ) : <EOL> def ping_and_reconnect ( self , * args , ** kwargs ) : <EOL> if server == '<STR_LIT>' : <EOL> server_instance = self . server <EOL> connection_function = self . connect <EOL> elif server == '<STR_LIT>' : <EOL> return fun ( self , * args , ** kwargs ) <EOL> else : <EOL> raise UnknownServerError ( ) <EOL> try : <EOL> server_instance . help ( ) <EOL> response = fun ( self , * args , ** kwargs ) <EOL> return response <EOL> except : <EOL> connection_function ( ) <EOL> return fun ( self , * args , ** kwargs ) <EOL> return ping_and_reconnect <EOL> return wrapper <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def decode_raw_transaction ( self , hex_transaction ) : <EOL> return self . server . decoderawtransaction ( hex_transaction ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_json_transaction ( self , hex_transaction ) : <EOL> return self . server . decoderawtransaction ( hex_transaction ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def sign_transaction ( self , raw_transaction , prevtx = [ ] , priv_keys = None ) : <EOL> if priv_keys : <EOL> result = self . server . signrawtransaction ( raw_transaction , prevtx , priv_keys ) <EOL> else : <EOL> result = self . server . signrawtransaction ( raw_transaction , prevtx ) <EOL> return result [ '<STR_LIT>' ] <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_txid ( self , raw_transaction ) : <EOL> transaction_dict = self . server . decoderawtransaction ( raw_transaction ) <EOL> return transaction_dict [ '<STR_LIT>' ] <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def signatures_count ( self , raw_transaction , prevtx ) : <EOL> transaction_dict = self . server . decoderawtransaction ( raw_transaction ) <EOL> prevtx_dict = { } <EOL> for tx in prevtx : <EOL> prevtx_dict [ "<STR_LIT>" . format ( tx [ '<STR_LIT>' ] , tx [ '<STR_LIT>' ] ) ] = tx [ '<STR_LIT>' ] <EOL> has_signatures = <NUM_LIT> <EOL> for vin in transaction_dict [ '<STR_LIT>' ] : <EOL> redeem_script = prevtx_dict [ "<STR_LIT>" . format ( tx [ '<STR_LIT>' ] , tx [ '<STR_LIT>' ] ) ] <EOL> try : <EOL> asm = vin [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> logging . error ( '<STR_LIT>' ) <EOL> continue <EOL> asm_elements = asm . split ( ) <EOL> try : <EOL> asm_script_dict = self . server . decodescript ( redeem_script ) <EOL> int ( asm_script_dict [ '<STR_LIT>' ] ) <EOL> except KeyError : <EOL> logging . error ( '<STR_LIT>' ) <EOL> continue <EOL> asm_signatures = asm_elements [ <NUM_LIT:1> : - <NUM_LIT:1> ] <EOL> current_signatures = <NUM_LIT:0> <EOL> for a in asm_signatures : <EOL> if a != '<STR_LIT:0>' : <EOL> current_signatures += <NUM_LIT:1> <EOL> has_signatures = min ( has_signatures , current_signatures ) <EOL> return has_signatures <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def signatures ( self , raw_transaction , prevtx ) : <EOL> transaction_dict = self . server . decoderawtransaction ( raw_transaction ) <EOL> prevtx_dict = { } <EOL> for tx in prevtx : <EOL> prevtx_dict [ str ( ( tx [ '<STR_LIT>' ] , tx [ '<STR_LIT>' ] ) ) ] = tx [ '<STR_LIT>' ] <EOL> has_signatures = <NUM_LIT> <EOL> for vin in transaction_dict [ '<STR_LIT>' ] : <EOL> redeem_script = prevtx_dict [ str ( ( vin [ '<STR_LIT>' ] , vin [ '<STR_LIT>' ] ) ) ] <EOL> try : <EOL> asm = vin [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> logging . error ( '<STR_LIT>' ) <EOL> continue <EOL> asm_elements = asm . split ( ) <EOL> try : <EOL> asm_script_dict = self . server . decodescript ( redeem_script ) <EOL> int ( asm_script_dict [ '<STR_LIT>' ] ) <EOL> except KeyError : <EOL> logging . error ( '<STR_LIT>' ) <EOL> continue <EOL> return asm_elements <EOL> current_signatures = len ( asm_elements ) - <NUM_LIT:2> <EOL> current_signatures = max ( current_signatures , <NUM_LIT:0> ) <EOL> has_signatures = min ( has_signatures , current_signatures ) <EOL> return has_signatures <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def is_valid_transaction ( self , raw_transaction ) : <EOL> try : <EOL> self . server . decoderawtransaction ( raw_transaction ) <EOL> except ProtocolError : <EOL> logging . exception ( '<STR_LIT>' ) <EOL> return False <EOL> return True <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def address_is_mine ( self , address ) : <EOL> result = self . server . validateaddress ( address ) <EOL> return result [ '<STR_LIT>' ] <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def decode_script ( self , script ) : <EOL> return self . server . decodescript ( script ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_inputs_outputs ( self , raw_transaction ) : <EOL> transaction_dict = self . server . decoderawtransaction ( raw_transaction ) <EOL> vin = transaction_dict [ "<STR_LIT>" ] <EOL> vouts = transaction_dict [ "<STR_LIT>" ] <EOL> result = ( <EOL> sorted ( [ json . dumps ( { '<STR_LIT>' : tx_input [ '<STR_LIT>' ] , '<STR_LIT>' : tx_input [ '<STR_LIT>' ] } ) for tx_input in vin ] ) , <EOL> json . dumps ( <EOL> { <EOL> '<STR_LIT>' : sorted ( [ <EOL> { <EOL> "<STR_LIT:value>" : vout [ "<STR_LIT:value>" ] , <EOL> "<STR_LIT>" : vout [ "<STR_LIT>" ] [ "<STR_LIT>" ] <EOL> } for vout in vouts <EOL> ] ) <EOL> } <EOL> ) <EOL> ) <EOL> return result <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def transaction_already_signed ( self , raw_transaction , prevtx ) : <EOL> signed_transaction = self . sign_transaction ( raw_transaction , prevtx ) <EOL> if signed_transaction == raw_transaction : <EOL> return True <EOL> return False <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def transaction_need_signature ( self , raw_transaction ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . server . sendrawtransaction ( raw_transaction ) <EOL> return False <EOL> except ProtocolError : <EOL> return True <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def transaction_contains_output ( self , raw_transaction , address , fee ) : <EOL> transaction_dict = self . server . decoderawtransaction ( raw_transaction ) <EOL> if not '<STR_LIT>' in transaction_dict : <EOL> return False <EOL> for vout in transaction_dict [ '<STR_LIT>' ] : <EOL> if not '<STR_LIT:value>' in vout : <EOL> continue <EOL> if not '<STR_LIT>' in vout : <EOL> continue <EOL> if not '<STR_LIT>' in vout [ '<STR_LIT>' ] : <EOL> continue <EOL> for address in vout [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> if address == address : <EOL> value = Decimal ( vout [ '<STR_LIT:value>' ] ) <EOL> if value >= Decimal ( fee ) : <EOL> return True <EOL> return False <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def transaction_contains_oracle_fee ( self , raw_transaction ) : <EOL> return self . transaction_contains_output ( raw_transaction , ORACLE_ADDRESS , ORACLE_FEE ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def transaction_contains_org_fee ( self , raw_transaction ) : <EOL> return self . transaction_contains_output ( raw_transaction , ORGANIZATION_ADDRESS , ORGANIZATION_FEE ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def create_multisig_address ( self , min_sigs , keys ) : <EOL> keys = sorted ( keys ) <EOL> return self . server . createmultisig ( min_sigs , keys ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def add_multisig_address ( self , min_sigs , keys ) : <EOL> keys = sorted ( keys ) <EOL> if self . account : <EOL> return self . server . addmultisigaddress ( min_sigs , keys , self . account ) <EOL> return self . server . addmultisigaddress ( min_sigs , keys ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def create_raw_transaction ( self , tx_inputs , outputs ) : <EOL> return self . server . createrawtransaction ( tx_inputs , outputs ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_new_address ( self ) : <EOL> if self . account : <EOL> return self . server . getnewaddress ( self . account ) <EOL> return self . server . getnewaddress ( ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_addresses_for_account ( self , account ) : <EOL> all_addresses = self . server . listreceivedbyaddress ( <NUM_LIT:0> , True ) <EOL> addresses = [ elt [ '<STR_LIT:address>' ] for elt in all_addresses if elt [ '<STR_LIT>' ] == account ] <EOL> return addresses <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def validate_address ( self , address ) : <EOL> return self . server . validateaddress ( address ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_block_hash ( self , block_number ) : <EOL> try : <EOL> return self . blockchain_server . getblockhash ( block_number ) <EOL> except : <EOL> return None <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def bitcoind_get_block ( self , block_hash ) : <EOL> return self . blockchain_server . getblock ( block_hash ) <EOL> def get_block ( self , block_hash ) : <EOL> if not TEST_MODE : <EOL> return self . bitcoind_get_block ( block_hash ) <EOL> else : <EOL> not_proper_data = safe_nonbitcoind_blockchain_getblock ( block_hash ) <EOL> max_height = self . blockchain_server . getblockcount ( ) <EOL> proper_data = { } <EOL> try : <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> except : <EOL> logging . exception ( '<STR_LIT>' % not_proper_data ) <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT:size>' ] = not_proper_data [ '<STR_LIT:size>' ] <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT>' ] = max_height - proper_data [ '<STR_LIT>' ] + <NUM_LIT:1> <EOL> proper_data [ '<STR_LIT:version>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT:time>' ] = not_proper_data [ '<STR_LIT:time>' ] <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT>' ] = not_proper_data [ '<STR_LIT>' ] <EOL> proper_data [ '<STR_LIT>' ] = [ tx [ '<STR_LIT>' ] for tx in not_proper_data [ '<STR_LIT>' ] ] <EOL> return proper_data <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def get_block_count ( self ) : <EOL> return self . blockchain_server . getblockcount ( ) <EOL> @ keep_alive ( '<STR_LIT>' ) <EOL> def send_transaction ( self , tx ) : <EOL> try : <EOL> if not TEST_MODE : <EOL> self . blockchain_server . sendrawtransaction ( tx ) <EOL> return True <EOL> except ProtocolError : <EOL> return False <EOL> def get_raw_transaction ( self , txid ) : <EOL> if not TEST_MODE : <EOL> return self . server . getrawtransaction ( txid ) <EOL> else : <EOL> return safe_get_raw_transaction ( txid ) <EOL> def get_transactions_from_block ( self , block , addresses ) : <EOL> if not TEST_MODE : <EOL> return self . bitcoind_get_transactions_from_block ( block , addresses ) <EOL> else : <EOL> return self . blockchain_get_transactions_from_block ( block , addresses ) <EOL> def blockchain_get_transactions_from_block ( self , block , addresses ) : <EOL> transactions_per_address = { } <EOL> for addr in addresses : <EOL> transactions_per_address [ addr ] = [ ] <EOL> transaction_ids = block [ '<STR_LIT>' ] <EOL> address_chunks = slice_list ( addresses , <NUM_LIT:5> ) <EOL> transactions_on_addresses = [ ] <EOL> for chunk in address_chunks : <EOL> if len ( chunk ) == <NUM_LIT:0> : <EOL> continue <EOL> data = safe_blockchain_multiaddress ( chunk ) <EOL> if data : <EOL> txs = data [ '<STR_LIT>' ] <EOL> for tx in txs : <EOL> if tx [ '<STR_LIT>' ] in transaction_ids : <EOL> transactions_on_addresses . append ( tx [ '<STR_LIT>' ] ) <EOL> logging . info ( transactions_on_addresses ) <EOL> for tx in transactions_on_addresses : <EOL> try : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> raw_transaction = self . get_raw_transaction ( tx ) <EOL> except ProtocolError : <EOL> continue <EOL> transaction = self . decode_raw_transaction ( raw_transaction ) <EOL> for vout in transaction [ '<STR_LIT>' ] : <EOL> if not '<STR_LIT>' in vout [ '<STR_LIT>' ] : <EOL> continue <EOL> addresses_in_vout = set ( vout [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> for addr in addresses : <EOL> if addr in addresses_in_vout : <EOL> transactions_per_address [ addr ] . append ( transaction ) <EOL> logging . info ( transactions_per_address ) <EOL> return transactions_per_address <EOL> def bitcoind_get_transactions_from_block ( self , block , addresses ) : <EOL> logging . info ( addresses ) <EOL> transaction_ids = block [ '<STR_LIT>' ] <EOL> transactions_per_address = { } <EOL> for addr in addresses : <EOL> transactions_per_address [ addr ] = [ ] <EOL> for tx in transaction_ids : <EOL> try : <EOL> raw_transaction = self . get_raw_transaction ( tx ) <EOL> except ProtocolError : <EOL> continue <EOL> transaction = self . decode_raw_transaction ( raw_transaction ) <EOL> for vout in transaction [ '<STR_LIT>' ] : <EOL> if not '<STR_LIT>' in vout [ '<STR_LIT>' ] : <EOL> continue <EOL> addresses_in_vout = set ( vout [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> for addr in addresses : <EOL> if addr in addresses_in_vout : <EOL> transactions_per_address [ addr ] . append ( transaction ) <EOL> logging . info ( transactions_per_address ) <EOL> return transactions_per_address </s>
