def pprint(self, nIndent=0, endian=BIGENDIAN): indstr = indent*nIndent print indstr + 'BlockHeader:' print indstr + indent + 'Version: ', self.version print indstr + indent + 'ThisHash: ', binary_to_hex( self.theHash, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'PrevBlock: ', binary_to_hex(self.prevBlkHash, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'MerkRoot: ', binary_to_hex(self.merkleRoot, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'Timestamp: ', self.timestamp fltDiff = binaryBits_to_difficulty(self.diffBits) print indstr + indent + 'Difficulty:', fltDiff, '('+binary_to_hex(self.diffBits)+')' print indstr + indent + 'Nonce: ', self.nonce if not self.blkHeight==UNINITIALIZED: print indstr + indent + 'BlkHeight: ', self.blkHeight if not self.blkHeight==UNINITIALIZED: print indstr + indent + 'BlkFileLoc:', self.fileByteLoc if not self.nextBlkHash==UNINITIALIZED: #print indstr + indent + 'NextBlock: ', binary_to_hex(self.nextBlkHash) print indstr + indent + 'NextBlock: ', self.nextBlkHash if not self.numTx==UNINITIALIZED: print indstr + indent + 'NumTx: ', self.numTx if not self.intDifficult==UNINITIALIZED: print indstr + indent + 'Difficulty:', self.intDifficult if not self.sumDifficult==UNINITIALIZED: print indstr + indent + 'DiffSum: ', self.sumDifficult
def pprint(self, nIndent=0, endian=BIGENDIAN): indstr = indent * nIndent print indstr + 'BlockHeader:' print indstr + indent + 'Version: ', self.version print indstr + indent + 'ThisHash: ', binary_to_hex( self.theHash, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'PrevBlock: ', binary_to_hex(self.prevBlkHash, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'MerkRoot: ', binary_to_hex(self.merkleRoot, endOut=endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'Timestamp: ', self.timestamp fltDiff = binaryBits_to_difficulty(self.diffBits) print indstr + indent + 'Difficulty:', fltDiff, '(' + binary_to_hex( self.diffBits) + ')' print indstr + indent + 'Nonce: ', self.nonce if not self.blkHeight == UNINITIALIZED: print indstr + indent + 'BlkHeight: ', self.blkHeight if not self.blkHeight == UNINITIALIZED: print indstr + indent + 'BlkFileLoc:', self.fileByteLoc if not self.nextBlkHash == UNINITIALIZED: #print indstr + indent + 'NextBlock: ', binary_to_hex(self.nextBlkHash) print indstr + indent + 'NextBlock: ', self.nextBlkHash if not self.numTx == UNINITIALIZED: print indstr + indent + 'NumTx: ', self.numTx if not self.intDifficult == UNINITIALIZED: print indstr + indent + 'Difficulty:', self.intDifficult if not self.sumDifficult == UNINITIALIZED: print indstr + indent + 'DiffSum: ', self.sumDifficult
def callSplitSecret(self, secretHex, M, N, nbytes=1): secret = hex_to_binary(secretHex) print '\nSplitting secret into %d-of-%d: secret=%s' % (M,N,secretHex) tstart = RightNow() out = SplitSecret(secret, M, N) tsplit = RightNow() - tstart print 'Fragments:' for i in range(len(out)): x = binary_to_hex(out[i][0]) y = binary_to_hex(out[i][1]) print ' Fragment %d: [%s, %s]' % (i+1,x,y) trecon = 0 print 'Reconstructing secret from various subsets of fragments...' for i in range(10): shuffle(out) tstart = RightNow() reconstruct = ReconstructSecret(out, M, nbytes) trecon += RightNow() - tstart print ' The reconstructed secret is:', binary_to_hex(reconstruct) self.assertEqual(binary_to_hex(reconstruct), secretHex) print 'Splitting secret took: %0.5f sec' % tsplit print 'Reconstructing takes: %0.5f sec' % (trecon/10) # Running tests with "python <module name>" will NOT work for any Armory tests # You must run tests with "python -m unittest <module name>" or run all tests with "python -m unittest discover" # if __name__ == "__main__": # unittest.main()
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 pprint(self, nIndent=0): indstr = indent*nIndent print '' print indstr + 'Message(getheaders):' print indstr + indent + 'HashList(s) :' + binary_to_hex(self.hashList[0]) for i in range(1,len(self.hashList)): print indstr + indent + ' :' + binary_to_hex(self.hashList[i]) print indstr + indent + 'HashStop :' + binary_to_hex(self.hashStop)
def printMerkleTree(self, reverseHash=False, indent=''): print indent + 'Printing Merkle Tree:' if reverseHash: print indent + '(hashes will be reversed, like shown on BlockExplorer.com)' root = self.getMerkleRoot() print indent + 'Merkle Root:', binary_to_hex(root) for h in self.merkleTree: phash = binary_to_hex(h) if not reverseHash else binary_to_hex(h, endOut=BIGENDIAN) print indent + '\t' + phash
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 processMessage(self, msg): # TODO: when I start expanding this class to be more versatile, # I'll consider chaining/setting callbacks from the calling # application. For now, it's pretty static. #msg.payload.pprint(nIndent=2) if msg.cmd=='inv': invobj = msg.payload getdataMsg = PyMessage('getdata') for inv in invobj.invList: if inv[0]==MSG_INV_BLOCK: if self.factory.bdm and (self.factory.bdm.getBDMState()=='Scanning' or \ self.factory.bdm.hasHeaderWithHash(inv[1])): continue getdataMsg.payload.invList.append(inv) if inv[0]==MSG_INV_TX: if self.factory.bdm and (self.factory.bdm.getBDMState()=='Scanning' or \ self.factory.bdm.hasTxWithHash(inv[1])): continue getdataMsg.payload.invList.append(inv) # Now send the full request if self.factory.bdm and not self.factory.bdm.getBDMState()=='Scanning': self.sendMessage(getdataMsg) if msg.cmd=='tx': pytx = msg.payload.tx self.factory.func_newTx(pytx) elif msg.cmd=='inv': invList = msg.payload.invList self.factory.func_inv(invList) elif msg.cmd=='block': pyHeader = msg.payload.header pyTxList = msg.payload.txList LOGINFO('Received new block. %s', binary_to_hex(pyHeader.getHash(), BIGENDIAN)) self.factory.func_newBlock(pyHeader, pyTxList)
def testDumpprivkey(self): testPrivKey = self.privKey.toBinStr() hash160 = convertKeyDataToAddress(testPrivKey) addr58 = hash160_to_addrStr(hash160) # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception result = self.jsonServer.jsonrpc_dumpprivkey('bogus', 'hex') self.assertEqual(result['Error Type'],'InvalidBitcoinAddress') result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex') self.assertEqual(result['Error Type'],'PrivateKeyNotFound') # verify that the first private key can be found firstHash160 = self.wallet.getNextUnusedAddress().getAddr160() firstAddr58 = hash160_to_addrStr(firstHash160) actualPrivateKeyHex = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \ 'hex') actualPrivateKeyB58 = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \ 'base58') self.privKey = self.wallet.getAddrByHash160(firstHash160).serializePlainPrivateKey() expectedPrivateKeyHex = binary_to_hex(self.privKey) expectedPrivateKeyB58 = privKey_to_base58(self.privKey) self.assertEqual(actualPrivateKeyHex, expectedPrivateKeyHex) self.assertEqual(actualPrivateKeyB58, expectedPrivateKeyB58) # Verify that a locked wallet Raises WalletUnlockNeeded Exception kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1) self.wallet.changeKdfParams(*kdfParams) self.wallet.changeWalletEncryption( securePassphrase=self.passphrase ) self.wallet.lock() result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex') self.assertEqual(result['Error Type'],'WalletUnlockNeeded')
def pprint(self, nIndent=0): indstr = indent*nIndent print '' print indstr + 'Message(getdata):' for inv in self.invList: print indstr + indent + ('BLOCK: ' if inv[0]==2 else 'TX : ') + \ binary_to_hex(inv[1])
def testDumpprivkey(self): testPrivKey = self.privKey.toBinStr() hash160 = convertKeyDataToAddress(testPrivKey) addr58 = hash160_to_addrStr(hash160) # Verify that a bogus addrss Raises InvalidBitcoinAddress Exception result = self.jsonServer.jsonrpc_dumpprivkey('bogus', 'hex') self.assertEqual(result['Error Type'], 'InvalidBitcoinAddress') result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex') self.assertEqual(result['Error Type'], 'PrivateKeyNotFound') # verify that the first private key can be found firstHash160 = self.wallet.getNextUnusedAddress().getAddr160() firstAddr58 = hash160_to_addrStr(firstHash160) actualPrivateKeyHex = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \ 'hex') actualPrivateKeyB58 = self.jsonServer.jsonrpc_dumpprivkey(firstAddr58, \ 'base58') self.privKey = self.wallet.getAddrByHash160( firstHash160).serializePlainPrivateKey() expectedPrivateKeyHex = binary_to_hex(self.privKey) expectedPrivateKeyB58 = privKey_to_base58(self.privKey) self.assertEqual(actualPrivateKeyHex, expectedPrivateKeyHex) self.assertEqual(actualPrivateKeyB58, expectedPrivateKeyB58) # Verify that a locked wallet Raises WalletUnlockNeeded Exception kdfParams = self.wallet.computeSystemSpecificKdfParams(0.1) self.wallet.changeKdfParams(*kdfParams) self.wallet.changeWalletEncryption(securePassphrase=self.passphrase) self.wallet.lock() result = self.jsonServer.jsonrpc_dumpprivkey(addr58, 'hex') self.assertEqual(result['Error Type'], 'WalletUnlockNeeded')
def pprint(self, nIndent=0): indstr = indent * nIndent print '' print indstr + 'Message(getdata):' for inv in self.invList: print indstr + indent + ('BLOCK: ' if inv[0]==2 else 'TX : ') + \ binary_to_hex(inv[1])
def pprint(self, nIndent=0, endian=BIGENDIAN): indstr = indent*nIndent print indstr + 'BlockData:' print indstr + indent + 'MerkleRoot: ', binary_to_hex(self.getMerkleRoot(), endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'NumTx: ', self.numTx for tx in self.txList: tx.pprint(nIndent+1, endian=endian)
def pprint(self, nIndent=0): indstr = indent*nIndent print '' print indstr + 'Bitcoin-Network-Message -- ' + self.cmd.upper() print indstr + indent + 'Magic: ' + binary_to_hex(self.magic) print indstr + indent + 'Command: ' + self.cmd print indstr + indent + 'Payload: ' + str(len(self.payload.serialize())) + ' bytes' self.payload.pprint(nIndent+1)
def computeMerkleRoot(lst, merkleCounter=0): # print binary_to_hex(lst[-1]) if merkleCounter: for item in lst: print merkleCounter, binary_to_hex(item) merkleCounter += 1 print return computeMerkleRoot(dHashList(foldList(lst)), merkleCounter) if len(lst) > 1 else lst[0]
def pprint(self, nIndent=0, endian=BIGENDIAN): indstr = indent * nIndent print indstr + 'BlockData:' print indstr + indent + 'MerkleRoot: ', binary_to_hex(self.getMerkleRoot(), endian), \ '(BE)' if endian==BIGENDIAN else '(LE)' print indstr + indent + 'NumTx: ', self.numTx for tx in self.txList: tx.pprint(nIndent + 1, endian=endian)
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 testSerializeUnserialize(self): tx1 = PyTx().unserialize(tx1raw) tx2 = PyTx().unserialize(BinaryUnpacker(tx2raw)) tx1again = tx1.serialize() tx2again = tx2.serialize() self.assertEqual(tx1again, tx1raw) self.assertEqual(tx2again, tx2raw) blk = PyBlock().unserialize(hex_to_binary(hexBlock)) blockReHex = binary_to_hex(blk.serialize()) self.assertEqual(hexBlock, blockReHex) binRoot = blk.blockData.getMerkleRoot() self.assertEqual(blk.blockHeader.merkleRoot, blk.blockData.merkleRoot)
def testSerializeUnserialize(self): tx1 = PyTx().unserialize(tx1raw) tx2 = PyTx().unserialize(BinaryUnpacker(tx2raw)) tx1again = tx1.serialize() tx2again = tx2.serialize() self.assertEqual(tx1again, tx1raw) self.assertEqual(tx2again, tx2raw) blk = PyBlock().unserialize( hex_to_binary(hexBlock) ) blockReHex = binary_to_hex(blk.serialize()) self.assertEqual(hexBlock, blockReHex) binRoot = blk.blockData.getMerkleRoot() self.assertEqual(blk.blockHeader.merkleRoot, blk.blockData.merkleRoot)
def callSplitSecret(self, secretHex, M, N, nbytes=1): secret = hex_to_binary(secretHex) print '\nSplitting secret into %d-of-%d: secret=%s' % (M,N,secretHex) tstart = RightNow() out = SplitSecret(secret, M, N) tsplit = RightNow() - tstart print 'Fragments:' for i in range(len(out)): x = binary_to_hex(out[i][0]) y = binary_to_hex(out[i][1]) print ' Fragment %d: [%s, %s]' % (i+1,x,y) trecon = 0 print 'Reconstructing secret from various subsets of fragments...' for i in range(10): shuffle(out) tstart = RightNow() reconstruct = ReconstructSecret(out, M, nbytes) trecon += RightNow() - tstart print ' The reconstructed secret is:', binary_to_hex(reconstruct) self.assertEqual(binary_to_hex(reconstruct), secretHex) print 'Splitting secret took: %0.5f sec' % tsplit print 'Reconstructing takes: %0.5f sec' % (trecon/10)
def testCreateTx(self): addrA = PyBtcAddress().createFromPrivateKey(hex_to_int('aa' * 32)) addrB = PyBtcAddress().createFromPrivateKey(hex_to_int('bb' * 32)) # This TxIn will be completely ignored, so it can contain garbage txinA = PyTxIn() txinA.outpoint = PyOutPoint().unserialize(hex_to_binary('00'*36)) txinA.binScript = hex_to_binary('99'*4) txinA.intSeq = hex_to_int('ff'*4) # test binary unpacker in unserialize testTxIn = PyTxIn().unserialize(txinA.serialize()) self.assertEqual(txinA.getScript(), testTxIn.getScript()) self.assertEqual(txinA.intSeq, testTxIn.intSeq) self.assertEqual(txinA.outpoint.txHash, testTxIn.outpoint.txHash) txoutA = PyTxOut() txoutA.value = 50 * ONE_BTC txoutA.binScript = '\x76\xa9\x14' + addrA.getAddr160() + '\x88\xac' # Test pprint print '\nTest pretty print PyTxIn, expect PrevTXHash all 0s' testTxIn.pprint() # test binary unpacker in unserialize testTxOut = PyTxOut().unserialize(txoutA.serialize()) self.assertEqual(txoutA.getScript(), testTxOut.getScript()) self.assertEqual(txoutA.value, testTxOut.getValue()) # Test pprint print '\nTest pretty print PyTxOut' testTxOut.pprint() tx1 = PyTx() tx1.version = 1 tx1.numInputs = 1 tx1.inputs = [txinA] tx1.numOutputs = 1 tx1.outputs = [txoutA] tx1.locktime = 0 tx1hash = tx1.getHash() recipientList = tx1.makeRecipientsList() self.assertEqual(len(recipientList), 1) self.assertEqual(recipientList[0][0], 0) self.assertEqual(recipientList[0][1], 50 * ONE_BTC) self.assertEqual(tx1.getHashHex(), binary_to_hex(tx1hash)) # Creating transaction to send coins from A to B tx2 = PyCreateAndSignTx_old( [[ addrA, tx1, 0 ]], [[addrB, 50*ONE_BTC]]) psp = PyScriptProcessor() psp.setTxObjects(tx1, tx2, 0) self.assertTrue(psp.verifyTransactionValid())
def testCreateTx(self): addrA = PyBtcAddress().createFromPrivateKey(hex_to_int('aa' * 32)) addrB = PyBtcAddress().createFromPrivateKey(hex_to_int('bb' * 32)) # This TxIn will be completely ignored, so it can contain garbage txinA = PyTxIn() txinA.outpoint = PyOutPoint().unserialize(hex_to_binary('00' * 36)) txinA.binScript = hex_to_binary('99' * 4) txinA.intSeq = hex_to_int('ff' * 4) # test binary unpacker in unserialize testTxIn = PyTxIn().unserialize(txinA.serialize()) self.assertEqual(txinA.getScript(), testTxIn.getScript()) self.assertEqual(txinA.intSeq, testTxIn.intSeq) self.assertEqual(txinA.outpoint.txHash, testTxIn.outpoint.txHash) txoutA = PyTxOut() txoutA.value = 50 * ONE_BTC txoutA.binScript = '\x76\xa9\x14' + addrA.getAddr160() + '\x88\xac' # Test pprint print '\nTest pretty print PyTxIn, expect PrevTXHash all 0s' testTxIn.pprint() # test binary unpacker in unserialize testTxOut = PyTxOut().unserialize(txoutA.serialize()) self.assertEqual(txoutA.getScript(), testTxOut.getScript()) self.assertEqual(txoutA.value, testTxOut.getValue()) # Test pprint print '\nTest pretty print PyTxOut' testTxOut.pprint() tx1 = PyTx() tx1.version = 1 tx1.numInputs = 1 tx1.inputs = [txinA] tx1.numOutputs = 1 tx1.outputs = [txoutA] tx1.locktime = 0 tx1hash = tx1.getHash() recipientList = tx1.makeRecipientsList() self.assertEqual(len(recipientList), 1) self.assertEqual(recipientList[0][0], 0) self.assertEqual(recipientList[0][1], 50 * ONE_BTC) self.assertEqual(tx1.getHashHex(), binary_to_hex(tx1hash)) # Creating transaction to send coins from A to B tx2 = PyCreateAndSignTx_old([[addrA, tx1, 0]], [[addrB, 50 * ONE_BTC]]) psp = PyScriptProcessor() psp.setTxObjects(tx1, tx2, 0) self.assertTrue(psp.verifyTransactionValid())
def processMessage(self, msg): # TODO: when I start expanding this class to be more versatile, # I'll consider chaining/setting callbacks from the calling # application. For now, it's pretty static. #msg.payload.pprint(nIndent=2) if msg.cmd == 'inv': invobj = msg.payload getdataMsg = PyMessage('getdata') for inv in invobj.invList: if inv[0] == MSG_INV_BLOCK: if self.factory.bdm and (self.factory.bdm.getState()==BDM_SCANNING or \ self.factory.bdm.bdv().blockchain().hasHeaderWithHash(inv[1])): continue getdataMsg.payload.invList.append(inv) if inv[0] == MSG_INV_TX: if not self.factory.bdm or self.factory.bdm.getState( ) != BDM_BLOCKCHAIN_READY: continue getdataMsg.payload.invList.append(inv) # Now send the full request if self.factory.bdm and not self.factory.bdm.getState( ) == BDM_SCANNING: self.sendMessage(getdataMsg) if msg.cmd == 'tx': pytx = msg.payload.tx self.factory.func_newTx(pytx) elif msg.cmd == 'inv': invList = msg.payload.invList self.factory.func_inv(invList) elif msg.cmd == 'block': pyHeader = msg.payload.header pyTxList = msg.payload.txList LOGINFO('Received new block. %s', binary_to_hex(pyHeader.getHash(), BIGENDIAN)) self.factory.func_newBlock(pyHeader, pyTxList) elif msg.cmd == 'alert': # store the alert in our map id = msg.payload.uniqueID if not self.alerts.get(id): self.alerts[id] = msg.payload LOGWARN("received alert: %s" % msg.payload.statusBar)
def processMessage(self, msg): # TODO: when I start expanding this class to be more versatile, # I'll consider chaining/setting callbacks from the calling # application. For now, it's pretty static. #msg.payload.pprint(nIndent=2) if msg.cmd=='inv': invobj = msg.payload getdataMsg = PyMessage('getdata') for inv in invobj.invList: if inv[0]==MSG_INV_BLOCK: if self.factory.bdm and (self.factory.bdm.getState()==BDM_SCANNING or \ self.factory.bdm.bdv().blockchain().hasHeaderWithHash(inv[1])): continue getdataMsg.payload.invList.append(inv) if inv[0]==MSG_INV_TX: if not self.factory.bdm or self.factory.bdm.getState()!=BDM_BLOCKCHAIN_READY: continue getdataMsg.payload.invList.append(inv) # Now send the full request if self.factory.bdm and not self.factory.bdm.getState()==BDM_SCANNING: self.sendMessage(getdataMsg) if msg.cmd=='tx': pytx = msg.payload.tx self.factory.func_newTx(pytx) elif msg.cmd=='inv': invList = msg.payload.invList self.factory.func_inv(invList) elif msg.cmd=='block': pyHeader = msg.payload.header pyTxList = msg.payload.txList LOGINFO('Received new block. %s', binary_to_hex(pyHeader.getHash(), BIGENDIAN)) self.factory.func_newBlock(pyHeader, pyTxList) elif msg.cmd=='alert': # store the alert in our map id = msg.payload.uniqueID if not self.alerts.get(id): self.alerts[id] = msg.payload LOGWARN("received alert: %s" % msg.payload.statusBar)
def decodeSigCollect(): print "Paste your TXSIGCOLLECT below and press <enter>:\n" stopAt = "================================================================" SIGCOLLECT = "" for line in iter(raw_input, stopAt): SIGCOLLECT += line + "\n" SIGCOLLECT += stopAt a = UnsignedTransaction() tx = a.unserializeAscii(SIGCOLLECT) txJSON = tx.toJSONMap() pp.pprint(txJSON) print "\n" print "\nTransaction summary:\n" tx.pprint() tx.evaluateSigningStatus().pprint() print "\n" raw = binary_to_hex(tx.getSignedPyTx(doVerifySigs=False).serialize()) if tx.evaluateSigningStatus().canBroadcast: confirmed = raw_input("Broadcast Transaction? [y/N]: ") or "false" if util.strtobool(confirmed): return broadcastTx(raw) else: print "Not broadcasting transaction." else: print "Transaction not complete." print "\nRaw Transaction:\n" print raw if isTestnet: print "\nBroadcast Transaction:\nhttp://tbtc.blockr.io/tx/push\n" else: print "\nBroadcast Transaction:\nhttps://blockchain.info/pushtx\n"
def decodeSigCollect(): print "Paste your TXSIGCOLLECT below and press <enter>:\n" stopAt = "================================================================" SIGCOLLECT = "" for line in iter(raw_input, stopAt): SIGCOLLECT += line + "\n" SIGCOLLECT += stopAt a = UnsignedTransaction() tx = a.unserializeAscii(SIGCOLLECT) txJSON = tx.toJSONMap() pp.pprint(txJSON) print "\n" print "\nTransaction summary:\n" tx.pprint() tx.evaluateSigningStatus().pprint() print "\n" raw = binary_to_hex(tx.getSignedPyTx(doVerifySigs=False).serialize()) if tx.evaluateSigningStatus().canBroadcast: confirmed = raw_input("Broadcast Transaction? [y/N]: ") or "false" if util.strtobool(confirmed): return broadcastTx(raw) else: print "Not broadcasting transaction." else: print "Transaction not complete." print "\nRaw Transaction:\n" print raw print "\nBroadcast Transaction:\nhttps://blockchain.info/pushtx\n"
# Start composing transaction print "Creating transaction on BTChip..." app.startUntrustedTransaction(True, 0, [trustedInput], bytearray(REDEEMSCRIPT.decode('hex'))) app.finalizeInputFull(OUTPUT) print "Signing..." signature = app.untrustedHashSign(KEYPATH, "") sigStr = hex_to_binary(binascii.hexlify(signature)) # Put signature back into armory transaction tx.insertSignature(sigStr, hex_to_binary(pubKey)) print "\n\nSignature summary and signing status:\n\n" tx.pprint() tx.evaluateSigningStatus().pprint() print "\n\nRaw transaction:\n\n" # doVerifySigs = tx.evaluateSigningStatus().canBroadcast # print binary_to_hex(tx.getSignedPyTx(doVerifySigs=doVerifySigs).serialize()) # Unfortunately Armory doesn't appear to be able to verify these, so you're best off broadcasting the raw # tx via the bitcoind CLI. print binary_to_hex(tx.getSignedPyTx(doVerifySigs=False).serialize()) print "\n\nSigcollect below:\n\n" print tx.serializeAscii() exit(0)
def getHashHex(self, endian=LITTLEENDIAN): if self.version == UNINITIALIZED: raise UnitializedBlockDataError, 'PyBlockHeader object not initialized!' if len(self.theHash) < 32: self.theHash = hash256(self.serialize()) return binary_to_hex(self.theHash, endian)
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 testPyBtcWallet(self): self.wlt.addrPoolSize = 5 # No block chain loaded so this should return -1 # self.assertEqual(self.wlt.detectHighestUsedIndex(True), -1) self.assertEqual(self.wlt.kdfKey, None) self.assertEqual(binary_to_hex(self.wlt.addrMap['ROOT'].addrStr20), WALLET_ROOT_ADDR ) ############################################################################# # (1) Getting a new address: newAddr = self.wlt.getNextUnusedAddress() self.wlt.pprint(indent=' '*5) self.assertEqual(binary_to_hex(newAddr.addrStr20), NEW_UNUSED_ADDR) # (1) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # (2)Testing unencrypted wallet import-address' originalLength = len(self.wlt.linearAddr160List) self.wlt.importExternalAddressData(privKey=self.privKey2) self.assertEqual(len(self.wlt.linearAddr160List), originalLength+1) # (2) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) self.assertTrue(self.wlt.isEqualTo(wlt2)) # (2a)Testing deleteImportedAddress # Wallet size before delete:', os.path.getsize(self.wlt.walletPath) # Addresses before delete:', len(self.wlt.linearAddr160List) toDelete160 = convertKeyDataToAddress(self.privKey2) self.wlt.deleteImportedAddress(toDelete160) self.assertEqual(len(self.wlt.linearAddr160List), originalLength) # (2a) Reimporting address for remaining tests # Wallet size before reimport:', os.path.getsize(self.wlt.walletPath) self.wlt.importExternalAddressData(privKey=self.privKey2) self.assertEqual(len(self.wlt.linearAddr160List), originalLength+1) # (2b)Testing ENCRYPTED wallet import-address privKey3 = SecureBinaryData('\xbb'*32) privKey4 = SecureBinaryData('\x44'*32) self.chainstr2 = SecureBinaryData('\xdd'*32) theIV2 = SecureBinaryData(hex_to_binary('66'*16)) self.passphrase2= SecureBinaryData('hello') wltE = PyBtcWallet().createNewWallet(withEncrypt=True, \ plainRootKey=privKey3, \ securePassphrase=self.passphrase2, \ chaincode=self.chainstr2, \ IV=theIV2, \ shortLabel=self.shortlabel) # We should have thrown an error about importing into a locked wallet... self.assertRaises(WalletLockError, wltE.importExternalAddressData, privKey=self.privKey2) wltE.unlock(securePassphrase=self.passphrase2) wltE.importExternalAddressData(privKey=self.privKey2) # (2b) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(wltE.walletPath) self.assertTrue(wltE.isEqualTo(wlt2)) # (2b) Unlocking wlt2 after re-reading locked-import-wallet wlt2.unlock(securePassphrase=self.passphrase2) self.assertFalse(wlt2.isLocked) ############################################################################# # Now play with encrypted wallets # *********************************************************************' # (3)Testing conversion to encrypted wallet kdfParams = self.wlt.computeSystemSpecificKdfParams(0.1) self.wlt.changeKdfParams(*kdfParams) self.assertEqual(self.wlt.kdf.getSalt(), kdfParams[2]) self.wlt.changeWalletEncryption( securePassphrase=self.passphrase ) self.assertEqual(self.wlt.kdf.getSalt(), kdfParams[2]) # (3) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) # NOTE: this isEqual operation compares the serializations # of the wallet addresses, which only contains the # encrypted versions of the private keys. However, # self.wlt is unlocked and contains the plaintext keys, too # while wlt2 does not. self.wlt.lock() for key in self.wlt.addrMap: self.assertTrue(self.wlt.addrMap[key].isLocked) self.assertEqual(self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') ############################################################################# # (4)Testing changing self.passphrase on encrypted wallet', self.wlt.unlock( securePassphrase=self.passphrase ) for key in self.wlt.addrMap: self.assertFalse(self.wlt.addrMap[key].isLocked) self.assertNotEqual(self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # ...to same self.passphrase' origKdfKey = self.wlt.kdfKey self.wlt.changeWalletEncryption( securePassphrase=self.passphrase ) self.assertEqual(origKdfKey, self.wlt.kdfKey) # (4)And now testing new self.passphrase...' self.wlt.changeWalletEncryption( securePassphrase=self.passphrase2 ) self.assertNotEqual(origKdfKey, self.wlt.kdfKey) # (4) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # (5)Testing changing KDF on encrypted wallet' self.wlt.unlock( securePassphrase=self.passphrase2 ) MEMORY_REQT_BYTES = 1024 NUM_ITER = 999 SALT_ALL_0 ='00'*32 self.wlt.changeKdfParams(MEMORY_REQT_BYTES, NUM_ITER, hex_to_binary(SALT_ALL_0), self.passphrase2) self.assertEqual(self.wlt.kdf.getMemoryReqtBytes(), MEMORY_REQT_BYTES) self.assertEqual(self.wlt.kdf.getNumIterations(), NUM_ITER) self.assertEqual(self.wlt.kdf.getSalt().toHexStr(), SALT_ALL_0) self.wlt.changeWalletEncryption( securePassphrase=self.passphrase2 ) # I don't know why this shouldn't be '' # Commenting out because it's a broken assertion # self.assertNotEqual(origKdfKey.toHexStr(), '') # (5) Get new address from locked wallet' # Locking wallet' self.wlt.lock() for i in range(10): self.wlt.getNextUnusedAddress() self.assertEqual(len(self.wlt.addrMap), originalLength+13) # (5) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # !!! #forkOnlineWallet() # (6)Testing forking encrypted wallet for online mode' self.wlt.forkOnlineWallet('OnlineVersionOfEncryptedWallet.bin') wlt2.readWalletFile('OnlineVersionOfEncryptedWallet.bin') for key in wlt2.addrMap: self.assertTrue(self.wlt.addrMap[key].isLocked) self.assertEqual(self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # (6)Getting a new addresses from both wallets' for i in range(self.wlt.addrPoolSize*2): self.wlt.getNextUnusedAddress() wlt2.getNextUnusedAddress() newaddr1 = self.wlt.getNextUnusedAddress() newaddr2 = wlt2.getNextUnusedAddress() self.assertTrue(newaddr1.getAddr160() == newaddr2.getAddr160()) self.assertEqual(len(wlt2.addrMap), 3*originalLength+14) # (6) Re-reading wallet from file, compare the two wallets wlt3 = PyBtcWallet().readWalletFile('OnlineVersionOfEncryptedWallet.bin') self.assertTrue(wlt3.isEqualTo(wlt2)) ############################################################################# # (7)Testing removing wallet encryption' # Wallet is locked? ', self.wlt.isLocked self.wlt.unlock(securePassphrase=self.passphrase2) self.wlt.changeWalletEncryption( None ) for key in self.wlt.addrMap: self.assertFalse(self.wlt.addrMap[key].isLocked) self.assertNotEqual(self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # (7) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # \n' # *********************************************************************' # (8)Doing interrupt tests to test wallet-file-update recovery' def hashfile(fn): f = open(fn,'r') d = hash256(f.read()) f.close() return binary_to_hex(d[:8]) def verifyFileStatus(fileAExists = True, fileBExists = True, \ fileAupdExists = True, fileBupdExists = True): self.assertEqual(os.path.exists(self.fileA), fileAExists) self.assertEqual(os.path.exists(self.fileB), fileBExists) self.assertEqual(os.path.exists(self.fileAupd), fileAupdExists) self.assertEqual(os.path.exists(self.fileBupd), fileBupdExists) correctMainHash = hashfile(self.fileA) try: self.wlt.interruptTest1 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest1 = False # (8a)Interrupted getNextUnusedAddress on primary file update' verifyFileStatus(True, True, False, True) # (8a)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(correctMainHash, hashfile(self.fileA)) try: self.wlt.interruptTest2 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest2 = False # (8b)Interrupted getNextUnusedAddress on between primary/backup update' verifyFileStatus(True, True, True, True) # (8b)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(hashfile(self.fileA), hashfile(self.fileB)) # (8c) Try interrupting at state 3' verifyFileStatus(True, True, False, False) try: self.wlt.interruptTest3 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest3 = False # (8c)Interrupted getNextUnusedAddress on backup file update' verifyFileStatus(True, True, True, False) # (8c)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(hashfile(self.fileA), hashfile(self.fileB)) ############################################################################# # \n' # *********************************************************************' # (9)Checksum-based byte-error correction tests!' # (9)Start with a good primary and backup file...' # (9a)Open primary wallet, change second byte in KDF' wltfile = open(self.wlt.walletPath,'r+b') wltfile.seek(326) wltfile.write('\xff') wltfile.close() # (9a)Byte changed, file hashes:' verifyFileStatus(True, True, False, False) # (9a)Try to read wallet from file, should correct KDF error, write fix' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9b)Change a byte in each checksummed field in root addr' wltfile = open(self.wlt.walletPath,'r+b') wltfile.seek(838); wltfile.write('\xff') wltfile.seek(885); wltfile.write('\xff') wltfile.seek(929); wltfile.write('\xff') wltfile.seek(954); wltfile.write('\xff') wltfile.seek(1000); wltfile.write('\xff') wltfile.close() # (9b) New file hashes...' verifyFileStatus(True, True, False, False) # (9b)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9c)Change a byte in each checksummed field, of first non-root addr' wltfile = open(self.wlt.walletPath,'r+b') wltfile.seek(1261+21+838); wltfile.write('\xff') wltfile.seek(1261+21+885); wltfile.write('\xff') wltfile.seek(1261+21+929); wltfile.write('\xff') wltfile.seek(1261+21+954); wltfile.write('\xff') wltfile.seek(1261+21+1000); wltfile.write('\xff') wltfile.close() # (9c) New file hashes...' verifyFileStatus(True, True, False, False) # (9c)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9d)Now butcher the CHECKSUM, see if correction works' wltfile = open(self.wlt.walletPath,'r+b') wltfile.seek(977); wltfile.write('\xff') wltfile.close() # (9d) New file hashes...' verifyFileStatus(True, True, False, False) # (9d)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # *******' # (9z) Test comment I/O' comment1 = 'This is my normal unit-testing address.' comment2 = 'This is fake tx... no tx has this hash.' comment3 = comment1 + ' Corrected!' hash1 = '\x1f'*20 # address160 hash2 = '\x2f'*32 # tx hash self.wlt.setComment(hash1, comment1) self.wlt.setComment(hash2, comment2) self.wlt.setComment(hash1, comment3) wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) c3 = wlt2.getComment(hash1) c2 = wlt2.getComment(hash2) self.assertEqual(c3, comment3) self.assertEqual(c2, comment2)
def dataReceived(self, data): """ Called by the reactor when data is received over the connection. This method will do nothing if we don't receive a full message. """ #print '\n\nData Received:', #pprintHex(binary_to_hex(data), withAddr=False) # Put the current buffer into an unpacker, process until empty self.recvData += data buf = BinaryUnpacker(self.recvData) messages = [] while True: try: # recvData is only modified if the unserialize succeeds # Had a serious issue with references, so I had to convert # messages to strings to guarantee that copies were being # made! (yes, hacky...) thisMsg = PyMessage().unserialize(buf) messages.append( thisMsg.serialize() ) self.recvData = buf.getRemainingString() except NetworkIDError: LOGERROR('Message for a different network!' ) if BLOCKCHAINS.has_key(self.recvData[:4]): LOGERROR( '(for network: %s)', BLOCKCHAINS[self.recvData[:4]]) # Before raising the error, we should've finished reading the msg # So pop it off the front of the buffer self.recvData = buf.getRemainingString() return except UnknownNetworkPayload: return except UnpackerError: # Expect this error when buffer isn't full enough for a whole msg break # We might've gotten here without anything to process -- if so, bail if len(messages)==0: return # Finally, we have some message to process, let's do it for msgStr in messages: msg = PyMessage().unserialize(msgStr) cmd = msg.cmd # Log the message if netlog option if CLI_OPTIONS.netlog: LOGDEBUG( 'DataReceived: %s', msg.payload.command) if msg.payload.command == 'tx': LOGDEBUG('\t' + binary_to_hex(msg.payload.tx.thisHash)) elif msg.payload.command == 'block': LOGDEBUG('\t' + msg.payload.header.getHashHex()) elif msg.payload.command == 'inv': for inv in msg.payload.invList: LOGDEBUG(('\tBLOCK: ' if inv[0]==2 else '\tTX : ') + \ binary_to_hex(inv[1])) # We process version and verackk only if we haven't yet if cmd=='version' and not self.sentVerack: self.peerInfo = {} self.peerInfo['version'] = msg.payload.version self.peerInfo['subver'] = msg.payload.subver self.peerInfo['time'] = msg.payload.time self.peerInfo['height'] = msg.payload.height0 LOGINFO('Received version message from peer:') LOGINFO(' Version: %s', str(self.peerInfo['version'])) LOGINFO(' SubVersion: %s', str(self.peerInfo['subver'])) LOGINFO(' TimeStamp: %s', str(self.peerInfo['time'])) LOGINFO(' StartHeight: %s', str(self.peerInfo['height'])) self.sentVerack = True self.sendMessage( PayloadVerack() ) elif cmd=='verack': self.gotVerack = True self.factory.handshakeFinished(self) #self.startHeaderDL() #################################################################### # Don't process any other messages unless the handshake is finished if self.gotVerack and self.sentVerack: self.processMessage(msg)
def testPyBtcWallet(self): self.wlt.addrPoolSize = 5 # No block chain loaded so this should return -1 # self.assertEqual(self.wlt.detectHighestUsedIndex(True), -1) self.assertEqual(self.wlt.kdfKey, None) self.assertEqual(binary_to_hex(self.wlt.addrMap['ROOT'].addrStr20), WALLET_ROOT_ADDR) ############################################################################# # (1) Getting a new address: newAddr = self.wlt.getNextUnusedAddress() self.wlt.pprint(indent=' ' * 5) self.assertEqual(binary_to_hex(newAddr.addrStr20), NEW_UNUSED_ADDR) # (1) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # (2)Testing unencrypted wallet import-address' originalLength = len(self.wlt.linearAddr160List) self.wlt.importExternalAddressData(privKey=self.privKey2) self.assertEqual(len(self.wlt.linearAddr160List), originalLength + 1) # (2) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) self.assertTrue(self.wlt.isEqualTo(wlt2)) # (2a)Testing deleteImportedAddress # Wallet size before delete:', os.path.getsize(self.wlt.walletPath) # Addresses before delete:', len(self.wlt.linearAddr160List) toDelete160 = convertKeyDataToAddress(self.privKey2) self.wlt.deleteImportedAddress(toDelete160) self.assertEqual(len(self.wlt.linearAddr160List), originalLength) # (2a) Reimporting address for remaining tests # Wallet size before reimport:', os.path.getsize(self.wlt.walletPath) self.wlt.importExternalAddressData(privKey=self.privKey2) self.assertEqual(len(self.wlt.linearAddr160List), originalLength + 1) # (2b)Testing ENCRYPTED wallet import-address privKey3 = SecureBinaryData('\xbb' * 32) privKey4 = SecureBinaryData('\x44' * 32) self.chainstr2 = SecureBinaryData('\xdd' * 32) theIV2 = SecureBinaryData(hex_to_binary('66' * 16)) self.passphrase2 = SecureBinaryData('hello') wltE = PyBtcWallet().createNewWallet(withEncrypt=True, \ plainRootKey=privKey3, \ securePassphrase=self.passphrase2, \ chaincode=self.chainstr2, \ IV=theIV2, \ shortLabel=self.shortlabel) # We should have thrown an error about importing into a locked wallet... self.assertRaises(WalletLockError, wltE.importExternalAddressData, privKey=self.privKey2) wltE.unlock(securePassphrase=self.passphrase2) wltE.importExternalAddressData(privKey=self.privKey2) # (2b) Re-reading wallet from file, compare the two wallets wlt2 = PyBtcWallet().readWalletFile(wltE.walletPath) self.assertTrue(wltE.isEqualTo(wlt2)) # (2b) Unlocking wlt2 after re-reading locked-import-wallet wlt2.unlock(securePassphrase=self.passphrase2) self.assertFalse(wlt2.isLocked) ############################################################################# # Now play with encrypted wallets # *********************************************************************' # (3)Testing conversion to encrypted wallet kdfParams = self.wlt.computeSystemSpecificKdfParams(0.1) self.wlt.changeKdfParams(*kdfParams) self.assertEqual(self.wlt.kdf.getSalt(), kdfParams[2]) self.wlt.changeWalletEncryption(securePassphrase=self.passphrase) self.assertEqual(self.wlt.kdf.getSalt(), kdfParams[2]) # (3) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) # NOTE: this isEqual operation compares the serializations # of the wallet addresses, which only contains the # encrypted versions of the private keys. However, # self.wlt is unlocked and contains the plaintext keys, too # while wlt2 does not. self.wlt.lock() for key in self.wlt.addrMap: self.assertTrue(self.wlt.addrMap[key].isLocked) self.assertEqual( self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') ############################################################################# # (4)Testing changing self.passphrase on encrypted wallet', self.wlt.unlock(securePassphrase=self.passphrase) for key in self.wlt.addrMap: self.assertFalse(self.wlt.addrMap[key].isLocked) self.assertNotEqual( self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # ...to same self.passphrase' origKdfKey = self.wlt.kdfKey self.wlt.changeWalletEncryption(securePassphrase=self.passphrase) self.assertEqual(origKdfKey, self.wlt.kdfKey) # (4)And now testing new self.passphrase...' self.wlt.changeWalletEncryption(securePassphrase=self.passphrase2) self.assertNotEqual(origKdfKey, self.wlt.kdfKey) # (4) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # (5)Testing changing KDF on encrypted wallet' self.wlt.unlock(securePassphrase=self.passphrase2) MEMORY_REQT_BYTES = 1024 NUM_ITER = 999 SALT_ALL_0 = '00' * 32 self.wlt.changeKdfParams(MEMORY_REQT_BYTES, NUM_ITER, hex_to_binary(SALT_ALL_0), self.passphrase2) self.assertEqual(self.wlt.kdf.getMemoryReqtBytes(), MEMORY_REQT_BYTES) self.assertEqual(self.wlt.kdf.getNumIterations(), NUM_ITER) self.assertEqual(self.wlt.kdf.getSalt().toHexStr(), SALT_ALL_0) self.wlt.changeWalletEncryption(securePassphrase=self.passphrase2) # I don't know why this shouldn't be '' # Commenting out because it's a broken assertion # self.assertNotEqual(origKdfKey.toHexStr(), '') # (5) Get new address from locked wallet' # Locking wallet' self.wlt.lock() for i in range(10): self.wlt.getNextUnusedAddress() self.assertEqual(len(self.wlt.addrMap), originalLength + 13) # (5) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # !!! #forkOnlineWallet() # (6)Testing forking encrypted wallet for online mode' self.wlt.forkOnlineWallet('OnlineVersionOfEncryptedWallet.bin') wlt2.readWalletFile('OnlineVersionOfEncryptedWallet.bin') for key in wlt2.addrMap: self.assertTrue(self.wlt.addrMap[key].isLocked) self.assertEqual( self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # (6)Getting a new addresses from both wallets' for i in range(self.wlt.addrPoolSize * 2): self.wlt.getNextUnusedAddress() wlt2.getNextUnusedAddress() newaddr1 = self.wlt.getNextUnusedAddress() newaddr2 = wlt2.getNextUnusedAddress() self.assertTrue(newaddr1.getAddr160() == newaddr2.getAddr160()) self.assertEqual(len(wlt2.addrMap), 3 * originalLength + 14) # (6) Re-reading wallet from file, compare the two wallets wlt3 = PyBtcWallet().readWalletFile( 'OnlineVersionOfEncryptedWallet.bin') self.assertTrue(wlt3.isEqualTo(wlt2)) ############################################################################# # (7)Testing removing wallet encryption' # Wallet is locked? ', self.wlt.isLocked self.wlt.unlock(securePassphrase=self.passphrase2) self.wlt.changeWalletEncryption(None) for key in self.wlt.addrMap: self.assertFalse(self.wlt.addrMap[key].isLocked) self.assertNotEqual( self.wlt.addrMap[key].binPrivKey32_Plain.toHexStr(), '') # (7) Re-reading wallet from file, compare the two wallets' wlt2 = PyBtcWallet().readWalletFile(self.wlt.getWalletPath()) self.assertTrue(self.wlt.isEqualTo(wlt2)) ############################################################################# # \n' # *********************************************************************' # (8)Doing interrupt tests to test wallet-file-update recovery' def hashfile(fn): f = open(fn, 'r') d = hash256(f.read()) f.close() return binary_to_hex(d[:8]) def verifyFileStatus(fileAExists = True, fileBExists = True, \ fileAupdExists = True, fileBupdExists = True): self.assertEqual(os.path.exists(self.fileA), fileAExists) self.assertEqual(os.path.exists(self.fileB), fileBExists) self.assertEqual(os.path.exists(self.fileAupd), fileAupdExists) self.assertEqual(os.path.exists(self.fileBupd), fileBupdExists) correctMainHash = hashfile(self.fileA) try: self.wlt.interruptTest1 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest1 = False # (8a)Interrupted getNextUnusedAddress on primary file update' verifyFileStatus(True, True, False, True) # (8a)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(correctMainHash, hashfile(self.fileA)) try: self.wlt.interruptTest2 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest2 = False # (8b)Interrupted getNextUnusedAddress on between primary/backup update' verifyFileStatus(True, True, True, True) # (8b)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(hashfile(self.fileA), hashfile(self.fileB)) # (8c) Try interrupting at state 3' verifyFileStatus(True, True, False, False) try: self.wlt.interruptTest3 = True self.wlt.getNextUnusedAddress() except InterruptTestError: # Interrupted!' pass self.wlt.interruptTest3 = False # (8c)Interrupted getNextUnusedAddress on backup file update' verifyFileStatus(True, True, True, False) # (8c)Do consistency check on the wallet' self.wlt.doWalletFileConsistencyCheck() verifyFileStatus(True, True, False, False) self.assertEqual(hashfile(self.fileA), hashfile(self.fileB)) ############################################################################# # \n' # *********************************************************************' # (9)Checksum-based byte-error correction tests!' # (9)Start with a good primary and backup file...' # (9a)Open primary wallet, change second byte in KDF' wltfile = open(self.wlt.walletPath, 'r+b') wltfile.seek(326) wltfile.write('\xff') wltfile.close() # (9a)Byte changed, file hashes:' verifyFileStatus(True, True, False, False) # (9a)Try to read wallet from file, should correct KDF error, write fix' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9b)Change a byte in each checksummed field in root addr' wltfile = open(self.wlt.walletPath, 'r+b') wltfile.seek(838) wltfile.write('\xff') wltfile.seek(885) wltfile.write('\xff') wltfile.seek(929) wltfile.write('\xff') wltfile.seek(954) wltfile.write('\xff') wltfile.seek(1000) wltfile.write('\xff') wltfile.close() # (9b) New file hashes...' verifyFileStatus(True, True, False, False) # (9b)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9c)Change a byte in each checksummed field, of first non-root addr' wltfile = open(self.wlt.walletPath, 'r+b') wltfile.seek(1261 + 21 + 838) wltfile.write('\xff') wltfile.seek(1261 + 21 + 885) wltfile.write('\xff') wltfile.seek(1261 + 21 + 929) wltfile.write('\xff') wltfile.seek(1261 + 21 + 954) wltfile.write('\xff') wltfile.seek(1261 + 21 + 1000) wltfile.write('\xff') wltfile.close() # (9c) New file hashes...' verifyFileStatus(True, True, False, False) # (9c)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # \n' # *********************************************************************' # (9d)Now butcher the CHECKSUM, see if correction works' wltfile = open(self.wlt.walletPath, 'r+b') wltfile.seek(977) wltfile.write('\xff') wltfile.close() # (9d) New file hashes...' verifyFileStatus(True, True, False, False) # (9d)Try to read wallet from file, should correct address errors' wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) verifyFileStatus(True, True, False, False) self.assertNotEqual(hashfile(self.fileA), hashfile(self.fileB)) # *******' # (9z) Test comment I/O' comment1 = 'This is my normal unit-testing address.' comment2 = 'This is fake tx... no tx has this hash.' comment3 = comment1 + ' Corrected!' hash1 = '\x1f' * 20 # address160 hash2 = '\x2f' * 32 # tx hash self.wlt.setComment(hash1, comment1) self.wlt.setComment(hash2, comment2) self.wlt.setComment(hash1, comment3) wlt2 = PyBtcWallet().readWalletFile(self.wlt.walletPath) c3 = wlt2.getComment(hash1) c2 = wlt2.getComment(hash2) self.assertEqual(c3, comment3) self.assertEqual(c2, comment2)
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 testGetrawtransaction(self): actualRawTx = self.jsonServer.jsonrpc_getrawtransaction(TX_ID1) pyTx = PyTx().unserialize(hex_to_binary(actualRawTx)) self.assertEquals(TX_ID1, binary_to_hex(pyTx.getHash(), BIGENDIAN))
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)
print "Creating transaction on BTChip..." app.startUntrustedTransaction(True, 0, [trustedInput], bytearray(REDEEMSCRIPT.decode('hex'))) app.finalizeInputFull(OUTPUT) print "Signing..." signature = app.untrustedHashSign(KEYPATH, "") sigStr = hex_to_binary(binascii.hexlify(signature)) # Put signature back into armory transaction tx.insertSignature(sigStr, hex_to_binary(pubKey)) print "\n\nSignature summary and signing status:\n\n" tx.pprint() tx.evaluateSigningStatus().pprint() print "\n\nRaw transaction:\n\n" # doVerifySigs = tx.evaluateSigningStatus().canBroadcast # print binary_to_hex(tx.getSignedPyTx(doVerifySigs=doVerifySigs).serialize()) # Unfortunately Armory doesn't appear to be able to verify these, so you're best off broadcasting the raw # tx via the bitcoind CLI. print binary_to_hex(tx.getSignedPyTx(doVerifySigs=False).serialize()) print "\n\nSigcollect below:\n\n" print tx.serializeAscii() exit(0)
MAGIC_HEX_STRING = "f9beb4d9" MAGIC_NUMBER_LENGTH = 4 VERSION_LENGTH = 4 BLOCK_SIZE_LENGTH = 4 TX_OUT_HASH_LENGTH = 32 TX_OUT_INDEX_LENGTH = 4 SEQUENCE_LENGTH = 4 LOCKTIME_LENGTH = 4 SATOSHI_LENGTH = 8 HEADER_LENGTH = 80 HEX_32_BYTE_0 = "0000000000000000000000000000000000000000000000000000000000000000" BIN_32_BYTE_0 = hex_to_binary(HEX_32_BYTE_0) HEX_32_BYTE_ALL_F = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" DIFFICULTY_NUMERATOR = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 getHighestTarget = lambda bits: float(hex_to_int(binary_to_hex(bits, BIGENDIAN)[2:8]) * 2**(8*(hex_to_int(binary_to_hex(bits, BIGENDIAN)[:2]) - 3))) def calculateDifficulty(bits): return DIFFICULTY_NUMERATOR / getHighestTarget(bits) def parseBlockHeader(blkHdrBinary): binunpack = BinaryUnpacker(blkHdrBinary) return BlockHeader(binunpack.get(UINT32), binunpack.get(BINARY_CHUNK, 32), binunpack.get(BINARY_CHUNK, 32), binunpack.get(UINT32), binunpack.get(UINT32), binunpack.get(UINT32)) blkCounter = -1
def dataReceived(self, data): """ Called by the reactor when data is received over the connection. This method will do nothing if we don't receive a full message. """ #print '\n\nData Received:', #pprintHex(binary_to_hex(data), withAddr=False) # Put the current buffer into an unpacker, process until empty self.recvData += data buf = BinaryUnpacker(self.recvData) messages = [] while True: try: # recvData is only modified if the unserialize succeeds # Had a serious issue with references, so I had to convert # messages to strings to guarantee that copies were being # made! (yes, hacky...) thisMsg = PyMessage().unserialize(buf) messages.append(thisMsg.serialize()) self.recvData = buf.getRemainingString() except NetworkIDError: LOGERROR('Message for a different network!') if BLOCKCHAINS.has_key(self.recvData[:4]): LOGERROR('(for network: %s)', BLOCKCHAINS[self.recvData[:4]]) # Before raising the error, we should've finished reading the msg # So pop it off the front of the buffer self.recvData = buf.getRemainingString() return except UnpackerError: # Expect this error when buffer isn't full enough for a whole msg break # We might've gotten here without anything to process -- if so, bail if len(messages) == 0: return # Finally, we have some message to process, let's do it for msgStr in messages: msg = PyMessage().unserialize(msgStr) cmd = msg.cmd # Log the message if netlog option if CLI_OPTIONS.netlog: LOGDEBUG('DataReceived: %s', msg.payload.command) if msg.payload.command == 'tx': LOGDEBUG('\t' + binary_to_hex(msg.payload.tx.thisHash)) elif msg.payload.command == 'block': LOGDEBUG('\t' + msg.payload.header.getHashHex()) elif msg.payload.command == 'inv': for inv in msg.payload.invList: LOGDEBUG(('\tBLOCK: ' if inv[0]==2 else '\tTX : ') + \ binary_to_hex(inv[1])) # We process version and verackk only if we haven't yet if cmd == 'version' and not self.sentVerack: self.peerInfo = {} self.peerInfo['version'] = msg.payload.version self.peerInfo['subver'] = msg.payload.subver self.peerInfo['time'] = msg.payload.time self.peerInfo['height'] = msg.payload.height0 LOGINFO('Received version message from peer:') LOGINFO(' Version: %s', str(self.peerInfo['version'])) LOGINFO(' SubVersion: %s', str(self.peerInfo['subver'])) LOGINFO(' TimeStamp: %s', str(self.peerInfo['time'])) LOGINFO(' StartHeight: %s', str(self.peerInfo['height'])) self.sentVerack = True self.sendMessage(PayloadVerack()) elif cmd == 'verack': self.gotVerack = True self.factory.handshakeFinished(self) #self.startHeaderDL() #################################################################### # Don't process any other messages unless the handshake is finished if self.gotVerack and self.sentVerack: self.processMessage(msg)
def c2s(combinationMap): return '\n'.join([' '.join([str(k), binary_to_hex(v[0]), binary_to_hex(v[1])]) \ for k,v in combinationMap.iteritems()])
def hashfile(fn): f = open(fn, 'r') d = hash256(f.read()) f.close() return binary_to_hex(d[:8])
def hashfile(fn): f = open(fn,'r') d = hash256(f.read()) f.close() return binary_to_hex(d[:8])
def testWalletRecovery(self): #run recovery on broken wallet recThread = PyBtcWalletRecovery().RecoverWallet(self.corruptWallet, \ 'testing', RECOVERMODE.Full, \ returnError = 'Dict') recThread.join() brkWltResult = recThread.output self.assertTrue(len(brkWltResult['sequenceGaps'])==1, \ "Sequence Gap Undetected") self.assertTrue(len(brkWltResult['forkedPublicKeyChain'])==2, \ "Address Chain Forks Undetected") self.assertTrue(len(brkWltResult['unmatchedPair'])==100, \ "Unmatched Priv/Pub Key Undetected") self.assertTrue(len(brkWltResult['misc'])==50, \ "Wallet Encryption Inconsistency Undetected") self.assertTrue(brkWltResult['nErrors']==153, \ "Unexpected Errors Found") #check obfuscated keys yield the valid key #grab root key badWlt = PyBtcWallet() badWlt.readWalletFile(self.corruptWallet, False, False) rootAddr = badWlt.addrMap['ROOT'] SecurePassphrase = SecureBinaryData('testing') secureKdfOutput = badWlt.kdf.DeriveKey(SecurePassphrase) #HMAC Q rootAddr.unlock(secureKdfOutput) Q = rootAddr.binPrivKey32_Plain.toBinStr() nonce = 0 while 1: hmacQ = HMAC256(Q, 'LogMult%d' % nonce) if binary_to_int(hmacQ, BIGENDIAN) < SECP256K1_ORDER: hmacQ = SecureBinaryData(hmacQ) break nonce = nonce +1 #Bad Private Keys import operator badKeys = [addrObj for addrObj in (sorted(badWlt.addrMap.values(), key=operator.attrgetter('chainIndex')))] #run through obdsPrivKey for i in range(0, len(brkWltResult['privMult'])): obfsPKey = SecureBinaryData( hex_to_binary(brkWltResult['privMult'][i])) pKey = CryptoECDSA().ECMultiplyScalars(obfsPKey.toBinStr(), \ hmacQ.toBinStr()) try: badKeys[i+201].unlock(secureKdfOutput) except: continue self.assertTrue(binary_to_hex(pKey) == \ badKeys[i+201].binPrivKey32_Plain.toHexStr(), \ 'key mult error') #run recovery on recovered wallet recThread = PyBtcWalletRecovery().RecoverWallet( \ 'armory_%s_RECOVERED.wallet' % self.wltID, \ 'testing', RECOVERMODE.Full, \ returnError = 'Dict') recThread.join() rcvWltResult = recThread.output self.assertTrue(rcvWltResult['nErrors']==0, "Unexpected Errors Found") self.assertTrue(len(rcvWltResult['negativeImports'])==50, \ "Missing neg Imports")
def testImportprivkey(self): originalLength = len(self.wallet.linearAddr160List) self.jsonServer.jsonrpc_importprivkey(binary_to_hex(self.privKey2.toBinStr())) self.assertEqual(len(self.wallet.linearAddr160List), originalLength+1)
def testImportprivkey(self): originalLength = len(self.wallet.linearAddr160List) self.jsonServer.jsonrpc_importprivkey( binary_to_hex(self.privKey2.toBinStr())) self.assertEqual(len(self.wallet.linearAddr160List), originalLength + 1)