def pushtx(self, txhex): try: json_str = btc.blockr_pushtx(txhex, self.network) except Exception: log.debug('failed blockr.io pushtx') return None data = json.loads(json_str) if data['status'] != 'success': log.debug(data) return None return data['data']
def pushtx(self, txhex): try: json_str = btc.blockr_pushtx(txhex, self.network) except Exception: common.debug('failed blockr.io pushtx') return None data = json.loads(json_str) if data['status'] != 'success': common.debug(data) return None return data['data']
def pushtx(self, txhex): try: json_str = btc.blockr_pushtx(txhex, self.network) data = json.loads(json_str) if data['status'] != 'success': log.debug(data) return False except Exception: log.debug('failed blockr.io pushtx') log.debug(traceback.format_exc()) return False return True
def change_stage(): global stage, tx, inputs, outputs, confirmed, last_update, stage_time, confirmed if stage == "outputs" and len(outputs) > 0: stage = "inputs" elif stage == "inputs": if len(outputs) == len(inputs) and len(outputs) > 0: tx = mktx(inputs, outputs) print tx stage = "signatures" else: # If a different number of inputs and outputs, on just one of each one, is received, the process is restarted reset_arrays() stage = "outputs" elif stage == "signatures": if len(outputs) == len(inputs) == len(signatures): tx = insert_signatures(tx) print "Final tx: " + tx stage = "confirm" else: # If the three arrays are not of the same size, the process is restarted. reset_arrays() stage = "outputs" elif stage == "confirm": if confirmed: result = blockr_pushtx(tx, 'testnet') #result = local_push(tx) # End of the mixing, starting the process again reset_arrays() confirmed = False stage = "outputs" else: # Wait for the inputs to be confirmed # Check if there are utxo unconfirmed yet if len(unconfirmed) is not 0: for tx in unconfirmed: if get_tx_info(tx)['confirmations'] >= 6: unconfirmed.remove(tx) if len(unconfirmed) is 0: confirmed = True last_update = time() t = threading.Timer(stage_time, change_stage) t.start() print " * Current stage: " + stage
def test_blockr_bad_pushtx(): inps = [("00000000", "btc"), ("00000000", "testnet"), ('\x00' * 8, "testnet"), ('\x00' * 8, "x")] for i in inps: with pytest.raises(Exception) as e_info: btc.blockr_pushtx(i[0], i[1])
def test_blockr_bad_pushtx(): inps = [("00000000", "btc"), ("00000000", "testnet"), ('\x00'*8, "testnet"), ('\x00'*8, "x")] for i in inps: with pytest.raises(Exception) as e_info: btc.blockr_pushtx(i[0],i[1])
def commitTo(self, testnet, commit_address, private_key): """ Commit to some address on the blockchain """ # Check if we have the keys for the BM address public_key = highlevelcrypto.privToPub( private_key.encode('hex')).decode('hex') fromAddress = self.getAddress(testnet, public_key) result = self.getUnspentTransactions(testnet, [fromAddress]) if not 'unspent' in result or len(result['unspent']) == 0: log_debug("commitTo: No unspent TXs (%s)" % (fromAddress)) return False unspent_txs = result['unspent'] # filter for those with an amount >= minimum amount unspent_txs = filter( lambda tx: float(tx['amount']) > BitcoinThread. BTC_UNSPENT_MIN_AVAILABLE, unspent_txs) if len(unspent_txs) == 0: log_debug("commitTo: No unspent TXs >= %d (%s, %s)" % (BitcoinThread.BTC_UNSPENT_MIN_AVAILABLE, fromAddress, result['unspent'])) return False # Find random unspent with an amount >= 0.00010 mBTC random.shuffle(unspent_txs) while len(unspent_txs) > 0: tx = unspent_txs.pop(0) log_debug("Trying unspent tx: %s" % tx) amount = float(tx['amount']) amount_satoshis = int(amount * 100000000) change_satoshis = amount_satoshis - BitcoinThread.SATOSHI_COMMITMENT_AMOUNT - BitcoinThread.SATOSHI_TRANSACTION_FEE # Code in bitcoin.mktx separates the input string into tx=input[:64] and n=input[65:] input_tx = "%s %d" % (tx['tx'], tx['n']) commit_payable = { "address": commit_address, "value": BitcoinThread.SATOSHI_COMMITMENT_AMOUNT } change_payable = {"address": fromAddress, "value": change_satoshis} tx = bitcoin.mktx([input_tx], [commit_payable, change_payable]) signed_tx = bitcoin.sign(tx, 0, private_key) log_debug("Pushing tx: %s" % bitcoin.deserialize(tx)) if testnet: try: result = json.loads( bitcoin.blockr_pushtx(signed_tx, 'testnet')) except Exception, e: # If we get {"status":"fail","data":"Could not push your transaction!","code":500,"message":"Did you sign your transaction?"} # in an exception here, it probably means that the referenced inputs in our transaction have been spent in the meantime. try: e_obj = json.loads(e.message) if e_obj["data"] == "Could not push your transaction!": from debug import logger log_warn( "Couldn't push transaction. Sometimes this is because the referenced inputs have been spent in the meantime, %s" % e_obj) # Continue to try the next unspent tx continue else: log_warn(e) except: log_warn(e) return 'status' in result and result['status'] == "success" else: # if not testnet # I had problems pushing non-testnet transactions to blockr.io, # so we're using blockchain.info for this, and that works fine. try: result = bitcoin.pushtx(signed_tx) if result.lower() == "transaction submitted": log_debug("Committed to %s" % commit_address) return True else: log_warn("Transaction push fail: %s" % (result, )) except Exception, e: log_warn("Transaction push exception: %s" % (e, )) continue
app.logger.warn('Could not find addresses suitable to spend to from {}. Outputs may be too small.'.format(address)) return {'status': 'fail', 'data': { 'message': 'There are no addresses to where the donation can be successfully forwarded. The value of the donation may be too low, try sending a little more.', 'code': 500 }} raw_tx = bitcoin.transaction.mktx(address_unspent, outs) tx = bitcoin.transaction.signall(raw_tx, address_info.private_key) tx_hash = bitcoin.transaction.txhash(tx) try: try: push_result = bitcoin.pushtx(tx) except: push_result = bitcoin.blockr_pushtx(tx) tx_total = sum(out.get('value') for out in outs) # This address has been successfully spent from, update tx info and don't check it again. address_info.spent = True address_info.spending_tx = tx_hash address_info.donation_amount = tx_total # Keep a total of all bitcoins tipped total_donated = DataStore.query.filter_by(key='total_donated').first() if total_donated: total_donated.value = int(int(total_donated.value) + tx_total) else: total_donated = DataStore('total_donated', tx_total) db.session.add(total_donated) db.session.commit()
def commitTo(self, testnet, commit_address, private_key): """ Commit to some address on the blockchain """ # Check if we have the keys for the BM address public_key = highlevelcrypto.privToPub( private_key.encode('hex') ).decode('hex') fromAddress = self.getAddress( testnet, public_key ) result = self.getUnspentTransactions( testnet, [fromAddress] ) if not 'unspent' in result or len( result['unspent'] ) == 0: log_debug( "commitTo: No unspent TXs (%s)" % ( fromAddress ) ) return False unspent_txs = result['unspent'] # filter for those with an amount >= minimum amount unspent_txs = filter( lambda tx: float( tx['amount'] ) > BitcoinThread.BTC_UNSPENT_MIN_AVAILABLE, unspent_txs ) if len( unspent_txs ) == 0: log_debug( "commitTo: No unspent TXs >= %d (%s, %s)" % ( BitcoinThread.BTC_UNSPENT_MIN_AVAILABLE, fromAddress, result['unspent'] ) ) return False # Find random unspent with an amount >= 0.00010 mBTC random.shuffle( unspent_txs ) while len( unspent_txs ) > 0: tx = unspent_txs.pop( 0 ) log_debug( "Trying unspent tx: %s" % tx ) amount = float( tx['amount'] ) amount_satoshis = int( amount * 100000000 ) change_satoshis = amount_satoshis - BitcoinThread.SATOSHI_COMMITMENT_AMOUNT - BitcoinThread.SATOSHI_TRANSACTION_FEE # Code in bitcoin.mktx separates the input string into tx=input[:64] and n=input[65:] input_tx = "%s %d" % ( tx['tx'], tx['n'] ) commit_payable = { "address": commit_address, "value": BitcoinThread.SATOSHI_COMMITMENT_AMOUNT } change_payable = { "address": fromAddress, "value": change_satoshis } tx = bitcoin.mktx( [input_tx], [ commit_payable, change_payable ] ) signed_tx = bitcoin.sign(tx, 0, private_key ) log_debug( "Pushing tx: %s" % bitcoin.deserialize( tx ) ) if testnet: try: result = json.loads( bitcoin.blockr_pushtx(signed_tx, 'testnet') ) except Exception, e: # If we get {"status":"fail","data":"Could not push your transaction!","code":500,"message":"Did you sign your transaction?"} # in an exception here, it probably means that the referenced inputs in our transaction have been spent in the meantime. try: e_obj = json.loads( e.message ) if e_obj["data"] == "Could not push your transaction!": from debug import logger log_warn( "Couldn't push transaction. Sometimes this is because the referenced inputs have been spent in the meantime, %s" % e_obj ) # Continue to try the next unspent tx continue else: log_warn( e ) except: log_warn( e ) return 'status' in result and result['status'] == "success" else: # if not testnet # I had problems pushing non-testnet transactions to blockr.io, # so we're using blockchain.info for this, and that works fine. try: result = bitcoin.pushtx( signed_tx ) if result.lower() == "transaction submitted": log_debug( "Committed to %s" % commit_address ) return True else: log_warn( "Transaction push fail: %s" % ( result, ) ) except Exception, e: log_warn( "Transaction push exception: %s" % ( e, ) ) continue
'data': { 'message': 'There are no addresses to where the donation can be successfully forwarded. The value of the donation may be too low, try sending a little more.', 'code': 500 } } raw_tx = bitcoin.transaction.mktx(address_unspent, outs) tx = bitcoin.transaction.signall(raw_tx, address_info.private_key) tx_hash = bitcoin.transaction.txhash(tx) try: try: push_result = bitcoin.pushtx(tx) except: push_result = bitcoin.blockr_pushtx(tx) tx_total = sum(out.get('value') for out in outs) # This address has been successfully spent from, update tx info and don't check it again. address_info.spent = True address_info.spending_tx = tx_hash address_info.donation_amount = tx_total # Keep a total of all bitcoins tipped total_donated = DataStore.query.filter_by( key='total_donated').first() if total_donated: total_donated.value = int(int(total_donated.value) + tx_total) else: total_donated = DataStore('total_donated', tx_total) db.session.add(total_donated)