Esempio n. 1
0
 def createFromCppUtxo(self, cppUtxo):
    self.scrAddr = cppUtxo.getRecipientScrAddr()
    self.val  = cppUtxo.getValue()
    self.conf = cppUtxo.getNumConfirm()
    # For now, this will throw errors unless we always use hash160 scraddrs
    self.binScript = '\x76\xa9\x14' + CheckHash160(self.scrAddr) + '\x88\xac'
    self.txHash     = cppUtxo.getTxHash()
    self.txOutIndex = cppUtxo.getTxOutIndex()
    return self
Esempio n. 2
0
def pprintUnspentTxOutList(utxoList, headerLine='Coin Selection: '):
   totalSum = sum([u.getValue() for u in utxoList])
   print headerLine, '(Total = %s BTC)' % coin2str(totalSum)
   print '   ','Owner Address'.ljust(34),
   print '   ','TxOutValue'.rjust(18),
   print '   ','NumConf'.rjust(8),
   print '   ','PriorityFactor'.rjust(16)
   for utxo in utxoList:
      a160 = CheckHash160(utxo.getRecipientScrAddr())
      print '   ',hash160_to_addrStr(a160).ljust(34),
      print '   ',(coin2str(utxo.getValue()) + ' BTC').rjust(18),
      print '   ',str(utxo.getNumConfirm()).rjust(8),
      print '   ', ('%0.2f' % (utxo.getValue()*utxo.getNumConfirm()/(ONE_BTC*144.))).rjust(16)
Esempio n. 3
0
 def getRecipientHash160(self):
     return CheckHash160(self.scrAddr)
Esempio n. 4
0
        def sendDust():
            try:
                utxiList = []
                for utxo in self.dustTableModel.dustTxOutlist:
                    # The PyCreateAndSignTx method require PyTx and PyBtcAddress objects
                    rawTx = TheBDM.getTxByHash(utxo.getTxHash()).serialize()
                    a160 = CheckHash160(utxo.getRecipientScrAddr())
                    for pyAddr in self.dustTableModel.wlt.addrMap.values():
                        if a160 == pyAddr.getAddr160():
                            pubKey = pyAddr.binPublicKey65.toBinStr()
                            txoIdx = utxo.getTxOutIndex()
                            utxiList.append(
                                UnsignedTxInput(rawTx, txoIdx, None, pubKey))
                            break
                # Make copies, destroy them in the finally clause
                privKeyMap = {}
                for addrObj in self.dustTableModel.wlt.addrMap.values():
                    scrAddr = SCRADDR_P2PKH_BYTE + addrObj.getAddr160()
                    if self.dustTableModel.wlt.useEncryption and self.dustTableModel.wlt.isLocked:
                        # Target wallet is encrypted...
                        unlockdlg = DlgUnlockWallet(self.dustTableModel.wlt,
                                                    self.main, self.main,
                                                    'Unlock Wallet to Import')
                        if not unlockdlg.exec_():
                            QMessageBox.critical(self, 'Wallet is Locked', \
                               'Cannot send dust without unlocking the wallet!', \
                               QMessageBox.Ok)
                            return
                    privKeyMap[scrAddr] = addrObj.binPrivKey32_Plain.copy()
                signedTx = PyCreateAndSignTx(
                    utxiList, [], privKeyMap,
                    SIGHASH_NONE | SIGHASH_ANYONECANPAY)

                print "-------------"
                print binary_to_hex(signedTx.serialize())

                # sock = socket.create_connection(('dust-b-gone.bitcoin.petertodd.org',80))
                # sock.send(signedTx.serialize())
                # sock.send(b'\n')
                # sock.close()

            except socket.error as err:
                QMessageBox.critical(
                    self.main, tr('Negative Value'),
                    tr("""
               Failed to connect to dust-b-gone server: %s""" % err.strerror),
                    QMessageBox.Ok)
            except NegativeValueError:
                QMessageBox.critical(
                    self.main, tr('Negative Value'),
                    tr("""
               You must enter a positive value of at least 0.0000 0001 
               and less than %s for the dust limit.""" % MAX_DUST_LIMIT_STR),
                    QMessageBox.Ok)
            except TooMuchPrecisionError:
                QMessageBox.critical(
                    self.main.main, tr('Too much precision'),
                    tr("""
               Bitcoins can only be specified down to 8 decimal places. 
               The smallest unit of a Bitcoin is 0.0000 0001 BTC. 
               Please enter a dust limit of at least 0.0000 0001 and less than %s."""
                       % MAX_DUST_LIMIT_STR), QMessageBox.Ok)
            finally:
                for scraddr in privKeyMap:
                    privKeyMap[scraddr].destroy()
Esempio n. 5
0
def PySelectCoins(unspentTxOutInfo, targetOutVal, minFee=0, numRand=10, margin=CENT):
   """
   Intense algorithm for coin selection:  computes about 30 different ways to
   select coins based on the desired target output and the min tx fee.  Then
   ranks the various solutions and picks the best one
   """

   if sum([u.getValue() for u in unspentTxOutInfo]) < targetOutVal:
      return []

   targExact  = targetOutVal
   targMargin = targetOutVal+margin

   selectLists = []

   # Start with the intelligent solutions with different sortings
   for sortMethod in range(8):
      diffSortList = PySortCoins(unspentTxOutInfo, sortMethod)
      selectLists.append(PySelectCoins_SingleInput_SingleValue( diffSortList, targExact,  minFee ))
      selectLists.append(PySelectCoins_MultiInput_SingleValue(  diffSortList, targExact,  minFee ))
      selectLists.append(PySelectCoins_SingleInput_SingleValue( diffSortList, targMargin, minFee ))
      selectLists.append(PySelectCoins_MultiInput_SingleValue(  diffSortList, targMargin, minFee ))
      selectLists.append(PySelectCoins_SingleInput_DoubleValue( diffSortList, targExact,  minFee ))
      selectLists.append(PySelectCoins_MultiInput_DoubleValue(  diffSortList, targExact,  minFee ))
      selectLists.append(PySelectCoins_SingleInput_DoubleValue( diffSortList, targMargin, minFee ))
      selectLists.append(PySelectCoins_MultiInput_DoubleValue(  diffSortList, targMargin, minFee ))

   # Throw in a couple random solutions, maybe we get lucky
   # But first, make a copy before in-place shuffling
   # NOTE:  using list[:] like below, really causes a swig::vector<type> to freak out!
   #utxos = unspentTxOutInfo[:]
   #utxos = list(unspentTxOutInfo)
   for method in range(8,10):
      for i in range(numRand):
         utxos = PySortCoins(unspentTxOutInfo, method)
         selectLists.append(PySelectCoins_MultiInput_SingleValue(utxos, targExact,  minFee))
         selectLists.append(PySelectCoins_MultiInput_DoubleValue(utxos, targExact,  minFee))
         selectLists.append(PySelectCoins_MultiInput_SingleValue(utxos, targMargin, minFee))
         selectLists.append(PySelectCoins_MultiInput_DoubleValue(utxos, targMargin, minFee))

   # Now we define PyEvalCoinSelect as our sorting metric, and find the best solution
   scoreFunc = lambda ulist: PyEvalCoinSelect(ulist, targetOutVal, minFee)
   finalSelection = max(selectLists, key=scoreFunc)
   SCORES = getSelectCoinsScores(finalSelection, targetOutVal, minFee)
   if len(finalSelection)==0:
      return []

   # If we selected a list that has only one or two inputs, and we have
   # other, tiny, unspent outputs from the same addresses, we should
   # throw one or two of them in to help clear them out.  However, we
   # only do so if a plethora of conditions exist:
   #
   # First, we only consider doing this if the tx has <5 inputs already.
   # Also, we skip this process if the current tx doesn't have excessive
   # priority already -- we don't want to risk de-prioritizing a tx for
   # this purpose.
   #
   # Next we sort by LOWEST value, because we really benefit from this most
   # by clearing out tiny outputs.  Along those lines, we don't even do
   # unless it has low priority -- don't want to take a high-priority utxo
   # and convert it to one that will be low-priority to start.
   #
   # Finally, we shouldn't do this if a high score was assigned to output
   # anonymity: this extra output may cause a tx with good output anonymity
   # to no longer possess this property
   IDEAL_NUM_INPUTS = 5
   if len(finalSelection) < IDEAL_NUM_INPUTS and \
          SCORES[IDX_OUTANONYM] == 0:

      utxoToHash160 = lambda a: CheckHash160(a.getRecipientScrAddr())
      getPriority   = lambda a: a.getValue() * a.getNumConfirm()
      getUtxoID     = lambda a: a.getTxHash() + int_to_binary(a.getTxOutIndex())

      alreadyUsedAddr = set( [utxoToHash160(utxo) for utxo in finalSelection] )
      utxoSmallToLarge = sorted(unspentTxOutInfo, key=getPriority)
      utxoSmToLgIDs = [getUtxoID(utxo) for utxo in utxoSmallToLarge]
      finalSelectIDs = [getUtxoID(utxo) for utxo in finalSelection]
      
      for other in utxoSmallToLarge:
         
         # Skip it if it is already selected
         if getUtxoID(other) in finalSelectIDs:
            continue

         # We only consider UTXOs that won't link any new addresses together
         if not utxoToHash160(other) in alreadyUsedAddr:
            continue
         
         # Avoid zero-conf inputs altogether
         if other.getNumConfirm() == 0:
            continue

         # Don't consider any inputs that are high priority already
         if getPriority(other) > ONE_BTC*144:
            continue

         finalSelection.append(other) 
         if len(finalSelection)>=IDEAL_NUM_INPUTS:
            break
   return finalSelection