def hw4Exercise2(): print "Block Chain Parser HW #4 Exercise #2: " addrHistory = getAddrHistory(addrStr_to_hash160(TEST_ARMORY)) for key in sorted(addrHistory, key=lambda outpoint: outpoint.blkNum): print binary_to_hex(key.txHash, BIGENDIAN)[:8]+'...', key.txOutIndex, print coin2str(addrHistory[key].totalAccumulated, 4), print coin2str(addrHistory[key].balance, 4), print "Unspent" if addrHistory[key].txIn == None else "Spent"
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)
def data(self, index, role=Qt.DisplayRole): if role==Qt.DisplayRole: col = index.column() node = self.getNodeItem(index) if col == COL_TREE: return QVariant(node.treeNode.getName()) if col == COL_BALANCE: try: return QVariant(coin2str(node.treeNode.getBalance(), maxZeros=2)) except: return QVariant() if node.hasChildren(): return QVariant() if not node.treeNode.canDoubleClick(): return QVariant() if col == COL_COMMENT: return QVariant(node.treeNode.getComment()) if col == COL_COUNT: return QVariant(node.treeNode.getCount()) return QVariant()
def data(self, index, role=Qt.DisplayRole): if role == Qt.DisplayRole: col = index.column() node = self.getNodeItem(index) if col == COL_TREE: return QVariant(node.treeNode.getName()) if col == COL_BALANCE: try: return QVariant( coin2str(node.treeNode.getBalance(), maxZeros=2)) except: return QVariant() if node.hasChildren(): return QVariant() if not node.treeNode.canDoubleClick(): return QVariant() if col == COL_COMMENT: return QVariant(node.treeNode.getComment()) if col == COL_COUNT: return QVariant(node.treeNode.getCount()) return QVariant()
def data(self, index, role=Qt.DisplayRole): row, col = index.row(), index.column() txout = self.dustTxOutlist[row] addrStr = script_to_addrStr(txout.getScript()) pyAddr = self.wlt.addrMap[addrStr_to_hash160(addrStr)[1]] chainIndex = pyAddr.chainIndex + 1 if role == Qt.DisplayRole: if col == DUSTCOLS.chainIndex: return QVariant(chainIndex) if col == DUSTCOLS.AddrStr: return QVariant(addrStr) if col == DUSTCOLS.Btc: return QVariant(coin2str(txout.getValue(), maxZeros=8)) elif role == Qt.TextAlignmentRole: if col == DUSTCOLS.chainIndex: return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter)) if col == DUSTCOLS.AddrStr: return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter)) if col == DUSTCOLS.Btc: return QVariant(int(Qt.AlignRight | Qt.AlignVCenter)) elif role == Qt.ForegroundRole: return QVariant(Colors.Foreground) elif role == Qt.FontRole: if col == DUSTCOLS.Btc: return GETFONT('Fixed') return QVariant()
def data(self, index, role=Qt.DisplayRole): row, col = index.row(), index.column() txout = self.dustTxOutlist[row] addrStr = script_to_addrStr(txout.getScript()) pyAddr = self.wlt.addrMap[addrStr_to_hash160(addrStr)[1]] chainIndex = pyAddr.chainIndex + 1 if role == Qt.DisplayRole: if col == DUSTCOLS.chainIndex: return QVariant(chainIndex) if col == DUSTCOLS.AddrStr: return QVariant(addrStr) if col == DUSTCOLS.Btc: return QVariant(coin2str(txout.getValue(), maxZeros=8)) elif role == Qt.TextAlignmentRole: if col == DUSTCOLS.chainIndex: return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter)) if col == DUSTCOLS.AddrStr: return QVariant(int(Qt.AlignLeft | Qt.AlignVCenter)) if col == DUSTCOLS.Btc: return QVariant(int(Qt.AlignRight | Qt.AlignVCenter)) elif role == Qt.ForegroundRole: return QVariant(Colors.Foreground) elif role == Qt.FontRole: if col == DUSTCOLS.Btc: return GETFONT("Fixed") return QVariant()
def recordHistory(blkList, testHash): result = [] for blk in blkList: for tx in blk.txList: for txOut in tx.txOutList: if PAY_TO_PUBLIC_KEY == txOut.txOutType: # skip the push command at the beginning and OP_CHECKSIG at the end addr = txOut.script[1:-1] if binary_to_hex(hash160(addr)) == testHash: result.append(txOut) print blk.blkNum, coin2str(txOut.value, 4)
def data(self, index, role=Qt.DisplayRole): col = index.column() node = self.getNodeItem(index) if role == Qt.DisplayRole: if col == COL_NAME: return QVariant(node.treeNode.getName()) if col == COL_DESCR: try: return QVariant(node.treeNode.getComment()) except: pass if col == COL_VALUE: try: return QVariant( coin2str(node.treeNode.getBalance(), maxZeros=2)) except: pass if col == COL_TXOUTCOUNT: try: return QVariant(node.treeNode.getCount()) except: pass elif role == Qt.CheckStateRole: try: if col == COL_NAME: st = node.treeNode.checked() return st else: return QVariant() except: pass elif role == Qt.BackgroundRole: try: if node.treeNode.checked() != Qt.Unchecked: return QVariant(Colors.SlightBlue) except: pass elif role == Qt.FontRole: try: if node.treeNode.checked() != Qt.Unchecked: return GETFONT('Fixed', bold=True) except: pass return QVariant()
def data(self, index, role=Qt.DisplayRole): col = index.column() node = self.getNodeItem(index) if role==Qt.DisplayRole: if col == COL_NAME: return QVariant(node.treeNode.getName()) if col == COL_DESCR: try: return QVariant(node.treeNode.getComment()) except: pass if col == COL_VALUE: try: return QVariant(coin2str(node.treeNode.getBalance(), maxZeros=2)) except: pass if col == COL_TXOUTCOUNT: try: return QVariant(node.treeNode.getCount()) except: pass elif role==Qt.CheckStateRole: try: if col == COL_NAME: st = node.treeNode.checked() return st else: return QVariant() except: pass elif role==Qt.BackgroundRole: try: if node.treeNode.checked() != Qt.Unchecked: return QVariant(Colors.SlightBlue) except: pass elif role==Qt.FontRole: try: if node.treeNode.checked() != Qt.Unchecked: return GETFONT('Fixed', bold=True) except: pass return QVariant()
def updateLabelButtonText(self, txSize, flatFee, fee_byte): txSize = str(txSize) if txSize != 'N/A': txSize += " B" if flatFee != 'N/A': flatFee = coin2str(flatFee, maxZeros=0).strip() flatFee += " BTC" if not isinstance(fee_byte, str): fee_byte = '%.2f' % fee_byte lblStr = "Size: %s, Fee: %s" % (txSize, flatFee) if fee_byte != 'N/A': lblStr += " (%s sat/B)" % fee_byte self.lblButtonFee.setText(lblStr)
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 __init__(self, parent, utxo): self.utxo = utxo self.parent = parent if utxo.getTxHeight() == 2**32 - 1: self.name = QObject().tr("ZC id: %1 | TxOut: %2").arg(\ unicode(utxo.getTxIndex()), \ unicode(utxo.getTxOutIndex())) else: self.name = QObject().tr("Block: #%1 | Tx: #%2 | TxOut: #%3").arg(\ unicode(utxo.getTxHeight()), \ unicode(utxo.getTxIndex()), \ unicode(utxo.getTxOutIndex())) self.state = Qt.Checked if utxo.isChecked() == False: self.state = Qt.Unchecked h160 = utxo.getRecipientHash160() binAddr = utxo.getRecipientScrAddr() self.scrAddr = hash160_to_addrStr(h160, binAddr[0]) self.value = coin2str(utxo.getValue(), maxZeros=2)
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 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 prettyStr(self, indent=''): pstr = [indent] pstr.append(binary_to_hex(self.scrAddr[:8])) pstr.append(coin2str(self.val)) pstr.append(str(self.conf).rjust(8, ' ')) return ' '.join(pstr)
def __init__(self, main): def updateDustLimit(): try: self.dustTableModel.updateDustList( self.getSelectedWlt(), str2coin(self.dustLimitText.text())) self.beGoneDustButton.setEnabled( len(self.dustTableModel.dustTxOutlist) > 0) if self.dustTableModel.wlt: self.lblHeader.setText( tr("""<b>Dust Outputs for Wallet: %s</b>""" % self.dustTableModel.wlt.labelName)) except NegativeValueError: pass except TooMuchPrecisionError: pass except: LOGEXCEPT("Unexpected exception") pass 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() self.main = main self.lblHeader = QRichLabel( tr("""<b>Dust Outputs for Wallet: None Selected</b>"""), doWrap=False) self.beGoneDustButton = QPushButton("Remove Dust") self.beGoneDustButton.setEnabled(False) self.main.connect(self.beGoneDustButton, SIGNAL('clicked()'), sendDust) topRow = makeHorizFrame([self.lblHeader, 'stretch']) secondRow = makeHorizFrame([self.beGoneDustButton, 'stretch']) self.dustLimitLabel = QLabel("Max Dust Value (BTC): ") self.dustLimitText = QLineEdit() self.dustLimitText.setFont(GETFONT('Fixed')) self.dustLimitText.setMinimumWidth( tightSizeNChar(self.dustLimitText, 6)[0]) self.dustLimitText.setMaximumWidth( tightSizeNChar(self.dustLimitText, 12)[0]) self.dustLimitText.setAlignment(Qt.AlignRight) self.dustLimitText.setText(coin2str(DEFAULT_DUST_LIMIT)) self.main.connect(self.dustLimitText, SIGNAL('textChanged(QString)'), updateDustLimit) limitPanel = makeHorizFrame( [self.dustLimitLabel, self.dustLimitText, 'stretch']) self.dustTableModel = DustDisplayModel() self.dustTableView = QTableView() self.dustTableView.setModel(self.dustTableModel) self.dustTableView.setSelectionMode(QTableView.NoSelection) self.dustTableView.verticalHeader().setDefaultSectionSize(20) self.dustTableView.verticalHeader().hide() h = tightSizeNChar(self.dustTableView, 1)[1] self.dustTableView.setMinimumHeight(2 * (1.3 * h)) self.dustTableView.setMaximumHeight(10 * (1.3 * h)) initialColResize(self.dustTableView, [100, .7, .3]) self.dustTableView.setContextMenuPolicy(Qt.CustomContextMenu) self.lblTxioInfo = QRichLabel('') self.lblTxioInfo.setMinimumWidth( tightSizeNChar(self.lblTxioInfo, 30)[0]) self.main.connect(self.main.walletsView, SIGNAL('clicked(QModelIndex)'), updateDustLimit) self.dustBGoneFrame = makeVertFrame( [topRow, secondRow, limitPanel, self.dustTableView, 'stretch']) # Now set the scrollarea widget to the layout self.tabToDisplay = QScrollArea() self.tabToDisplay.setWidgetResizable(True) self.tabToDisplay.setWidget(self.dustBGoneFrame)
def __init__(self, parent, main, cs_callback, get_csstate): super(FeeSelectionDialog, self).__init__(parent, main) #Button Label self.lblButtonFee = QLabelButton("") #get default values flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE) flatFee = coin2str(flatFee, maxZeros=1).strip() fee_byte = str(self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE)) blocksToConfirm = self.main.getSettingOrSetDefault(\ "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM) feeStrategy = str(self.main.getSettingOrSetDefault(\ "Default_FeeByte_Strategy", FEEBYTE_CONSERVATIVE)) self.coinSelectionCallback = cs_callback self.getCoinSelectionState = get_csstate self.validAutoFee = True isSmartFee = True try: feeEstimate, isSmartFee, errorMsg = self.getFeeByteFromNode(blocksToConfirm, feeStrategy) except: feeEstimate = "N/A" self.validAutoFee = False defaultCheckState = \ self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE) #flat free def setFlatFee(): def callbck(): return self.selectType('FlatFee') return callbck def updateLbl(): self.updateCoinSelection() self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)")) self.edtFeeAmt = QLineEdit(flatFee) self.edtFeeAmt.setFont(GETFONT('Fixed')) self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0]) self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0]) self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee()) self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl) frmFlatFee = QFrame() frmFlatFee.setFrameStyle(STYLE_RAISED) layoutFlatFee = QGridLayout() layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1) layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1) frmFlatFee.setLayout(layoutFlatFee) #fee/byte def setFeeByte(): def callbck(): return self.selectType('FeeByte') return callbck self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)")) self.edtFeeByte = QLineEdit(fee_byte) self.edtFeeByte.setFont(GETFONT('Fixed')) self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0]) self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0]) self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte()) self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl) frmFeeByte = QFrame() frmFeeByte.setFrameStyle(STYLE_RAISED) layoutFeeByte = QGridLayout() layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1) layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1) frmFeeByte.setLayout(layoutFeeByte) #auto fee/byte if isSmartFee: frmAutoFeeByte = self.setupSmartAutoFeeByteUI(\ feeEstimate, blocksToConfirm, feeStrategy) else: frmAutoFeeByte = self.setupLegacyAutoFeeByteUI(\ feeEstimate, blocksToConfirm) #adjust and close self.btnClose = QPushButton(self.tr('Close')) self.connect(self.btnClose, SIGNAL('clicked()'), self.accept) self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy')) self.checkBoxAdjust.setChecked(\ self.main.getSettingOrSetDefault('AdjustFee', True)) self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl) frmClose = makeHorizFrame(\ [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE) #main layout layout = QGridLayout() layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4) layout.addWidget(frmFeeByte, 2, 0, 1, 4) layout.addWidget(frmFlatFee, 4, 0, 1, 4) layout.addWidget(frmClose, 5, 0, 1, 4) self.setLayout(layout) self.setWindowTitle(self.tr('Select Fee Type')) self.selectType(defaultCheckState) self.setFocus()
def __init__(self, parent, main, cs_callback, get_csstate): super(FeeSelectionDialog, self).__init__(parent, main) #Button Label self.lblButtonFee = QLabelButton("") #get default values flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE) flatFee = coin2str(flatFee, maxZeros=1).strip() fee_byte = str( self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE)) blocksToConfirm = self.main.getSettingOrSetDefault(\ "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM) feeStrategy = str(self.main.getSettingOrSetDefault(\ "Default_FeeByte_Strategy", FEEBYTE_CONSERVATIVE)) self.coinSelectionCallback = cs_callback self.getCoinSelectionState = get_csstate self.validAutoFee = True isSmartFee = True try: feeEstimate, isSmartFee, errorMsg = self.getFeeByteFromNode( blocksToConfirm, feeStrategy) except: feeEstimate = "N/A" self.validAutoFee = False defaultCheckState = \ self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE) #flat free def setFlatFee(): def callbck(): return self.selectType('FlatFee') return callbck def updateLbl(): self.updateCoinSelection() self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)")) self.edtFeeAmt = QLineEdit(flatFee) self.edtFeeAmt.setFont(GETFONT('Fixed')) self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0]) self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0]) self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee()) self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl) frmFlatFee = QFrame() frmFlatFee.setFrameStyle(STYLE_RAISED) layoutFlatFee = QGridLayout() layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1) layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1) frmFlatFee.setLayout(layoutFlatFee) #fee/byte def setFeeByte(): def callbck(): return self.selectType('FeeByte') return callbck self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)")) self.edtFeeByte = QLineEdit(fee_byte) self.edtFeeByte.setFont(GETFONT('Fixed')) self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0]) self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0]) self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte()) self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl) frmFeeByte = QFrame() frmFeeByte.setFrameStyle(STYLE_RAISED) layoutFeeByte = QGridLayout() layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1) layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1) frmFeeByte.setLayout(layoutFeeByte) #auto fee/byte if isSmartFee: frmAutoFeeByte = self.setupSmartAutoFeeByteUI(\ feeEstimate, blocksToConfirm, feeStrategy) else: frmAutoFeeByte = self.setupLegacyAutoFeeByteUI(\ feeEstimate, blocksToConfirm) #adjust and close self.btnClose = QPushButton(self.tr('Close')) self.connect(self.btnClose, SIGNAL('clicked()'), self.accept) self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy')) self.checkBoxAdjust.setChecked(\ self.main.getSettingOrSetDefault('AdjustFee', True)) self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl) frmClose = makeHorizFrame(\ [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE) #main layout layout = QGridLayout() layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4) layout.addWidget(frmFeeByte, 2, 0, 1, 4) layout.addWidget(frmFlatFee, 4, 0, 1, 4) layout.addWidget(frmClose, 5, 0, 1, 4) self.setLayout(layout) self.setWindowTitle(self.tr('Select Fee Type')) self.selectType(defaultCheckState) self.setFocus()
def prettyStr(self, indent=''): pstr = [indent] pstr.append(binary_to_hex(self.scrAddr[:8])) pstr.append(coin2str(self.val)) pstr.append(str(self.conf).rjust(8,' ')) return ' '.join(pstr)
def __init__(self, main): def updateDustLimit(): try: self.dustTableModel.updateDustList(self.getSelectedWlt(), str2coin(self.dustLimitText.text())) self.beGoneDustButton.setEnabled(len(self.dustTableModel.dustTxOutlist)>0) if self.dustTableModel.wlt: self.lblHeader.setText(tr("""<b>Dust Outputs for Wallet: %s</b>""" % self.dustTableModel.wlt.labelName)) except NegativeValueError: pass except TooMuchPrecisionError: pass except: LOGEXCEPT("Unexpected exception") pass 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() self.main = main self.lblHeader = QRichLabel(tr("""<b>Dust Outputs for Wallet: None Selected</b>"""), doWrap=False) self.beGoneDustButton = QPushButton("Remove Dust") self.beGoneDustButton.setEnabled(False) self.main.connect(self.beGoneDustButton, SIGNAL('clicked()'), sendDust) topRow = makeHorizFrame([self.lblHeader,'stretch']) secondRow = makeHorizFrame([self.beGoneDustButton, 'stretch']) self.dustLimitLabel = QLabel("Max Dust Value (GRS): ") self.dustLimitText = QLineEdit() self.dustLimitText.setFont(GETFONT('Fixed')) self.dustLimitText.setMinimumWidth(tightSizeNChar(self.dustLimitText, 6)[0]) self.dustLimitText.setMaximumWidth(tightSizeNChar(self.dustLimitText, 12)[0]) self.dustLimitText.setAlignment(Qt.AlignRight) self.dustLimitText.setText(coin2str(DEFAULT_DUST_LIMIT)) self.main.connect(self.dustLimitText, SIGNAL('textChanged(QString)'), updateDustLimit) limitPanel = makeHorizFrame([self.dustLimitLabel, self.dustLimitText, 'stretch']) self.dustTableModel = DustDisplayModel() self.dustTableView = QTableView() self.dustTableView.setModel(self.dustTableModel) self.dustTableView.setSelectionMode(QTableView.NoSelection) self.dustTableView.verticalHeader().setDefaultSectionSize(20) self.dustTableView.verticalHeader().hide() h = tightSizeNChar(self.dustTableView, 1)[1] self.dustTableView.setMinimumHeight(2 * (1.3 * h)) self.dustTableView.setMaximumHeight(10 * (1.3 * h)) initialColResize(self.dustTableView, [100, .7, .3]) self.dustTableView.setContextMenuPolicy(Qt.CustomContextMenu) self.lblTxioInfo = QRichLabel('') self.lblTxioInfo.setMinimumWidth(tightSizeNChar(self.lblTxioInfo, 30)[0]) self.main.connect(self.main.walletsView, SIGNAL('clicked(QModelIndex)'), updateDustLimit) self.dustBGoneFrame = makeVertFrame([topRow, secondRow, limitPanel, self.dustTableView, 'stretch']) # Now set the scrollarea widget to the layout self.tabToDisplay = QScrollArea() self.tabToDisplay.setWidgetResizable(True) self.tabToDisplay.setWidget(self.dustBGoneFrame)
def __init__(self, parent, main, cs_callback, get_csstate): super(FeeSelectionDialog, self).__init__(parent, main) #Button Label self.lblButtonFee = QLabelButton("") #get default values flatFee = self.main.getSettingOrSetDefault("Default_Fee", MIN_TX_FEE) flatFee = coin2str(flatFee, maxZeros=1).strip() fee_byte = str(self.main.getSettingOrSetDefault("Default_FeeByte", MIN_FEE_BYTE)) blocksToConfirm = self.main.getSettingOrSetDefault(\ "Default_FeeByte_BlocksToConfirm", NBLOCKS_TO_CONFIRM) self.coinSelectionCallback = cs_callback self.getCoinSelectionState = get_csstate self.validAutoFee = True try: autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0) except: autoFee_byte = "N/A" self.validAutoFee = False defaultCheckState = \ self.main.getSettingOrSetDefault("FeeOption", DEFAULT_FEE_TYPE) #flat free def setFlatFee(): def callbck(): return self.selectType('FlatFee') return callbck def updateLbl(): self.updateCoinSelection() self.radioFlatFee = QRadioButton(self.tr("Flat Fee (BTC)")) self.edtFeeAmt = QLineEdit(flatFee) self.edtFeeAmt.setFont(GETFONT('Fixed')) self.edtFeeAmt.setMinimumWidth(tightSizeNChar(self.edtFeeAmt, 6)[0]) self.edtFeeAmt.setMaximumWidth(tightSizeNChar(self.edtFeeAmt, 12)[0]) self.connect(self.radioFlatFee, SIGNAL('clicked()'), setFlatFee()) self.connect(self.edtFeeAmt, SIGNAL('textChanged(QString)'), updateLbl) frmFlatFee = QFrame() frmFlatFee.setFrameStyle(STYLE_RAISED) layoutFlatFee = QGridLayout() layoutFlatFee.addWidget(self.radioFlatFee, 0, 0, 1, 1) layoutFlatFee.addWidget(self.edtFeeAmt, 0, 1, 1, 1) frmFlatFee.setLayout(layoutFlatFee) #fee/byte def setFeeByte(): def callbck(): return self.selectType('FeeByte') return callbck self.radioFeeByte = QRadioButton(self.tr("Fee/Byte (Satoshi/Byte)")) self.edtFeeByte = QLineEdit(fee_byte) self.edtFeeByte.setFont(GETFONT('Fixed')) self.edtFeeByte.setMinimumWidth(tightSizeNChar(self.edtFeeByte, 6)[0]) self.edtFeeByte.setMaximumWidth(tightSizeNChar(self.edtFeeByte, 12)[0]) self.connect(self.radioFeeByte, SIGNAL('clicked()'), setFeeByte()) self.connect(self.edtFeeByte, SIGNAL('textChanged(QString)'), updateLbl) frmFeeByte = QFrame() frmFeeByte.setFrameStyle(STYLE_RAISED) layoutFeeByte = QGridLayout() layoutFeeByte.addWidget(self.radioFeeByte, 0, 0, 1, 1) layoutFeeByte.addWidget(self.edtFeeByte, 0, 1, 1, 1) frmFeeByte.setLayout(layoutFeeByte) #auto fee/byte def setAutoFeeByte(): def callbck(): return self.selectType('Auto') return callbck radioButtonTxt = self.tr("Fee rate from node (sat/Byte): ") if not self.validAutoFee: radioButtonTxt = self.tr("Failed to fetch fee/byte from node") self.radioAutoFeeByte = QRadioButton(radioButtonTxt) self.lblAutoFeeByte = QLabel(autoFee_byte) self.lblAutoFeeByte.setFont(GETFONT('Fixed')) self.lblAutoFeeByte.setMinimumWidth(tightSizeNChar(self.lblAutoFeeByte, 6)[0]) self.lblAutoFeeByte.setMaximumWidth(tightSizeNChar(self.lblAutoFeeByte, 12)[0]) self.sliderAutoFeeByte = QSlider(Qt.Horizontal, self) self.sliderAutoFeeByte.setMinimum(2) self.sliderAutoFeeByte.setMaximum(6) self.sliderAutoFeeByte.setValue(blocksToConfirm) self.lblSlider = QLabel() def getSliderLabelTxt(): return self.tr("Blocks to confirm: %1").arg(\ unicode(self.sliderAutoFeeByte.value())) def updateAutoFeeByte(): blocksToConfirm = self.sliderAutoFeeByte.value() try: autoFee_byte = str(estimateFee(blocksToConfirm) / 1000.0) except: autoFee_byte = "N/A" self.lblSlider.setText(getSliderLabelTxt()) self.lblAutoFeeByte.setText(autoFee_byte) updateLbl() self.lblSlider.setText(getSliderLabelTxt()) self.connect(self.radioAutoFeeByte, SIGNAL('clicked()'), setAutoFeeByte()) self.sliderAutoFeeByte.valueChanged.connect(updateAutoFeeByte) self.sliderAutoFeeByte.setEnabled(False) frmAutoFeeByte = QFrame() frmAutoFeeByte.setFrameStyle(STYLE_RAISED) layoutAutoFeeByte = QGridLayout() layoutAutoFeeByte.addWidget(self.radioAutoFeeByte, 0, 0, 1, 1) layoutAutoFeeByte.addWidget(self.lblAutoFeeByte, 0, 1, 1, 1) layoutAutoFeeByte.addWidget(self.lblSlider, 1, 0, 1, 2) layoutAutoFeeByte.addWidget(self.sliderAutoFeeByte, 2, 0, 1, 2) frmAutoFeeByte.setLayout(layoutAutoFeeByte) if not self.validAutoFee: frmAutoFeeByte.setEnabled(False) #adjust and close self.btnClose = QPushButton(self.tr('Close')) self.connect(self.btnClose, SIGNAL('clicked()'), self.accept) self.checkBoxAdjust = QCheckBox(self.tr('Adjust fee/byte for privacy')) self.checkBoxAdjust.setChecked(\ self.main.getSettingOrSetDefault('AdjustFee', True)) self.connect(self.checkBoxAdjust, SIGNAL('clicked()'), updateLbl) frmClose = makeHorizFrame(\ [self.checkBoxAdjust, 'Stretch', self.btnClose], STYLE_NONE) #main layout layout = QGridLayout() layout.addWidget(frmAutoFeeByte, 0, 0, 1, 4) layout.addWidget(frmFeeByte, 2, 0, 1, 4) layout.addWidget(frmFlatFee, 4, 0, 1, 4) layout.addWidget(frmClose, 5, 0, 1, 4) self.setLayout(layout) self.setWindowTitle(self.tr('Select Fee Type')) self.selectType(defaultCheckState) self.setFocus()
while f.tell() < fSize: blk = getNextBlock(f) if blk != None: addBlockToPrunedTree(prunedTree, blk) def getPrunedTree(): prunedTree = {} for blkFileName in blkFileNameList: addFileToPrunedTree(prunedTree, blkFileName) return prunedTree print "Block Chain Parser HW #4 Exercise #3: " prunedTree = getPrunedTree() print print "Unspent txOuts: ", len(prunedTree.keys()) print "Total unspent bitcoins: ", coin2str(balance, 4), "(" + 50*(blkCounter+1) + ")" treeSize = 0 for key,value in prunedTree.iteritems(): treeSize += len(value.txOut.script)+45 print "Tree Size: ", treeSize