def sweep_btc_account(self, SENDER_ADDRESS='', email=''): addrs = [] addrs.append(SENDER_ADDRESS) transactions = [] transactions_with_key = [] sum = 0.0 utxo = rpc.listunspent(minconf=6, addrs=addrs) # Return if there are no transactions if len(utxo) == 0: return for txo in utxo: sum += float(txo['amount']) / COIN transaction = {} transaction['txid'] = b2lx(txo['outpoint'].hash) transaction['vout'] = txo['outpoint'].n transactions.append(transaction) transaction['scriptPubKey'] = hexlify(txo['scriptPubKey']) transactions_with_key.append(transaction) # Need to calculate transaction fee transaction_fee = 0.0001 addresses = {} addresses[EXCHANGE_BITCOIN_ADDRESS] = sum - transaction_fee # Pickup the private key from the database, hardcoded for now PRIVATE_KEY = manager_c.get('bitcoin_keypairs', SENDER_ADDRESS)['priv_key'] private_keys = [] private_keys.append(PRIVATE_KEY) try: raw_tx = rpc.createrawtransaction(transactions, addresses) signed_transaction = rpc.signrawtransaction( raw_tx, transactions_with_key, private_keys) except: raise return if not signed_transaction['complete'] or not signed_transaction: raise 'Transaction signing unsuccessful' return else: txid = rpc.sendrawtransaction(signed_transaction['tx']) print 'Sent %s from %s to %s' % ( addresses[EXCHANGE_BITCOIN_ADDRESS], SENDER_ADDRESS, PRIVATE_KEY) lxtxid = b2lx(txid) print lxtxid # Update the the users space in hyperdex, add 'sum' bitcoin to the # user's balance keyed on email-id. x = webserver_c.begin_transaction() #x.put('users', email, {'Bitcoin': x.get('users', email)['Bitcoin'] + addresses[EXCHANGE_BITCOIN_ADDRESS]}) x.atomic_add('users', email, {'Bitcoin': addresses[EXCHANGE_BITCOIN_ADDRESS]}) x.commit()
def sweep_btc_account(self, SENDER_ADDRESS='', email=''): addrs = [] addrs.append(SENDER_ADDRESS) transactions = [] transactions_with_key = [] sum = 0.0 utxo = rpc.listunspent(minconf=6, addrs=addrs) # Return if there are no transactions if len(utxo) == 0: return for txo in utxo: sum += float(txo['amount'])/COIN transaction = {} transaction['txid'] = b2lx(txo['outpoint'].hash) transaction['vout'] = txo['outpoint'].n transactions.append(transaction) transaction['scriptPubKey'] = hexlify(txo['scriptPubKey']) transactions_with_key.append(transaction) # Need to calculate transaction fee transaction_fee = 0.0001 addresses = {} addresses[EXCHANGE_BITCOIN_ADDRESS] = sum - transaction_fee # Pickup the private key from the database, hardcoded for now PRIVATE_KEY = manager_c.get('bitcoin_keypairs', SENDER_ADDRESS)['priv_key'] private_keys = [] private_keys.append(PRIVATE_KEY) try: raw_tx = rpc.createrawtransaction( transactions, addresses) signed_transaction = rpc.signrawtransaction( raw_tx, transactions_with_key, private_keys) except: raise return if not signed_transaction['complete'] or not signed_transaction: raise 'Transaction signing unsuccessful' return else: txid = rpc.sendrawtransaction(signed_transaction['tx']) print 'Sent %s from %s to %s' % (addresses[EXCHANGE_BITCOIN_ADDRESS], SENDER_ADDRESS, PRIVATE_KEY) lxtxid = b2lx(txid) print lxtxid # Update the the users space in hyperdex, add 'sum' bitcoin to the # user's balance keyed on email-id. x = webserver_c.begin_transaction() #x.put('users', email, {'Bitcoin': x.get('users', email)['Bitcoin'] + addresses[EXCHANGE_BITCOIN_ADDRESS]}) x.atomic_add('users', email, {'Bitcoin': addresses[EXCHANGE_BITCOIN_ADDRESS]}) x.commit()
if args.multisig: multisig_txout = CTxOut(args.dust, CScript([1, x('0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71'), b'\x00'*33, 2, OP_CHECKMULTISIG])) tx.vout.append(multisig_txout) for bad_addr in args.bad_addr: bad_addr = CBitcoinAddress(bad_addr) txout = CTxOut(args.dust, bad_addr.to_scriptPubKey()) tx.vout.append(txout) # Add inputs until we meet the fee1 threshold unspent = sorted(rpc.listunspent(1), key=lambda x: x['amount']) value_in = 0 value_out = sum([vout.nValue for vout in tx.vout]) while (value_in - value_out) / len(tx.serialize()) < feeperbyte1: # What's the delta fee that we need to get to our desired fees per byte at # the current tx size? delta_fee = math.ceil((feeperbyte1 * len(tx.serialize())) - (value_in - value_out)) logging.debug('Delta fee: %s' % str_money_value(delta_fee)) # If we simply subtract that from the change outpoint are we still above # the dust threshold? if change_txout.nValue - delta_fee > args.dust: change_txout.nValue -= delta_fee value_out -= delta_fee
value_out = sum([vout.nValue for vout in tx.vout]) # Units: satoshi's per byte old_fees_per_byte = (value_in - value_out) / len(tx.serialize()) desired_fees_per_byte = old_fees_per_byte * args.ratio # Old transaction might have had no fees at all, in which case use the minimum of 0.1mBTC/KB desired_fees_per_byte = max(desired_fees_per_byte, 0.0001 * COIN / 1000) logging.debug('Old size: %.3f KB, Old fees: %s, %s BTC/KB, Desired fees: %s BTC/KB' % \ (len(tx.serialize()) / 1000, str_money_value(value_in-value_out), str_money_value(old_fees_per_byte * 1000), str_money_value(desired_fees_per_byte * 1000))) unspent = sorted(rpc.listunspent(1), key=lambda x: x['amount']) # Modify the transaction by either reducing the amount of change out, or adding # new inputs, until it meets the fees-per-byte that we want. while (value_in - value_out) / len(tx.serialize()) < desired_fees_per_byte: # What's the delta fee that we need to get to our desired fees per byte at # the current tx size? delta_fee = math.ceil((desired_fees_per_byte * len(tx.serialize())) - (value_in - value_out)) # Ensure termination; the loop converges so it can get stuck at no fee. if delta_fee < 1: break logging.debug('Delta fee: %s' % str_money_value(delta_fee))
# Create the unsigned transaction. tx = CMutableTransaction([txin], [txout1, txout2]) # Calculate the signature hash for that transaction. sighash = SignatureHash(txin_scriptPubKey, tx, 0, SIGHASH_ALL) # Now sign it. We have to append the type of signature we want to the end, in # this case the usual SIGHASH_ALL. sig = seckey.sign(sighash) + bytes([SIGHASH_ALL]) # Set the scriptSig of our transaction input appropriately. txin.scriptSig = CScript([sig, seckey.pub]) # Verify the signature worked. This calls EvalScript() and actually executes # the opcodes in the scripts to see if everything worked out. If it doesn't an # exception will be raised. VerifyScript(txin.scriptSig, txin_scriptPubKey, tx, 0, (SCRIPT_VERIFY_P2SH,)) rpc = bitcoin.rpc.Proxy() # from json import dumps print(rpc.listunspent(1)) # Done! Print the transaction to standard output with the bytes-to-hex # function. # print(b2x(tx.serialize())) # rpc = bitcoin.rpc.Proxy() # # r = rpc.signrawtransaction(tx) # # assert(r['complete']) # # tx = CMutableTransaction.from_tx(r['tx']) # txid = rpc.sendrawtransaction(tx)
if args.prev_txid is not None: try: args.prev_txid = lx(args.prev_txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.prev_txid) != 32: parser.error('Invalid txid: Wrong length.') tx1 = rpc.getrawtransaction(args.prev_txid) elif not args.no_reuse: # Try to find an unconfirmed transaction with full-RBF enabled and a change # output > amount txids_seen = set() for unspent in rpc.listunspent(0,0): txid = unspent['outpoint'].hash if txid not in txids_seen: unspent_tx = rpc.getrawtransaction(txid) # FIXME: this still fails if amount doesn't leave enough for fees if unspent_tx.vout[0].nValue < args.amount: continue if check_full_rbf_optin(unspent_tx): tx1 = unspent_tx logging.info('Found unconfirmed full-RBF tx1 %s' % b2lx(txid)) break else: txids_seen.add(txid)
if args.prev_txid is not None: try: args.prev_txid = lx(args.prev_txid) except ValueError as err: parser.error('Invalid txid: %s' % str(err)) if len(args.prev_txid) != 32: parser.error('Invalid txid: Wrong length.') tx1 = rpc.getrawtransaction(args.prev_txid) elif not args.no_reuse: # Try to find an unconfirmed transaction with full-RBF enabled and a change # output > amount txids_seen = set() for unspent in rpc.listunspent(0, 0): txid = unspent['outpoint'].hash if txid not in txids_seen: unspent_tx = rpc.getrawtransaction(txid) # FIXME: this still fails if amount doesn't leave enough for fees if unspent_tx.vout[0].nValue < args.amount: continue if check_full_rbf_optin(unspent_tx): tx1 = unspent_tx logging.info('Found unconfirmed full-RBF tx1 %s' % b2lx(txid)) break else: txids_seen.add(txid)