def createNewWalletFromWizard(self): 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=self.main.getExtraEntropyForKeyGen()) 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) if TheBDM.getBDMState() in ('Uninitialized', 'Offline'): TheBDM.registerWallet(walletFromDisk, isFresh=True, wait=False) else: self.main.newWalletList.append([walletFromDisk, True])
def setUp(self): self.fileA = os.path.join(ARMORY_HOME_DIR, 'armory_%s_.wallet' % TEST_WALLET_ID) self.fileB = os.path.join(ARMORY_HOME_DIR, 'armory_%s_backup.wallet' % TEST_WALLET_ID) self.fileAupd = os.path.join( ARMORY_HOME_DIR, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID) self.fileBupd = os.path.join( ARMORY_HOME_DIR, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID) self.removeFileList( [self.fileA, self.fileB, self.fileAupd, self.fileBupd]) # We need a controlled test, so we script the all the normally-random stuff self.privKey = SecureBinaryData('\xaa' * 32) self.privKey2 = SecureBinaryData('\x33' * 32) self.chainstr = SecureBinaryData('\xee' * 32) theIV = SecureBinaryData(hex_to_binary('77' * 16)) self.passphrase = SecureBinaryData('A self.passphrase') self.passphrase2 = SecureBinaryData('A new self.passphrase') self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \ plainRootKey=self.privKey, \ chaincode=self.chainstr, \ IV=theIV, \ shortLabel=TEST_WALLET_NAME, \ longLabel=TEST_WALLET_DESCRIPTION) self.jsonServer = Armory_Json_Rpc_Server(self.wallet) TheBDM.registerWallet(self.wallet)
def stopBitcoind(self): LOGINFO('Called stopBitcoind') if self.bitcoind == False: self.bitcoind = None return try: if not self.isRunningBitcoind(): LOGINFO('...but bitcoind is not running, to be able to stop') return from armoryengine.BDM import TheBDM cookie = TheBDM.getCookie() TheBDM.bdv().shutdownNode(cookie) #poll the pid until it's gone, for as long as 2 minutes total = 0 while self.bitcoind.poll() == None: time.sleep(0.1) total += 1 if total > 1200: LOGERROR( "bitcoind failed to shutdown in less than 2 minutes." " Terminating.") return self.bitcoind = None except Exception as e: LOGERROR(e) return
def createNewWalletFromWizard(self): 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=self.main.getExtraEntropyForKeyGen()) self.newWallet.unlock(securePassphrase=SecureBinaryData( self.setPassphrasePage.pageFrame.getPassphrase())) # We always want to fill the address pool, right away. fillpool = lambda: self.newWallet.fillAddressPool(doRegister=False) DlgExecLongProcess(fillpool, 'Creating Wallet...', self, self).exec_() # 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) if TheBDM.getBDMState() in ('Uninitialized', 'Offline'): TheBDM.registerWallet(walletFromDisk, isFresh=True, wait=False) else: self.main.newWalletList.append([walletFromDisk, True])
def stopBitcoind(self): LOGINFO('Called stopBitcoind') if self.bitcoind == False: self.bitcoind = None return try: if not self.isRunningBitcoind(): LOGINFO('...but bitcoind is not running, to be able to stop') return from armoryengine.BDM import TheBDM cookie = TheBDM.getCookie() TheBDM.bdv().shutdownNode(cookie); #poll the pid until it's gone, for as long as 2 minutes total = 0 while self.bitcoind.poll()==None: time.sleep(0.1) total += 1 if total > 1200: LOGERROR("bitcoind failed to shutdown in less than 2 minutes." " Terminating.") return self.bitcoind = None except Exception as e: LOGERROR(e) return
def setUp(self): self.verifyBlockHeight() # Load the primary file from the test net in a box self.fileA = os.path.join(self.tiab.tiabDirectory, 'tiab\\armory\\armory_%s_.wallet' % TEST_WALLET_ID) self.wlt = PyBtcWallet().readWalletFile(self.fileA, doScanNow=True) self.jsonServer = Armory_Json_Rpc_Server(self.wlt) TheBDM.registerWallet(self.wlt)
def setUpClass(self): # This is not a UI so no need to worry about the main thread being blocked. # Any UI that uses this Daemon can put the call to the Daemon on it's own thread. TheBDM.setBlocking(True) TheBDM.setOnlineMode(True) while not TheBDM.getBDMState()=='BlockchainReady': time.sleep(2)
def setUpClass(self): # This is not a UI so no need to worry about the main thread being blocked. # Any UI that uses this Daemon can put the call to the Daemon on it's own thread. TheBDM.setBlocking(True) TheBDM.setOnlineMode(True) while not TheBDM.getBDMState() == 'BlockchainReady': time.sleep(2)
def setUp(self): self.verifyBlockHeight() self.fileA = os.path.join(self.armoryHomeDir, 'armory_%s_.wallet' % TEST_WALLET_ID) self.fileB = os.path.join(self.armoryHomeDir, 'armory_%s_backup.wallet' % TEST_WALLET_ID) self.fileAupd = os.path.join(self.armoryHomeDir, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID) self.fileBupd = os.path.join(self.armoryHomeDir, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID) self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd]) # We need a controlled test, so we script the all the normally-random stuff self.privKey = SecureBinaryData('\xaa'*32) self.privKey2 = SecureBinaryData('\x33'*32) self.chainstr = SecureBinaryData('\xee'*32) theIV = SecureBinaryData(hex_to_binary('77'*16)) self.passphrase = SecureBinaryData('A self.passphrase') self.passphrase2 = SecureBinaryData('A new self.passphrase') self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \ plainRootKey=self.privKey, \ chaincode=self.chainstr, \ IV=theIV, \ shortLabel=TEST_WALLET_NAME, \ longLabel=TEST_WALLET_DESCRIPTION, armoryHomeDir = self.armoryHomeDir) self.jsonServer = Armory_Json_Rpc_Server(self.wallet) TheBDM.registerWallet(self.wallet)
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)) # 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
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
def setUp(self): self.verifyBlockHeight() self.fileA = os.path.join(self.armoryHomeDir, 'armory_%s_.wallet' % TEST_WALLET_ID) self.fileB = os.path.join(self.armoryHomeDir, 'armory_%s_backup.wallet' % TEST_WALLET_ID) self.fileAupd = os.path.join( self.armoryHomeDir, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID) self.fileBupd = os.path.join( self.armoryHomeDir, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID) self.removeFileList( [self.fileA, self.fileB, self.fileAupd, self.fileBupd]) # We need a controlled test, so we script the all the normally-random stuff self.privKey = SecureBinaryData('\xaa' * 32) self.privKey2 = SecureBinaryData('\x33' * 32) self.chainstr = SecureBinaryData('\xee' * 32) theIV = SecureBinaryData(hex_to_binary('77' * 16)) self.passphrase = SecureBinaryData('A self.passphrase') self.passphrase2 = SecureBinaryData('A new self.passphrase') #register a callback TheBDM.registerCppNotification(self.armoryDTestCallback) #flag to check on wallet scan status self.walletIsScanned = False #create the wallet self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \ plainRootKey=self.privKey, \ chaincode=self.chainstr, \ IV=theIV, \ shortLabel=TEST_WALLET_NAME, \ longLabel=TEST_WALLET_DESCRIPTION, armoryHomeDir = self.armoryHomeDir) self.jsonServer = Armory_Json_Rpc_Server(self.wallet) #register it self.wallet.registerWallet() #wait on scan for 2 min then raise if the scan hasn't finished yet i = 0 while not self.walletIsScanned: time.sleep(0.5) i += 1 if i >= 60 * 4: raise RuntimeError( "Timeout waiting for TheBDM to register the wallet.")
def setupTheBDM(): TheBDM.setBlocking(True) if not TheBDM.isInitialized(): TheBDM.registerWallet(masterWallet) TheBDM.setOnlineMode(True) # Only executed on the first call if blockchain not loaded yet. LOGINFO('Blockchain loading') while not TheBDM.getBDMState()=='BlockchainReady': LOGINFO('Blockchain Not Ready Yet %s' % TheBDM.getBDMState()) time.sleep(2)
def setUp(self): TheBDM.Reset() self.shortlabel = 'TestWallet1' self.wltID ='3VB8XSoY' if USE_TESTNET else '3VB8XSmd' self.fileA = os.path.join(ARMORY_HOME_DIR, 'armory_%s_.wallet' % self.wltID) self.fileB = os.path.join(ARMORY_HOME_DIR, 'armory_%s_backup.wallet' % self.wltID) self.fileAupd = os.path.join(ARMORY_HOME_DIR, 'armory_%s_backup_unsuccessful.wallet' % self.wltID) self.fileBupd = os.path.join(ARMORY_HOME_DIR, 'armory_%s_update_unsuccessful.wallet' % self.wltID) self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd]) # We need a controlled test, so we script the all the normally-random stuff self.privKey = SecureBinaryData('\xaa'*32) self.privKey2 = SecureBinaryData('\x33'*32) self.chainstr = SecureBinaryData('\xee'*32) theIV = SecureBinaryData(hex_to_binary('77'*16)) self.passphrase = SecureBinaryData('A self.passphrase') self.passphrase2 = SecureBinaryData('A new self.passphrase') self.wlt = PyBtcWallet().createNewWallet(withEncrypt=False, \ plainRootKey=self.privKey, \ chaincode=self.chainstr, \ IV=theIV, \ shortLabel=self.shortlabel)
def searchItem(): searchString = str(self.searchEntry.text()) if len(searchString) > 0: likelyDataType = isLikelyDataType(searchString) for wltID, wlt in self.main.walletMap.iteritems(): if wlt.hasAddr(searchString): searchHash = searchString if likelyDataType == DATATYPE.Hex \ else addrStr_to_hash160(searchString)[1] dialog = DlgAddressInfo(wlt, searchHash, main=self.main) dialog.exec_() break if likelyDataType == DATATYPE.Hex: walletLedger = wlt.cppWallet.getTxLedger() txHashToFind = hex_to_binary(searchString, endOut=BIGENDIAN) txFound = False for entry in walletLedger: if entry.getTxHash() == txHashToFind: cppTx = TheBDM.getTxByHash(txHashToFind) serializedCppTx = cppTx.serialize() pytx = PyTx().unserialize(serializedCppTx) DlgDispTxInfo(pytx, wlt, self.main, self.main).exec_() txFound = True break if txFound: break
def updateOnCoinControl(self): useAllAddr = (self.altBalance == None) wlt = self.main.walletMap[self.getSelectedWltID()] fullBal = wlt.getBalance('Spendable') if useAllAddr: self.dispID.setText(wlt.uniqueIDB58) self.dispName.setText(wlt.labelName) self.dispDescr.setText(wlt.labelDescr) if fullBal == 0: self.dispBal.setText('0.0', color='TextRed', bold=True) else: self.dispBal.setValueText(fullBal, wBold=True) else: self.dispID.setText(wlt.uniqueIDB58 + '*') self.dispName.setText(wlt.labelName + '*') self.dispDescr.setText('*Coin Control Subset*', color='TextBlue', bold=True) self.dispBal.setText(coin2str(self.altBalance, maxZeros=0), color='TextBlue') rawValTxt = str(self.dispBal.text()) self.dispBal.setText(rawValTxt + ' <font color="%s">(of %s)</font>' % \ (htmlColor('DisableFG'), coin2str(fullBal, maxZeros=0))) if not TheBDM.getState() == BDM_BLOCKCHAIN_READY: self.dispBal.setText('(available when online)', color='DisableFG') self.repaint() if self.coinControlCallback: self.coinControlCallback(self.sourceAddrList, self.altBalance)
def __init__(self, parent, main): super(WalletWizard, self).__init__(parent, main) self.newWallet = None self.isBackupCreated = False self.setWindowTitle(tr("Wallet Creation Wizard")) self.setOption(QWizard.HaveFinishButtonOnEarlyPages, on=True) self.setOption(QWizard.IgnoreSubTitles, on=True) # Page 1: Create Wallet self.walletCreationPage = WalletCreationPage(self) self.addPage(self.walletCreationPage) # Page 2: Set Passphrase self.setPassphrasePage = SetPassphrasePage(self) self.addPage(self.setPassphrasePage) # Page 3: Verify Passphrase self.verifyPassphrasePage = VerifyPassphrasePage(self) self.addPage(self.verifyPassphrasePage) # Page 4: Create Paper Backup self.walletBackupPage = WalletBackupPage(self) self.addPage(self.walletBackupPage) # Page 5: Create Watching Only Wallet -- but only if expert, or offline self.hasCWOWPage = False if self.main.usermode == USERMODE.Expert or TheBDM.getState() == BDM_OFFLINE: self.hasCWOWPage = True self.createWOWPage = CreateWatchingOnlyWalletPage(self) self.addPage(self.createWOWPage) self.setButtonLayout([QWizard.BackButton, QWizard.Stretch, QWizard.NextButton, QWizard.FinishButton])
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 = PyTxDistProposal().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.prepareFinalTx() print '\nSigned transaction to be broadcast using Armory "offline transactions"...' print txdp.serializeAscii() finally: TheBDM.execCleanShutdown() return pytx
def tearDownClass(self): def tiabBDMShutdownCallback(action, arg): global doneShuttingDownBDM if action == STOPPED_ACTION: doneShuttingDownBDM = True TheBDM.registerCppNotification(tiabBDMShutdownCallback) TheBDM.beginCleanShutdown() i = 0 while not doneShuttingDownBDM: time.sleep(0.5) i += 1 if i >= 40: raise RuntimeError("Timeout waiting for TheBDM to shutdown.") self.tiab.clean()
def getTxFee(tx): btcIn, btcOut = 0, 0 for i in range(tx.getNumTxIn()): btcIn += TheBDM.getSentValue(tx.getTxIn(i)) for i in range(tx.getNumTxOut()): btcOut += tx.getTxOut(i).getValue() return (btcIn - btcOut)
def getTxFee(tx): btcIn, btcOut = 0,0 for i in range(tx.getNumTxIn()): btcIn += TheBDM.getSentValue(tx.getTxIn(i)) for i in range(tx.getNumTxOut()): btcOut += tx.getTxOut(i).getValue() return (btcIn - btcOut)
def setUpClass(self): global doneShuttingDownBDM doneShuttingDownBDM = False # Handle both calling the this test from the context of the test directory # and calling this test from the context of the main directory. # The latter happens if you run all of the tests in the directory if os.path.exists(TIAB_ZIPFILE_NAME): tiabZipPath = TIAB_ZIPFILE_NAME elif os.path.exists(os.path.join('pytest',TIAB_ZIPFILE_NAME)): tiabZipPath = (os.path.join('pytest',TIAB_ZIPFILE_NAME)) else: self.fail(NEED_TIAB_MSG) self.tiab = TiabSession(tiabZipPath=tiabZipPath) newTheBDM() self.armoryHomeDir = os.path.join(self.tiab.tiabDirectory,'tiab','armory') TheBDM.setSatoshiDir(os.path.join(self.tiab.tiabDirectory,'tiab','1','testnet3')) TheBDM.setArmoryDBDir(os.path.join(self.tiab.tiabDirectory,'tiab','armory','databases')) TheBDM.goOnline(armoryDBDir=self.armoryHomeDir) i = 0 while not TheBDM.getState()==BDM_BLOCKCHAIN_READY: time.sleep(2) i += 1 if i >= 60: raise RuntimeError("Timeout waiting for TheBDM to get into BlockchainReady state.")
def setUp(self): self.verifyBlockHeight() # Load the primary file from the test net in a box self.fileA = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % FIRST_WLT_NAME) self.wltA = PyBtcWallet().readWalletFile(self.fileA, doScanNow=True) self.fileB = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % SECOND_WLT_NAME) self.wltB = PyBtcWallet().readWalletFile(self.fileB, doScanNow=True) self.fileC = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % THIRD_WLT_NAME) self.wltC = PyBtcWallet().readWalletFile(self.fileC, doScanNow=True) self.jsonServer = Armory_Json_Rpc_Server(self.wltA, \ inWltMap={SECOND_WLT_NAME : self.wltB, \ THIRD_WLT_NAME : self.wltC}, \ armoryHomeDir=os.path.join(self.tiab.tiabDirectory, \ 'tiab','armory')) TheBDM.registerWallet(self.wltA)
def setUp(self): self.verifyBlockHeight() self.fileA = os.path.join(self.armoryHomeDir, 'armory_%s_.wallet' % TEST_WALLET_ID) self.fileB = os.path.join(self.armoryHomeDir, 'armory_%s_backup.wallet' % TEST_WALLET_ID) self.fileAupd = os.path.join(self.armoryHomeDir, 'armory_%s_backup_unsuccessful.wallet' % TEST_WALLET_ID) self.fileBupd = os.path.join(self.armoryHomeDir, 'armory_%s_update_unsuccessful.wallet' % TEST_WALLET_ID) self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd]) # We need a controlled test, so we script the all the normally-random stuff self.privKey = SecureBinaryData('\xaa'*32) self.privKey2 = SecureBinaryData('\x33'*32) self.chainstr = SecureBinaryData('\xee'*32) theIV = SecureBinaryData(hex_to_binary('77'*16)) self.passphrase = SecureBinaryData('A self.passphrase') self.passphrase2 = SecureBinaryData('A new self.passphrase') #register a callback TheBDM.registerCppNotification(self.armoryDTestCallback) #flag to check on wallet scan status self.walletIsScanned = False #create the wallet self.wallet = PyBtcWallet().createNewWallet(withEncrypt=False, \ plainRootKey=self.privKey, \ chaincode=self.chainstr, \ IV=theIV, \ shortLabel=TEST_WALLET_NAME, \ longLabel=TEST_WALLET_DESCRIPTION, armoryHomeDir = self.armoryHomeDir) self.jsonServer = Armory_Json_Rpc_Server(self.wallet) #register it self.wallet.registerWallet() #wait on scan for 2 min then raise if the scan hasn't finished yet i = 0 while not self.walletIsScanned: time.sleep(0.5) i += 1 if i >= 60*4: raise RuntimeError("Timeout waiting for TheBDM to register the wallet.")
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 Groestlcoin is 0.0000 0001 GRS. 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()
def setUp(self): self.verifyBlockHeight() # Load the primary file from the test net in a box self.fileA = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % FIRST_WLT_NAME) self.wltA = PyBtcWallet().readWalletFile(self.fileA) self.fileB = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % SECOND_WLT_NAME) self.wltB = PyBtcWallet().readWalletFile(self.fileB) self.fileC = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % THIRD_WLT_NAME) self.wltC = PyBtcWallet().readWalletFile(self.fileC) self.jsonServer = Armory_Json_Rpc_Server(self.wltA, \ inWltMap={SECOND_WLT_NAME : self.wltB, \ THIRD_WLT_NAME : self.wltC}, \ armoryHomeDir=os.path.join(self.tiab.tiabDirectory, \ 'tiab','armory')) self.wltIDs = [ self.wltA.uniqueIDB58, self.wltB.uniqueIDB58, self.wltC.uniqueIDB58 ] #register a callback TheBDM.registerCppNotification(self.armoryDTiabTestCallback) #flag to check on wallet scan status self.numberOfWalletsScanned = 0 self.wltA.registerWallet() time.sleep(0.5) self.wltB.registerWallet() time.sleep(0.5) self.wltC.registerWallet() time.sleep(0.5) #wait on scan for 20sec then raise if the scan hasn't finished yet i = 0 while self.numberOfWalletsScanned < 3: time.sleep(0.5) i += 1 if i >= 40: raise RuntimeError("self.numberOfWalletsScanned = %d" % self.numberOfWalletsScanned)
def setupTheBDM(): TheBDM.setBlocking(True) if not TheBDM.getState()==BDM_BLOCKCHAIN_READY: masterWallet.registerWallet() TheBDM.setOnlineMode(True) # Only executed on the first call if blockchain not loaded yet. LOGINFO('Blockchain loading') while not TheBDM.getState()==BDM_BLOCKCHAIN_READY: LOGINFO('Blockchain Not Ready Yet %s' % TheBDM.getState()) time.sleep(2)
def setUp(self): self.verifyBlockHeight() # Load the primary file from the test net in a box self.fileA = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % FIRST_WLT_NAME) self.wltA = PyBtcWallet().readWalletFile(self.fileA) self.fileB = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % SECOND_WLT_NAME) self.wltB = PyBtcWallet().readWalletFile(self.fileB) self.fileC = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', \ 'armory_%s_.wallet' % THIRD_WLT_NAME) self.wltC = PyBtcWallet().readWalletFile(self.fileC) self.jsonServer = Armory_Json_Rpc_Server(self.wltA, \ inWltMap={SECOND_WLT_NAME : self.wltB, \ THIRD_WLT_NAME : self.wltC}, \ armoryHomeDir=os.path.join(self.tiab.tiabDirectory, \ 'tiab','armory')) self.wltIDs = [self.wltA.uniqueIDB58, self.wltB.uniqueIDB58, self.wltC.uniqueIDB58] #register a callback TheBDM.registerCppNotification(self.armoryDTiabTestCallback) #flag to check on wallet scan status self.numberOfWalletsScanned = 0 self.wltA.registerWallet() time.sleep(0.5) self.wltB.registerWallet() time.sleep(0.5) self.wltC.registerWallet() time.sleep(0.5) #wait on scan for 20sec then raise if the scan hasn't finished yet i = 0 while self.numberOfWalletsScanned < 3: time.sleep(0.5) i += 1 if i >= 40: raise RuntimeError("self.numberOfWalletsScanned = %d" % self.numberOfWalletsScanned)
def __init__(self, parent, main): super(WalletWizard, self).__init__(parent, main) self.newWallet = None self.isBackupCreated = False self.setWindowTitle(tr("Wallet Creation Wizard")) self.setOption(QWizard.HaveFinishButtonOnEarlyPages, on=True) self.setOption(QWizard.IgnoreSubTitles, on=True) self.walletCreationId, self.manualEntropyId, self.setPassphraseId, self.verifyPassphraseId, self.walletBackupId, self.WOWId = range( 6) # Page 1: Create Wallet self.walletCreationPage = WalletCreationPage(self) self.setPage(self.walletCreationId, self.walletCreationPage) # Page 1.5: Add manual entropy self.manualEntropyPage = ManualEntropyPage(self) self.setPage(self.manualEntropyId, self.manualEntropyPage) # Page 2: Set Passphrase self.setPassphrasePage = SetPassphrasePage(self) self.setPage(self.setPassphraseId, self.setPassphrasePage) # Page 3: Verify Passphrase self.verifyPassphrasePage = VerifyPassphrasePage(self) self.setPage(self.verifyPassphraseId, self.verifyPassphrasePage) # Page 4: Create Paper Backup self.walletBackupPage = WalletBackupPage(self) self.setPage(self.walletBackupId, self.walletBackupPage) # Page 5: Create Watching Only Wallet -- but only if expert, or offline self.hasCWOWPage = False if self.main.usermode == USERMODE.Expert or TheBDM.getState( ) == BDM_OFFLINE: self.hasCWOWPage = True self.createWOWPage = CreateWatchingOnlyWalletPage(self) self.setPage(self.WOWId, self.createWOWPage) self.setButtonLayout([ QWizard.BackButton, QWizard.Stretch, QWizard.NextButton, QWizard.FinishButton ])
def updateWalletTable(self): numWallets = len(self.main.walletMap) self.wltTable.setRowCount(numWallets) self.wltTable.setColumnCount(4) row = 0 for wltID, wltObj in self.main.walletMap.iteritems(): wltValueBTC = '(...)' wltValueUSD = '(...)' if TheBDM.getState() == BDM_BLOCKCHAIN_READY: convertVal = float(self.lastSellStr.replace(',', '')) wltBal = wltObj.getBalance('Total') wltValueBTC = coin2str(wltBal, maxZeros=2) wltValueUSD = '$' + self.addCommasToPrice( '%0.2f' % (wltBal * convertVal / 1e8)) rowItems = [] rowItems.append(QTableWidgetItem(wltID)) rowItems.append(QTableWidgetItem(wltObj.labelName)) rowItems.append(QTableWidgetItem(wltValueBTC)) rowItems.append(QTableWidgetItem(wltValueUSD)) rowItems[-2].setTextAlignment(Qt.AlignRight) rowItems[-1].setTextAlignment(Qt.AlignRight) rowItems[-2].setFont(GETFONT('Fixed', 10)) rowItems[-1].setFont(GETFONT('Fixed', 10)) for i, item in enumerate(rowItems): self.wltTable.setItem(row, i, item) item.setFlags(Qt.NoItemFlags) self.wltTable.setHorizontalHeaderItem( 0, QTableWidgetItem(tr('Wallet ID'))) self.wltTable.setHorizontalHeaderItem( 1, QTableWidgetItem(tr('Wallet Name'))) self.wltTable.setHorizontalHeaderItem( 2, QTableWidgetItem(tr('BTC Balance'))) self.wltTable.setHorizontalHeaderItem( 3, QTableWidgetItem(tr('USD ($) Value'))) self.wltTable.verticalHeader().hide() row += 1
def updateOnWalletChange(self, ignoredInt=None): """ "ignoredInt" is because the signals should call this function with the selected index of the relevant container, but we grab it again anyway using getSelectedWltID() """ wltID = self.getSelectedWltID() if len(wltID) > 0: wlt = self.main.walletMap[wltID] self.dispID.setText(wltID) self.dispName.setText(wlt.labelName) self.dispDescr.setText(wlt.labelDescr) self.selectedID = wltID if not TheBDM.getState() == BDM_BLOCKCHAIN_READY: self.dispBal.setText('-' * 12) else: bal = wlt.getBalance('Spendable') balStr = coin2str(wlt.getBalance('Spendable'), maxZeros=1) if bal <= self.balAtLeast: self.dispBal.setText('<font color="red"><b>%s</b></font>' % balStr) else: self.dispBal.setText('<b>' + balStr + '</b>') if self.selectWltCallback: self.selectWltCallback(wlt) self.repaint() # Reset the coin control variables after a new wallet is selected if self.coinControlCallback: self.altBalance = None self.sourceAddrList = None self.btnCoinCtrl.setEnabled(wlt.getBalance('Spendable') > 0) self.lblCoinCtrl.setText('Source: All addresses' if wlt.getBalance('Spendable')>0 else\ 'Source: 0 addresses' ) self.updateOnCoinControl()
def updateOnWalletChange(self, ignoredInt=None): """ "ignoredInt" is because the signals should call this function with the selected index of the relevant container, but we grab it again anyway using getSelectedWltID() """ wltID = self.getSelectedWltID() if len(wltID) > 0: wlt = self.main.walletMap[wltID] self.dispID.setText(wltID) self.dispName.setText(wlt.labelName) self.dispDescr.setText(wlt.labelDescr) self.selectedID = wltID if not TheBDM.getState() == BDM_BLOCKCHAIN_READY: self.dispBal.setText('-' * 12) else: bal = wlt.getBalance('Spendable') balStr = coin2str(wlt.getBalance('Spendable'), maxZeros=1) if bal <= self.balAtLeast: self.dispBal.setText('<font color="red"><b>%s</b></font>' % balStr) else: self.dispBal.setText('<b>' + balStr + '</b>') if self.selectWltCallback: self.selectWltCallback(wlt) self.repaint() # Reset the coin control variables after a new wallet is selected if self.coinControlCallback: self.altBalance = None self.sourceAddrList = None self.btnCoinCtrl.setEnabled(wlt.getBalance('Spendable')>0) self.lblCoinCtrl.setText('Source: All addresses' if wlt.getBalance('Spendable')>0 else\ 'Source: 0 addresses' ) self.updateOnCoinControl()
def updateWalletTable(self): numWallets = len(self.main.walletMap) self.wltTable.setRowCount(numWallets) self.wltTable.setColumnCount(4) row = 0 for wltID, wltObj in self.main.walletMap.iteritems(): wltValueBTC = "(...)" wltValueUSD = "(...)" if TheBDM.getState() == BDM_BLOCKCHAIN_READY: convertVal = float(self.lastSellStr.replace(",", "")) wltBal = wltObj.getBalance("Total") wltValueBTC = coin2str(wltBal, maxZeros=2) wltValueUSD = "$" + self.addCommasToPrice("%0.2f" % (wltBal * convertVal / 1e8)) rowItems = [] rowItems.append(QTableWidgetItem(wltID)) rowItems.append(QTableWidgetItem(wltObj.labelName)) rowItems.append(QTableWidgetItem(wltValueBTC)) rowItems.append(QTableWidgetItem(wltValueUSD)) rowItems[-2].setTextAlignment(Qt.AlignRight) rowItems[-1].setTextAlignment(Qt.AlignRight) rowItems[-2].setFont(GETFONT("Fixed", 10)) rowItems[-1].setFont(GETFONT("Fixed", 10)) for i, item in enumerate(rowItems): self.wltTable.setItem(row, i, item) item.setFlags(Qt.NoItemFlags) self.wltTable.setHorizontalHeaderItem(0, QTableWidgetItem(tr("Wallet ID"))) self.wltTable.setHorizontalHeaderItem(1, QTableWidgetItem(tr("Wallet Name"))) self.wltTable.setHorizontalHeaderItem(2, QTableWidgetItem(tr("BTC Balance"))) self.wltTable.setHorizontalHeaderItem(3, QTableWidgetItem(tr("USD ($) Value"))) self.wltTable.verticalHeader().hide() row += 1
def setup(self): rbfList = self.wallet.getRBFTxOutList() self.rbfDict = {} #order outputs by parent hash for utxo in rbfList: parentHash = utxo.getTxHashStr() if not parentHash in self.rbfDict: self.rbfDict[parentHash] = [] utxoList = self.rbfDict[parentHash] utxoList.append(utxo) for txhash in self.rbfDict: #get outpoints for spender tx entryList = self.rbfDict[txhash] cppTx = TheBDM.bdv().getTxByHash(txhash) if cppTx.isInitialized(): pytx = PyTx().unserialize(cppTx.serialize()) else: continue for _input in pytx.inputs: spentHash = _input.outpoint.txHash #if this tx redeems an output in our list of RBF tx, #link it to the spendee if spentHash in self.rbfDict: spendeeList = self.rbfDict[spentHash] spendeeList.append([txhash, entryList]) def getRBFDict(): return self.rbfDict self.root = RBFTreeNode(None, "root", True, getRBFDict)
def updateWalletTable(self): numWallets = len(self.main.walletMap) self.wltTable.setRowCount(numWallets) self.wltTable.setColumnCount(4) row = 0 for wltID,wltObj in self.main.walletMap.iteritems(): wltValueBTC = '(...)' wltValueUSD = '(...)' if TheBDM.getBDMState()=='BlockchainReady': convertVal = float(self.lastSellStr.replace(',','')) wltBal = wltObj.getBalance('Total') wltValueBTC = coin2str(wltBal, maxZeros=2) wltValueUSD = '$' + self.addCommasToPrice('%0.2f' % (wltBal*convertVal/1e8)) rowItems = [] rowItems.append(QTableWidgetItem(wltID)) rowItems.append(QTableWidgetItem(wltObj.labelName)) rowItems.append(QTableWidgetItem(wltValueBTC)) rowItems.append(QTableWidgetItem(wltValueUSD)) rowItems[-2].setTextAlignment(Qt.AlignRight) rowItems[-1].setTextAlignment(Qt.AlignRight) rowItems[-2].setFont(GETFONT('Fixed', 10)) rowItems[-1].setFont(GETFONT('Fixed', 10)) for i,item in enumerate(rowItems): self.wltTable.setItem(row, i, item) item.setFlags(Qt.NoItemFlags) self.wltTable.setHorizontalHeaderItem(0, QTableWidgetItem(tr('Wallet ID'))) self.wltTable.setHorizontalHeaderItem(1, QTableWidgetItem(tr('Wallet Name'))) self.wltTable.setHorizontalHeaderItem(2, QTableWidgetItem(tr('BTC Balance'))) self.wltTable.setHorizontalHeaderItem(3, QTableWidgetItem(tr('USD ($) Value'))) self.wltTable.verticalHeader().hide() row += 1
def tearDown(self): TheBDM.unregisterCppNotification(self.armoryDTiabTestCallback) self.wltA.unregisterWallet() self.wltB.unregisterWallet() self.wltC.unregisterWallet() self.resetWalletFiles()
def setUp(self): TheBDM.Reset(wait=True)
def fetchCpp(self): """ Convert a raw blockheader with no context, to a C++ BlockHeader """ return TheBDM.getHeaderByHash(self.getHash())
def __init__(self, parent, main, layoutDir=VERTICAL, spendFromLBID=None): super(LockboxSelectFrame, self).__init__(parent, main) self.lbox = self.main.getLockboxByID(spendFromLBID) self.cppWlt = self.main.cppLockboxWltMap[spendFromLBID] if not self.lbox: QMessageBox.warning(self, tr("Invalid Lockbox"), tr(""" There was an error loading the specified lockbox (%s).""") % spendFromLBID, QMessageBox.Ok) self.reject() return lblSpendFromLB = QRichLabel(tr(""" <font color="%s" size=4><b><u>Lockbox %s (%d-of-%d)</u></b></font>""") % (htmlColor('TextBlue'), \ self.lbox.uniqueIDB58, self.lbox.M, self.lbox.N)) lblSpendFromLB.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) lbls = [] lbls.append(QRichLabel("Lockbox ID:", doWrap=False)) lbls.append(QRichLabel("Name:", doWrap=False)) lbls.append(QRichLabel("Description:", doWrap=False)) lbls.append(QRichLabel("Spendable GRS:", doWrap=False)) layoutDetails = QGridLayout() for i,lbl in enumerate(lbls): lbl.setAlignment(Qt.AlignLeft | Qt.AlignTop) lbl.setText('<b>' + str(lbls[i].text()) + '</b>') layoutDetails.addWidget(lbl, i+1, 0) # LockboxID self.dispID = QRichLabel(spendFromLBID) # Lockbox Short Description/Name self.dispName = QRichLabel(self.lbox.shortName) self.dispName.setWordWrap(True) self.dispName.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # Lockbox long descr dispDescr = self.lbox.longDescr[:253] if len(self.lbox.longDescr)>253: dispDescr += '...' self.dispDescr = QRichLabel(dispDescr) self.dispDescr.setWordWrap(True) self.dispDescr.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) bal = self.cppWlt.getSpendableBalance(TheBDM.getTopBlockHeight(), IGNOREZC) self.dispBal = QMoneyLabel(bal, wBold=True) self.dispBal.setTextFormat(Qt.RichText) layoutDetails.addWidget(self.dispID, 1, 1) layoutDetails.addWidget(self.dispName, 2, 1) layoutDetails.addWidget(self.dispDescr, 3, 1) layoutDetails.addWidget(self.dispBal, 4, 1) layoutDetails.setColumnStretch(0,0) layoutDetails.setColumnStretch(1,1) frmDetails = QFrame() frmDetails.setLayout(layoutDetails) frmDetails.setFrameStyle(STYLE_SUNKEN) layout = QVBoxLayout() layout.addWidget(lblSpendFromLB) layout.addWidget(frmDetails) self.setLayout(layout)
def tearDown(self): TheBDM.unregisterCppNotification(self.armoryDTestCallback) self.wallet.unregisterWallet() self.removeFileList( [self.fileA, self.fileB, self.fileAupd, self.fileBupd])
cppWallet.registerWallet() ################################################################################ if run_LoadBlockchain_Async: """ By setting blocking=False, most calls to TheBDM will return immediately, after queuing the BDM to execute the operation in the background. You have to check back later to see when it's done. However, even when blocking is false, any functions that return data must block so the data can be returned. If you are in asynchronous mode, and don't want to ever wait for anything, always check TheBDM.getState()==BDM_BLOCKCHAIN_READY before requesting data that will force blocking. """ start = RightNow() TheBDM.setBlocking(False) TheBDM.setOnlineMode(True) sleep(2) print 'Waiting for blockchain loading to finish', while not TheBDM.getState()==BDM_BLOCKCHAIN_READY: print '.', sys.stdout.flush() sleep(2) print 'Loading blockchain took %0.1f sec' % (RightNow() - start) topBlock = TheBDM.getTopBlockHeight() print '\n\nCurrent Top Block is:', topBlock TheBDM.blockchain().top().pprint() ################################################################################ if run_LoadBlockchain_Block:
def __init__(self, parent, main, addrtype): super(AddressTypeSelectDialog, self).__init__(parent, main) self.type = "P2PKH" if addrtype is not None: self.type = addrtype #p2pkh self.radioP2PKH = QRadioButton(self.tr("P2PKH Address")) p2pkhDescr = QLabel( self.tr('Legacy Armory address type. Backwards compatible.')) frmP2PKH = QFrame() frmP2PKH.setFrameStyle(STYLE_RAISED) p2pkhLayout = QGridLayout() p2pkhLayout.addWidget(self.radioP2PKH, 0, 0, 1, 1) p2pkhLayout.addWidget(p2pkhDescr, 1, 0, 1, 1) frmP2PKH.setLayout(p2pkhLayout) def setP2PKH(): self.selectType('P2PKH') self.connect(self.radioP2PKH, SIGNAL('clicked()'), setP2PKH) #nested p2wpkh self.radioSW = QRadioButton(self.tr("P2SH-P2WPKH address")) swDescr = QLabel( self. tr('P2WPKH (SegWit script) nested in P2SH script. Any wallet can pay to ' 'this address. Only wallets supporting SegWit can spend from it.' )) frmSW = QFrame() frmSW.setFrameStyle(STYLE_RAISED) swLayout = QGridLayout() swLayout.addWidget(self.radioSW, 0, 0, 1, 1) swLayout.addWidget(swDescr, 1, 0, 1, 1) frmSW.setLayout(swLayout) if TheBDM.isSegWitEnabled() == False: frmSW.setDisabled(True) def setSW(): self.selectType('P2SH-P2WPKH') self.connect(self.radioSW, SIGNAL('clicked()'), setSW) #nested p2pk self.radioNP2PK = QRadioButton(self.tr("P2SH-P2PK address")) np2pkDescr = QLabel( self. tr('Compressed P2PK script nested in P2SH output. Any wallet can pay to this ' 'address. Only Armory 0.96+ can spend from it.<br><br>' 'This format allow for more efficient transaction space use, resulting in ' 'smaller inputs and lower fees.')) frmNP2PK = QFrame() frmNP2PK.setFrameStyle(STYLE_RAISED) np2pkLayout = QGridLayout() np2pkLayout.addWidget(self.radioNP2PK, 0, 0, 1, 1) np2pkLayout.addWidget(np2pkDescr, 1, 0, 1, 1) frmNP2PK.setLayout(np2pkLayout) def setNP2PK(): self.selectType('P2SH-P2PK') self.connect(self.radioNP2PK, SIGNAL('clicked()'), setNP2PK) #main layout layout = QGridLayout() layout.addWidget(frmP2PKH, 0, 0, 1, 4) layout.addWidget(frmNP2PK, 2, 0, 1, 4) layout.addWidget(frmSW, 4, 0, 1, 4) self.btnOk = QPushButton(self.tr('Apply')) self.btnCancel = QPushButton(self.tr('Cancel')) self.connect(self.btnOk, SIGNAL('clicked()'), self.accept) self.connect(self.btnCancel, SIGNAL('clicked()'), self.reject) layout.addWidget(self.btnOk, 5, 2, 1, 1) layout.addWidget(self.btnCancel, 5, 3, 1, 1) self.setLayout(layout) self.setWindowTitle(self.tr('Select Address Type')) self.selectType(self.type) self.setFocus()
def setUpClass(self): # Handle both calling the this test from the context of the test directory # and calling this test from the context of the main directory. # The latter happens if you run all of the tests in the directory if os.path.exists(TIAB_ZIPFILE_NAME): tiabZipPath = TIAB_ZIPFILE_NAME elif os.path.exists(os.path.join('pytest', TIAB_ZIPFILE_NAME)): tiabZipPath = (os.path.join('pytest', TIAB_ZIPFILE_NAME)) else: self.fail(NEED_TIAB_MSG) self.tiab = TiabSession(tiabZipPath=tiabZipPath) # Need to destroy whatever BDM may have been created automatically CppBlockUtils.BlockDataManager().DestroyBDM() newTheBDM() TheBDM.setDaemon(True) TheBDM.start() TheBDM.setSatoshiDir( os.path.join(self.tiab.tiabDirectory, 'tiab', '1', 'testnet3')) self.armoryHomeDir = os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory') TheBDM.setLevelDBDir( os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory', 'databases')) TheBDM.setBlocking(True) TheBDM.setOnlineMode(wait=True) i = 0 while not TheBDM.getBDMState() == 'BlockchainReady' and i < 10: time.sleep(2) i += 1 if i >= 10: raise RuntimeError( "Timeout waiting for TheBDM to get into BlockchainReady state." )
def setUpClass(self): # Handle both calling the this test from the context of the test directory # and calling this test from the context of the main directory. # The latter happens if you run all of the tests in the directory if os.path.exists(TIAB_ZIPFILE_NAME): tiabZipPath = TIAB_ZIPFILE_NAME elif os.path.exists(os.path.join('test',TIAB_ZIPFILE_NAME)): tiabZipPath = (os.path.join('test',TIAB_ZIPFILE_NAME)) else: self.fail(NEED_TIAB_MSG) self.tiab = TiabSession(tiabZipPath=tiabZipPath) # Need to destroy whatever BDM may have been created automatically CppBlockUtils.BlockDataManager().DestroyBDM() newTheBDM() TheBDM.setDaemon(True) TheBDM.start() TheBDM.setSatoshiDir(os.path.join(self.tiab.tiabDirectory,'tiab','1','testnet3')) TheBDM.setLevelDBDir(os.path.join(self.tiab.tiabDirectory,'tiab','armory','databases')) TheBDM.setBlocking(True) TheBDM.setOnlineMode(wait=True) while not TheBDM.getBDMState()=='BlockchainReady': time.sleep(2)
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()
def __init__(self, parent, main, layoutDir=VERTICAL, spendFromLBID=None): super(LockboxSelectFrame, self).__init__(parent, main) self.lbox = self.main.getLockboxByID(spendFromLBID) self.cppWlt = self.main.cppLockboxWltMap[spendFromLBID] if not self.lbox: QMessageBox.warning( self, tr("Invalid Lockbox"), tr(""" There was an error loading the specified lockbox (%s).""") % spendFromLBID, QMessageBox.Ok) self.reject() return lblSpendFromLB = QRichLabel(tr(""" <font color="%s" size=4><b><u>Lockbox %s (%d-of-%d)</u></b></font>""") % (htmlColor('TextBlue'), \ self.lbox.uniqueIDB58, self.lbox.M, self.lbox.N)) lblSpendFromLB.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) lbls = [] lbls.append(QRichLabel("Lockbox ID:", doWrap=False)) lbls.append(QRichLabel("Name:", doWrap=False)) lbls.append(QRichLabel("Description:", doWrap=False)) lbls.append(QRichLabel("Spendable BTC:", doWrap=False)) layoutDetails = QGridLayout() for i, lbl in enumerate(lbls): lbl.setAlignment(Qt.AlignLeft | Qt.AlignTop) lbl.setText('<b>' + str(lbls[i].text()) + '</b>') layoutDetails.addWidget(lbl, i + 1, 0) # LockboxID self.dispID = QRichLabel(spendFromLBID) # Lockbox Short Description/Name self.dispName = QRichLabel(self.lbox.shortName) self.dispName.setWordWrap(True) self.dispName.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # Lockbox long descr dispDescr = self.lbox.longDescr[:253] if len(self.lbox.longDescr) > 253: dispDescr += '...' self.dispDescr = QRichLabel(dispDescr) self.dispDescr.setWordWrap(True) self.dispDescr.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) bal = self.cppWlt.getSpendableBalance(TheBDM.getTopBlockHeight(), IGNOREZC) self.dispBal = QMoneyLabel(bal, wBold=True) self.dispBal.setTextFormat(Qt.RichText) layoutDetails.addWidget(self.dispID, 1, 1) layoutDetails.addWidget(self.dispName, 2, 1) layoutDetails.addWidget(self.dispDescr, 3, 1) layoutDetails.addWidget(self.dispBal, 4, 1) layoutDetails.setColumnStretch(0, 0) layoutDetails.setColumnStretch(1, 1) frmDetails = QFrame() frmDetails.setLayout(layoutDetails) frmDetails.setFrameStyle(STYLE_SUNKEN) layout = QVBoxLayout() layout.addWidget(lblSpendFromLB) layout.addWidget(frmDetails) self.setLayout(layout)
def tearDown(self): TheBDM.unregisterCppNotification(self.armoryDTestCallback) self.wallet.unregisterWallet() self.removeFileList([self.fileA, self.fileB, self.fileAupd, self.fileBupd])
def verifyBlockHeight(self): blockHeight = TheBDM.getTopBlockHeight() self.assertEqual(blockHeight, TOP_TIAB_BLOCK, NEED_TIAB_MSG + str(blockHeight))