Esempio n. 1
0
   def createNewWalletFromWizard(self):
      entropy = None
      if self.walletCreationPage.isManualEncryption():
         entropy = SecureBinaryData(
            int_to_binary(self.manualEntropyPage.pageFrame.getEntropy()))
      else:
         entropy = self.main.getExtraEntropyForKeyGen()
      self.newWallet = PyBtcWallet().createNewWallet(
         securePassphrase=self.setPassphrasePage.pageFrame.getPassphrase(),
         kdfTargSec=self.walletCreationPage.pageFrame.getKdfSec(),
         kdfMaxMem=self.walletCreationPage.pageFrame.getKdfBytes(),
         shortLabel=self.walletCreationPage.pageFrame.getName(),
         longLabel=self.walletCreationPage.pageFrame.getDescription(),
         doRegisterWithBDM=False,
         extraEntropy=entropy,
      )

      self.newWallet.unlock(securePassphrase=
               SecureBinaryData(self.setPassphrasePage.pageFrame.getPassphrase()))
      # We always want to fill the address pool, right away.  
      fillPoolProgress = DlgProgress(self, self.main, HBar=1, \
                                     Title="Creating Wallet") 
      fillPoolProgress.exec_(self.newWallet.fillAddressPool, doRegister=False,
                             Progress=fillPoolProgress.UpdateHBar)

      # Reopening from file helps make sure everything is correct -- don't
      # let the user use a wallet that triggers errors on reading it
      wltpath = self.newWallet.walletPath
      walletFromDisk = PyBtcWallet().readWalletFile(wltpath)
      self.main.addWalletToApplication(walletFromDisk, walletIsNew=True)
Esempio n. 2
0
   def put(self, varType, theData, width=None, endianness=LITTLEENDIAN):
      """
      Need to supply the argument type you are put'ing into the stream.
      Values of BINARY_CHUNK will automatically detect the size as necessary

      Use width=X to include padding of BINARY_CHUNKs w/ 0x00 bytes
      """
      E = endianness
      if   varType == UINT8:
         self.binaryConcat += int_to_binary(theData, 1, endianness)
      elif varType == UINT16:
         self.binaryConcat += int_to_binary(theData, 2, endianness)
      elif varType == UINT32:
         self.binaryConcat += int_to_binary(theData, 4, endianness)
      elif varType == UINT64:
         self.binaryConcat += int_to_binary(theData, 8, endianness)
      elif varType == INT8:
         self.binaryConcat += pack(E+'b', theData)
      elif varType == INT16:
         self.binaryConcat += pack(E+'h', theData)
      elif varType == INT32:
         self.binaryConcat += pack(E+'i', theData)
      elif varType == INT64:
         self.binaryConcat += pack(E+'q', theData)
      elif varType == VAR_INT:
         self.binaryConcat += packVarInt(theData)[0]
      elif varType == VAR_STR:
         self.binaryConcat += packVarInt(len(theData))[0]
         self.binaryConcat += theData
      elif varType == FLOAT:
         self.binaryConcat += pack(E+'f', theData)
      elif varType == BINARY_CHUNK:
         if width==None:
            self.binaryConcat += theData
         else:
            if len(theData)>width:
               raise PackerError, 'Too much data to fit into fixed width field'
            self.binaryConcat += theData.ljust(width, '\x00')
      else:
         raise PackerError, "Var type not recognized!  VarType="+str(varType)
   def testSimpleAddress(self):
      # Execute the tests with Satoshi's public key from the Bitcoin specification page
      satoshiPubKeyHex = '04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284'
      addrPiece1Hex = '65a4358f4691660849d9f235eb05f11fabbd69fa'
      addrPiece1Bin = hex_to_binary(addrPiece1Hex)
      satoshiAddrStr = hash160_to_addrStr(addrPiece1Bin)

      saddr = PyBtcAddress().createFromPublicKey( hex_to_binary(satoshiPubKeyHex) )
      print '\tAddr calc from pubkey: ', saddr.calculateAddrStr()
      self.assertTrue(checkAddrStrValid(satoshiAddrStr))
   
      testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY)
      msg = int_to_binary(39029348428)
      theHash = hash256(msg)
      derSig = testAddr.generateDERSignature(theHash)
      # Testing ECDSA signing & verification -- arbitrary binary strings:
      self.assertTrue(testAddr.verifyDERSignature( theHash, derSig))
    def testSimpleAddress(self):
        # Execute the tests with Satoshi's public key from the Bitcoin specification page
        satoshiPubKeyHex = '04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284'
        addrPiece1Hex = '65a4358f4691660849d9f235eb05f11fabbd69fa'
        addrPiece1Bin = hex_to_binary(addrPiece1Hex)
        satoshiAddrStr = hash160_to_addrStr(addrPiece1Bin)

        saddr = PyBtcAddress().createFromPublicKey(
            hex_to_binary(satoshiPubKeyHex))
        print '\tAddr calc from pubkey: ', saddr.calculateAddrStr()
        self.assertTrue(checkAddrStrValid(satoshiAddrStr))

        testAddr = PyBtcAddress().createFromPlainKeyData(
            PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY)
        msg = int_to_binary(39029348428)
        theHash = hash256(msg)
        derSig = testAddr.generateDERSignature(theHash)
        # Testing ECDSA signing & verification -- arbitrary binary strings:
        self.assertTrue(testAddr.verifyDERSignature(theHash, derSig))
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:

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

      alreadyUsedAddr = set( [utxoToScrAddr(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 utxoToScrAddr(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