예제 #1
0
    def testSendtoaddress(self):
        # Send 1 BTC
        serializedUnsignedTx = \
           self.jsonServer.jsonrpc_createustxtoaddress(TIAB_WLT_3_ADDR_3, \
                                                       BTC_TO_SEND)
        unsignedTx = UnsignedTransaction().unserializeAscii(
            serializedUnsignedTx)
        # Should have 2 txouts to TIAB_WLT_3_ADDR_3 and the change
        self.assertEqual(len(unsignedTx.decorTxOuts), 2)
        foundTxOut = False
        for txout in unsignedTx.decorTxOuts:
            if script_to_addrStr(txout.binScript) == TIAB_WLT_3_ADDR_3:
                self.assertEqual(txout.value, JSONtoAmount(BTC_TO_SEND))
                foundTxOut = True
        self.assertTrue(foundTxOut)

        # Test two paths through signing method and make sure they are equal
        # Wallets in the TIAB start out unencrypted
        f = open(TX_FILENAME, 'w')
        f.write(serializedUnsignedTx)
        f.close()
        serializedSignedTxUnencrypted = \
              self.jsonServer.jsonrpc_signasciitransaction(TX_FILENAME)
        self.jsonServer.jsonrpc_encryptwallet(PASSPHRASE1)
        self.jsonServer.jsonrpc_walletpassphrase(PASSPHRASE1)
        serializedSignedTxEncrypted = \
              self.jsonServer.jsonrpc_signasciitransaction(TX_FILENAME)
        # Other tests expect wallet to be unencrypted
        self.wltA.unlock(securePassphrase=SecureBinaryData(PASSPHRASE1),
                         tempKeyLifetime=1000000)
        self.wltA.changeWalletEncryption()
        signedTxUnencrypted = UnsignedTransaction().unserializeAscii(
            serializedSignedTxUnencrypted)
        signedTxEncrypted = UnsignedTransaction().unserializeAscii(
            serializedSignedTxEncrypted)
        # check number of outputs 1 Btc goes to a single output and the other goes to change
        self.assertEqual(len(signedTxUnencrypted.decorTxOuts), 2)
        self.assertEqual(len(signedTxEncrypted.decorTxOuts), 2)
        self.assertEqual(signedTxUnencrypted.asciiID,
                         signedTxEncrypted.asciiID)
        self.assertTrue(
            JSONtoAmount(BTC_TO_SEND) in [
                signedTxEncrypted.decorTxOuts[0].value,
                signedTxEncrypted.decorTxOuts[1].value
            ])
        self.assertTrue(
            JSONtoAmount(BTC_TO_SEND) in [
                signedTxUnencrypted.decorTxOuts[0].value,
                signedTxUnencrypted.decorTxOuts[1].value
            ])
        f = open(TX_FILENAME, 'w')
        f.write(signedTxEncrypted.serializeAscii())
        f.close()
        txHexToBroadcast = self.jsonServer.jsonrpc_gethextxtobroadcast(
            TX_FILENAME)
        finalPyTx = PyTx().unserialize(hex_to_binary(txHexToBroadcast))
        self.assertEqual(len(finalPyTx.outputs), 2)
        self.assertTrue(
            JSONtoAmount(BTC_TO_SEND) in
            [finalPyTx.outputs[0].value, finalPyTx.outputs[1].value])
예제 #2
0
def sweepImportedAddrs(masterWallet):
   setupTheBDM()
   recipValuePairs = []
   utxoList = []
   for importedAddr in masterWallet.getLinearAddrList():
      if importedAddr.chainIndex<0:
         addr160 = importedAddr.getAddr160()
         utxoList.extend(masterWallet.getAddrTxOutList(addr160))

   # get total value   
   totalAvailable = sum([u.getValue() for u in utxoList])
   fee = calcMinSuggestedFees(utxoList, totalAvailable, MIN_RELAY_TX_FEE, 1)[1]
   totalSpend = totalAvailable - fee
   if totalSpend<0:
      print '***ERROR: The fees are greater than the funds being swept!'
      raise NegativeValueError
   recipValuePairs.append((masterWallet.getNextUnusedAddress().getAddr160(), totalSpend ))

   # ACR:  To support P2SH in general, had to change createFromTxOutSelection
   #       to take full scripts, not just hash160 values.  Convert the list
   #       before passing it in
   scrPairs = [[hash160_to_p2pkhash_script(r), v] for r,v in recipValuePairs]
   ustx = UnsignedTransaction().createFromTxOutSelection(utxoList, scrPairs)
   
   masterWallet.unlock(securePassphrase = SecureBinaryData(getpass('Enter your secret string:')))
   # Sign and prepare the final transaction for broadcast
   masterWallet.signTxDistProposal(ustx)
   pytx = ustx.getPyTxSignedIfPossible()

   print '\nSigned transaction to be broadcast using Armory "offline transactions"...'
   print ustx.serializeAscii()
   return pytx
예제 #3
0
    def __init__(self, main, pytxOrUstx, setSignerFunc):
        self.main = main
        self.setSignerFunc = setSignerFunc

        self.ustx = pytxOrUstx
        if pytxOrUstx != None and isinstance(pytxOrUstx, PyTx):
            self.ustx = UnsignedTransaction()
            self.ustx.createFromPyTx(pytxOrUstx)

        self.frmSigner = QFrame()
        self.frmSigner.setFrameStyle(STYLE_RAISED)
        frmSignerLayout = QGridLayout()

        signerLabel = QLabel(self.main.tr('Signer: '))
        signerLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.typeLabel = QLabelButton("")
        self.typeLabel.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        self.originalType = SIGNER_DEFAULT
        if self.ustx != None:
            self.originalType = self.ustx.signerType

        self.setType(self.originalType)
        setSignerFunc(self.originalType)

        self.main.connect(self.typeLabel, SIGNAL('clicked()'), self.changeType)

        frmSignerLayout.addWidget(signerLabel, 0, 0, 1, 1)
        frmSignerLayout.addWidget(self.typeLabel, 0, 1, 1, 2)
        self.frmSigner.setLayout(frmSignerLayout)
예제 #4
0
def distributeBtc(masterWallet, amount, sendingAddrList):
   pytx = None
   setupTheBDM()
   try:
      recipValuePairs = []
      utxoList = []
      for sendingAddr in sendingAddrList:
         addr160 = sendingAddr.getAddr160()
         # Make sure the sending addresses are in the masterWallet
         if not masterWallet.hasAddr(addr160):
            raise WalletAddressError, 'Address is not in wallet! [%s]' % sendingAddr.getAddrStr()
         utxoList.extend(masterWallet.getAddrTxOutList(addr160))
   

      for importedAddr in masterWallet.getLinearAddrList():
         if importedAddr.chainIndex<0:
            recipValuePairs.append((importedAddr.getAddr160(),amount))
      totalSpend = len(recipValuePairs)*amount
      fee = calcMinSuggestedFees(utxoList, totalSpend, MIN_RELAY_TX_FEE, len(recipValuePairs))[1]
      # Get the necessary utxo list
      selectedUtxoList = PySelectCoins(utxoList, totalSpend, fee)
      # get total value   
      totalAvailable = sum([u.getValue() for u in selectedUtxoList])
      totalChange = totalAvailable - (totalSpend + fee)

      # Make sure there are funds to cover the transaction.
      if totalChange < 0:
         print '***ERROR: you are trying to spend more than your balance!'
         raise NegativeValueError
      recipValuePairs.append((masterWallet.getNextUnusedAddress().getAddr160(), totalChange ))

      # ACR:  To support P2SH in general, had to change createFromTxOutSelection
      #       to take full scripts, not just hash160 values.  Convert the list
      #       before passing it in
      scrPairs = [[hash160_to_p2pkhash_script(r), v] for r,v in recipValuePairs]
            # we're providing a key map for the inputs.
      pubKeyMap = {}
      for utxo in selectedUtxoList:
         scrType = getTxOutScriptType(utxo.getScript())
         if scrType in CPP_TXOUT_STDSINGLESIG:
            scrAddr = utxo.getRecipientScrAddr()
            a160 = scrAddr_to_hash160(scrAddr)[1]
            addrObj = masterWallet.getAddrByHash160(a160)
            if addrObj:
               pubKeyMap[scrAddr] = addrObj.binPublicKey65.toBinStr()

      ustx = UnsignedTransaction().createFromTxOutSelection(selectedUtxoList, scrPairs, pubKeyMap)
      
      masterWallet.unlock(securePassphrase = SecureBinaryData(getpass('Enter your secret string:')))
      # Sign and prepare the final transaction for broadcast
      masterWallet.signUnsignedTx(ustx)
      pytx = ustx.getPyTxSignedIfPossible()
   
      print '\nSigned transaction to be broadcast using Armory "offline transactions"...'
      print ustx.serializeAscii()
   finally:
      TheBDM.beginCleanShutdown()
   return pytx
예제 #5
0
    def testUnsignedTx(self):
        ustxi = UnsignedTxInput(tx1raw, 1, None, self.pubKey)
        a160_1 = addrStr_to_hash160('mhyjJTq9RsDfhNdjTkga1CKhTiL5VFw85J')[1]
        a160_2 = addrStr_to_hash160('mgoCqfR25kZVApAGFK3Tx5CTNcCppmKwfb')[1]
        dtxo1 = DecoratedTxOut(hash160_to_p2pkhash_script(a160_1),
                               long(1.00 * ONE_BTC))
        dtxo2 = DecoratedTxOut(hash160_to_p2pkhash_script(a160_2),
                               long(0.49 * ONE_BTC))

        ustx = UnsignedTransaction().createFromUnsignedTxIO([ustxi],
                                                            [dtxo1, dtxo2])

        self.assertEqual(len(ustx.ustxInputs), 1)
        self.assertEqual(len(ustx.decorTxOuts), 2)
        self.assertEqual(ustx.lockTime, 0)
        self.assertEqual(ustx.uniqueIDB58, 'J2mRenD7')

        serUstx = ustx.serialize()
        ustx2 = UnsignedTransaction().unserialize(serUstx)
        self.assertEqual(serUstx, ustx2.serialize())

        serUstxASCII = ustx.serializeAscii()
        ustx2 = UnsignedTransaction().unserializeAscii(serUstxASCII)
        self.assertEqual(serUstx, ustx2.serialize())
예제 #6
0
 def testSendmany(self):
     # Send 1 BTC
     serializedUnsignedTx = \
        self.jsonServer.jsonrpc_createustxformany(None, ','.join([TIAB_WLT_3_ADDR_2, str(BTC_TO_SEND)]), \
                                                  ','.join([TIAB_WLT_3_ADDR_3, str(BTC_TO_SEND)]))
     unsignedTx = UnsignedTransaction().unserializeAscii(
         serializedUnsignedTx)
     # Should have 2 txouts to TIAB_WLT_3_ADDR_3 and the change
     self.assertEqual(len(unsignedTx.decorTxOuts), 3)
     txOutsFound = 0
     for txout in unsignedTx.decorTxOuts:
         if script_to_addrStr(
                 txout.binScript) in [TIAB_WLT_3_ADDR_2, TIAB_WLT_3_ADDR_3]:
             self.assertEqual(txout.value, JSONtoAmount(BTC_TO_SEND))
             txOutsFound += 1
     self.assertEqual(txOutsFound, 2)
예제 #7
0
def distributeBtc(masterWallet, amount, sendingAddrList):
   pytx = None
   setupTheBDM()
   try:
      recipValuePairs = []
      utxoList = []
      for sendingAddr in sendingAddrList:
         addr160 = sendingAddr.getAddr160()
         # Make sure the sending addresses are in the masterWallet
         if not masterWallet.hasAddr(addr160):
            raise WalletAddressError, 'Address is not in wallet! [%s]' % sendingAddr.getAddrStr()
         utxoList.extend(masterWallet.getAddrTxOutList(addr160))
   

      for importedAddr in masterWallet.getLinearAddrList():
         if importedAddr.chainIndex<0:
            recipValuePairs.append((importedAddr.getAddr160(),amount))
      totalSpend = len(recipValuePairs)*amount
      fee = calcMinSuggestedFees(utxoList, totalSpend, MIN_RELAY_TX_FEE, len(recipValuePairs))[1]
      # Get the necessary utxo list
      selectedUtxoList = PySelectCoins(utxoList, totalSpend, fee)
      # get total value   
      totalAvailable = sum([u.getValue() for u in selectedUtxoList])
      totalChange = totalAvailable - (totalSpend + fee)

      # Make sure there are funds to cover the transaction.
      if totalChange < 0:
         print '***ERROR: you are trying to spend more than your balance!'
         raise NegativeValueError
      recipValuePairs.append((masterWallet.getNextUnusedAddress().getAddr160(), totalChange ))

      # ACR:  To support P2SH in general, had to change createFromTxOutSelection
      #       to take full scripts, not just hash160 values.  Convert the list
      #       before passing it in
      scrPairs = [[hash160_to_p2pkhash_script(r), v] for r,v in recipValuePairs]
      txdp = UnsignedTransaction().createFromTxOutSelection(selectedUtxoList, scrPairs)
      
      masterWallet.unlock(securePassphrase = SecureBinaryData(getpass('Enter your secret string:')))
      # Sign and prepare the final transaction for broadcast
      masterWallet.signTxDistProposal(txdp)
      pytx = txdp.getPyTxSignedIfPossible()
   
      print '\nSigned transaction to be broadcast using Armory "offline transactions"...'
      print txdp.serializeAscii()
   finally:
      TheBDM.execCleanShutdown()
   return pytx
예제 #8
0
    def testAddSigToUSTX(self):
        ustxi = UnsignedTxInput(tx1raw, 1, None, self.pubKey)
        a160_1 = addrStr_to_hash160('mhyjJTq9RsDfhNdjTkga1CKhTiL5VFw85J')[1]
        a160_2 = addrStr_to_hash160('mgoCqfR25kZVApAGFK3Tx5CTNcCppmKwfb')[1]
        dtxo1 = DecoratedTxOut(hash160_to_p2pkhash_script(a160_1),
                               long(1.00 * ONE_BTC))
        dtxo2 = DecoratedTxOut(hash160_to_p2pkhash_script(a160_2),
                               long(0.49 * ONE_BTC))

        ustx = UnsignedTransaction().createFromUnsignedTxIO([ustxi],
                                                            [dtxo1, dtxo2])

        msIndex = ustx.insertSignatureForInput(0, self.sigStr, self.pubKey)
        self.assertEqual(msIndex, 0)

        msIndex = ustx.insertSignatureForInput(0, self.sigStr)
        self.assertEqual(msIndex, 0)

        badSig = self.sigStr[:16] + '\x00' * 8 + self.sigStr[24:]
        msIndex = ustx.insertSignatureForInput(0, badSig)
        self.assertEqual(msIndex, -1)
예제 #9
0
    def testCreateMultisigTests(self):
        '''
      This is used solely to generate some multi-sig scripts, using known
      public/private keys, that we can then use to test signing, etc.  This
      test doesn't actually test anything, but could be tweaked and then 
      reenabled to produce new data for new tests
      '''

        import textwrap
        asc_nosig = textwrap.dedent("""
         =====TXSIGCOLLECT-5JxmLy4T======================================================
         AQAAAAsRCQcAAAAAAf19AQEAAAALEQkH/XsoFKgwJMVZsviXpv+aOun4BQHRm+Cuvs/X7O/J3n8BAAAA
         /QMBAQAAAAGcgxlJ0d+ZHi+MzG+laL4qTx/jVH/lPbbKmrGLA1oc8AAAAACMSTBGAiEArOklwdcihg72
         fMu+GvnKF+AdFiMmeT7CWV4KMZmA3kcCIQDyjBMqkI6tFVXMG/yhbBhVg7TNYsAGLjM5UWLfVx57WgFB
         BLmTMVBhjWo901GrcZzZMNBUectdX4ZsVyHhMNjZpaAJxlpQqnjiK9PAvrNqOIgMq8itz9S3KDaOs/Kh
         W6/lJNL/////AsAOFgIAAAAAGXapFInbjSGPxqYLm35NTXhzcAkVf8h8iKwwq98DAAAAABl2qRSBj0Gs
         NlhCyvZkoRO2iRw54544foisAAAAAAAA/////wFBBJ6i78WXHp6ywhTupFpF7A0V2jwQEjE9pWO1+7wZ
         qS+IM59Dur1Ut5OC+yUycjeFHQdqemkBDFT97zMCJalmtXwAAALiAQAAAAsRCQfJUkEEagSrmNnkd0rY
         BuMC3d62O+oWtctfIj7ndHjoYbtYPrM2tvvLYLWz1PFVGsReX/xJNkZufZj2x8Dsc2U590aRpkEEaGgH
         N8dtq7gByyIE9X2+TkV55PcQzWfcG0InWSyB6bXPArWsnotMn0m+UlEFa2ptAR5MN/a20X7ea1X6ojUZ
         4kEEuVwknYT0F+PjlaEnQlQotUBnHMFYgeuCjBe3IqU/xZniHKXlbJDzQJiNOTOsx2vrgy/WTKsHjd88
         5zKSMDHRqFOuoH+IAgAAAAAAAAROT05FADIBAAAACxEJBxl2qRRs7kd5CHIvdApqfOmMDp1dyrD6Mois
         gARXAQAAAAAAAAROT05FAA==
         ================================================================================
         """.strip())

        asc_sig = textwrap.dedent("""
         =====TXSIGCOLLECT-5JxmLy4T======================================================
         AQAAAAsRCQcAAAAAAf3EAQEAAAALEQkH/XsoFKgwJMVZsviXpv+aOun4BQHRm+Cuvs/X7O/J3n8BAAAA
         /QMBAQAAAAGcgxlJ0d+ZHi+MzG+laL4qTx/jVH/lPbbKmrGLA1oc8AAAAACMSTBGAiEArOklwdcihg72
         fMu+GvnKF+AdFiMmeT7CWV4KMZmA3kcCIQDyjBMqkI6tFVXMG/yhbBhVg7TNYsAGLjM5UWLfVx57WgFB
         BLmTMVBhjWo901GrcZzZMNBUectdX4ZsVyHhMNjZpaAJxlpQqnjiK9PAvrNqOIgMq8itz9S3KDaOs/Kh
         W6/lJNL/////AsAOFgIAAAAAGXapFInbjSGPxqYLm35NTXhzcAkVf8h8iKwwq98DAAAAABl2qRSBj0Gs
         NlhCyvZkoRO2iRw54544foisAAAAAAAA/////wFBBJ6i78WXHp6ywhTupFpF7A0V2jwQEjE9pWO1+7wZ
         qS+IM59Dur1Ut5OC+yUycjeFHQdqemkBDFT97zMCJalmtXxHMEQCIF12j4Vj1Shf49BkDWwVzf1kRgYr
         4EIPObgRTVPQz2KkAiAQ28gOniv2A5ozeBCk/rpWHTw2DqqkraEUDYLAPr83NQEAAuIBAAAACxEJB8lS
         QQRqBKuY2eR3StgG4wLd3rY76ha1y18iPud0eOhhu1g+sza2+8tgtbPU8VUaxF5f/Ek2Rm59mPbHwOxz
         ZTn3RpGmQQRoaAc3x22ruAHLIgT1fb5ORXnk9xDNZ9wbQidZLIHptc8Ctayei0yfSb5SUQVram0BHkw3
         9rbRft5rVfqiNRniQQS5XCSdhPQX4+OVoSdCVCi1QGccwViB64KMF7cipT/FmeIcpeVskPNAmI05M6zH
         a+uDL9ZMqweN3zznMpIwMdGoU66gf4gCAAAAAAAABE5PTkUAMgEAAAALEQkHGXapFGzuR3kIci90Cmp8
         6YwOnV3KsPoyiKyABFcBAAAAAAAABE5PTkUA
         ================================================================================
         """.strip())

        # For this manual construction to work, I had to save the signed funding
        # transaction
        signedFundMS = hex_to_binary( \
           '0100000001fd7b2814a83024c559b2f897a6ff9a3ae9f80501d19be0aebecfd7'
           'ecefc9de7f010000008a47304402205d768f8563d5285fe3d0640d6c15cdfd64'
           '46062be0420f39b8114d53d0cf62a4022010dbc80e9e2bf6039a337810a4feba'
           '561d3c360eaaa4ada1140d82c03ebf37350141049ea2efc5971e9eb2c214eea4'
           '5a45ec0d15da3c1012313da563b5fbbc19a92f88339f43babd54b79382fb2532'
           '7237851d076a7a69010c54fdef330225a966b57cffffffff02a07f8802000000'
           '00c95241046a04ab98d9e4774ad806e302dddeb63bea16b5cb5f223ee77478e8'
           '61bb583eb336b6fbcb60b5b3d4f1551ac45e5ffc4936466e7d98f6c7c0ec7365'
           '39f74691a6410468680737c76dabb801cb2204f57dbe4e4579e4f710cd67dc1b'
           '4227592c81e9b5cf02b5ac9e8b4c9f49be5251056b6a6d011e4c37f6b6d17ede'
           '6b55faa23519e24104b95c249d84f417e3e395a127425428b540671cc15881eb'
           '828c17b722a53fc599e21ca5e56c90f340988d3933acc76beb832fd64cab078d'
           'df3ce732923031d1a853ae80045701000000001976a9146cee477908722f740a'
           '6a7ce98c0e9d5dcab0fa3288ac00000000')

        #UnsignedTransaction().unserializeAscii(asc_nosig).evaluateSigningStatus().pprint()
        #UnsignedTransaction().unserializeAscii(asc_sig).evaluateSigningStatus().pprint()

        privKeys = [SecureBinaryData(a * 32) for a in ['\xaa', '\xbb', '\xcc']]
        pubKeys = [CryptoECDSA().ComputePublicKey(prv) for prv in privKeys]
        pubStrs = [pubk.toBinStr() for pubk in pubKeys]

        for i, prv in enumerate(privKeys):
            print 'PrivKey %d:', prv.toHexStr()

        msScript = pubkeylist_to_multisig_script(pubStrs, 2)
        msScriptReverse = pubkeylist_to_multisig_script(pubStrs[::-1], 2)
        self.assertEqual(msScript, msScriptReverse)

        for opStr in convertScriptToOpStrings(msScript):
            print '   ', opStr

        dtxo = DecoratedTxOut(msScript, 1.0 * ONE_BTC)

        ustxi = UnsignedTxInput(signedFundMS, 0)
        ustxi.pprint()

        refund1 = addrStr_to_scrAddr('mqSvihZRtKt1J3EBbwBJSHeAYVjdxUnpvf')
        refund2 = addrStr_to_scrAddr('mjAauu6jzmYaE7jrfFgKqLxtvpStmPxcb7')
        dtxo1 = DecoratedTxOut(scrAddr_to_script(refund1),
                               long(0.223 * ONE_BTC))
        dtxo2 = DecoratedTxOut(scrAddr_to_script(refund2),
                               long(0.200 * ONE_BTC))

        ustx = UnsignedTransaction().createFromUnsignedTxIO([ustxi],
                                                            [dtxo1, dtxo2])
        ustx.pprint()
        ustx.evaluateSigningStatus().pprint()

        # Need a candidate tx to test signing
        txObj = ustx.pytxObj

        # Test signing on the individual USTXI
        NOSIG = TXIN_SIGSTAT.NO_SIGNATURE
        SIG = TXIN_SIGSTAT.ALREADY_SIGNED
        for i in [0, 1]:
            for j in [0, 1]:
                for k in [0, 1]:
                    ustxiCopy = UnsignedTxInput().unserialize(
                        ustxi.serialize())
                    if i > 0:
                        ustxiCopy.createAndInsertSignature(txObj, privKeys[0])
                    if j > 0:
                        ustxiCopy.createAndInsertSignature(txObj, privKeys[1])
                    if k > 0:
                        ustxiCopy.createAndInsertSignature(txObj, privKeys[2])
                    sstat = ustxiCopy.evaluateSigningStatus()
                    sstat.pprint()
                    self.assertEqual(sstat.allSigned, (i + j + k) > 1)
                    self.assertEqual(sstat.statusM[0],
                                     NOSIG if i + j + k == 0 else SIG)
                    self.assertEqual(sstat.statusM[1],
                                     NOSIG if i + j + k < 2 else SIG)

        # Now try all this on the full USTX (not just the input
        for i in [0, 1]:
            for j in [0, 1]:
                for k in [0, 1]:
                    ustxCopy = UnsignedTransaction().unserialize(
                        ustx.serialize())
                    if i > 0:
                        ustxCopy.createAndInsertSignatureForInput(
                            0, privKeys[0])
                    if j > 0:
                        ustxCopy.createAndInsertSignatureForInput(
                            0, privKeys[1])
                    if k > 0:
                        ustxCopy.createAndInsertSignatureForInput(
                            0, privKeys[2])
                    sstat = ustxCopy.evaluateSigningStatus()
                    #sstat.pprint()
                    self.assertEqual(sstat.canBroadcast, (i + j + k) > 1)
                    #self.assertEqual(sstat.statusM[0], NOSIG if i+j+k==0 else SIG)
                    #self.assertEqual(sstat.statusM[1], NOSIG if i+j+k<2  else SIG)

        # Now actually sign it and dump out a raw signed tx!
        ustx.createAndInsertSignatureForInput(0, privKeys[0])
        ustx.createAndInsertSignatureForInput(0, privKeys[2])

        print ustx.serializeAscii()
        print binary_to_hex(ustx.getPyTxSignedIfPossible().serialize())