def block_at_height(block_height): _bitcoind = gen_bitcoind(timeout=5) while True: try: block_hash = _bitcoind.getblockhash(block_height) block = Block.parse(block_as_bytesio(_bitcoind, block_hash)) ans = (block, block_hash, block_height) # order important for merge_nulldatas logging.info("Processing results for height %d" % ans[2]) merge_nulldatas_from_block_obj(*ans, bitcoind=_bitcoind) return ans except timeout as e: logging.warning('%d, Timeout... Creating new bitcoind' % block_height) except http.client.CannotSendRequest as e: logging.warning("Got CannotSendRequest.") traceback.print_tb(e.__traceback__) except ScriptError as e: logging.error("Script parse error!") traceback.print_tb(e.__traceback__) except Exception as e: logging.warning("%d, %s, %s" % (block_height, e, type(e))) finally: _bitcoind = gen_bitcoind() logging.info("%d; Regen'd bitcoind" % block_height) sleep(0.1)
def test_getblock_p2p_non_verbose(self): hex_block ='010000006fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000982051fd1e4ba744bbbe6' \ '80e1fee14677ba1a3c3540bf7b1cdb606e857233e0e61bc6649ffff001d01e3629901010000000100000000000000' \ '00000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0' \ '100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0' \ 'a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000' bytes_block = binascii.unhexlify(hex_block.encode()) self.repository.headers.get_best_header.return_value = { 'block_height': 513980 } self.repository.headers.get_block_header.return_value = self.header self.repository.blockchain.get_block.return_value = None self.repository.blockchain.async_save_block.return_value = async_coro( True) self.p2p.get_block.side_effect = [ async_coro(None), async_coro({ 'block_hash': '00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048', 'block_bytes': bytes_block, 'block_object': Block.parse(io.BytesIO(bytes_block)) }) ] block = self.loop.run_until_complete( self.sut.getblock( '000000000000000000376267d342878f869cb68192ff5d73f5f1953ae83e3e1e', 0)) self.assertEqual(block, hex_block)
def main(): parser = argparse.ArgumentParser(description="Dump a block in human-readable form.") parser.add_argument("block_bin", nargs="+", type=argparse.FileType('rb'), help='The file containing the binary block.') args = parser.parse_args() for f in args.block_bin: block = Block.parse(f) dump_block(block, network='M') print('')
async def getblock(self, blockhash: str, mode: int = 1): start = time.time() if mode == 2: raise NotImplementedError block_header = self.repository.headers.get_block_header(blockhash) if not block_header: return if mode == 1: txids, size = self.repository.blockchain.get_txids_by_block_hash( block_header['block_hash']) if txids: block = self._serialize_header(block_header) block.update({'tx': txids, 'size': size}) best_header = self.repository.headers.get_best_header() block['confirmations'] = best_header[ 'block_height'] - block_header['block_height'] + 1 Logger.p2p.info( 'Verbose block %s (%s) provided from local storage in %ss)', block_header['block_height'], blockhash, '{:.4f}'.format(time.time() - start)) return block p2p_block = await self._get_block(block_header, verbose=True) Logger.p2p.info('Verbose block %s (%s) provided from P2P in %ss)', block_header['block_height'], blockhash, '{:.4f}'.format(time.time() - start)) return p2p_block['verbose'] else: transactions, size = self.repository.blockchain.get_transactions_by_block_hash( blockhash) if transactions: Logger.p2p.info( 'Raw block %s (%s) provided from local storage in %ss)', block_header['block_height'], blockhash, '{:.4f}'.format(time.time() - start)) try: block = Block.parse(io.BytesIO( block_header['header_bytes']), include_transactions=False) block.set_txs([ Tx.from_bin(t['transaction_bytes']) for t in transactions ]) return block.as_hex() except: Logger.repository.error( 'Error loading block %s from repository, falling back to P2P' % blockhash) p2p_block = await self._get_block(block_header) Logger.p2p.info('Raw block %s (%s) provided from P2P in %ss)', block_header['block_height'], blockhash, '{:.4f}'.format(time.time() - start)) return binascii.hexlify(p2p_block['block_bytes']).decode()
def test_block(self): expected_checksum = '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1'.lower( ) block_data = h2b( "010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C552000000000" "007900A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796" "974CED66471B204C324703010000000100000000000000000000000000000000000000" "00000000000000000000000000FFFFFFFF0804ED66471B024001FFFFFFFF0100F2052A" "010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48AC178E1F5F7E" "EAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0" "EDAC000000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328" "E0D77C199CB3B57F010000008A4730440220556F61B84F16E637836D2E74B8CB784DE4" "0C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D4F3F7F831AC696748AD8D8E79AE" "B4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C2054E2F5" "96CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49" "ED0BA930743D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E9" "80ACE6FA885C5A89E4F27AA08988ACC0ADA41A000000001976A9145D17976537F30886" "5ED533CCCFDD76558CA3C8F088AC00000000010000000165148D894D3922EF5FFDA962" "BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EBF4" "834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377F" "D018281E77285EFC31E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0A" "A38C05FA33DD185F84C17F611E58A8658CE996D8B04395B99C7BE36529CAB7606900A0" "CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFFFFF02404B4C000000" "00001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE010000" "001976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000") # try to parse a block block = Block.parse(io.BytesIO(block_data)) assert b2h_rev(block.hash()) == expected_checksum block.check_merkle_hash() # parse already validated block block = Block.parse(io.BytesIO(block_data), check_merkle_hash=False) assert block.as_bin() == block_data
def receive_message (self): """This method will attempt to extract a header and message. It will return a tuple of (header, message) and set whichever can be set so far (None otherwise). """ # Calculate the size of the buffer self.buffer.seek(0, os.SEEK_END) buffer_size = self.buffer.tell() # Check if a complete header is present if buffer_size < self.header_size: return (None, None) # Go to the beginning of the buffer self.buffer.seek(0) message_model = None message_header_serial = MessageHeaderSerializer() message_header = message_header_serial.deserialize(self.buffer) total_length = self.header_size + message_header.length # Incomplete message if buffer_size < total_length: self.buffer.seek(0, os.SEEK_END) return (message_header, None) payload = self.buffer.read(message_header.length) #print (codecs.encode (payload, 'hex')) remaining = self.buffer.read() self.buffer = BytesIO() self.buffer.write(remaining) payload_checksum = MessageHeaderSerializer.calc_checksum(payload) # Check if the checksum is valid if payload_checksum != message_header.checksum: msg = "Bad checksum for command %s" % message_header.command raise InvalidMessageChecksum(msg) if message_header.command in MESSAGE_MAPPING: #print (message_header.command) if message_header.command == 'block': message_model = Block.parse(BytesIO(payload)) #print (message_model.id ()) else: deserializer = MESSAGE_MAPPING[message_header.command]() message_model = deserializer.deserialize(BytesIO(payload)) return (message_header, message_model)
def receive_message(self): """This method will attempt to extract a header and message. It will return a tuple of (header, message) and set whichever can be set so far (None otherwise). """ # Calculate the size of the buffer self.buffer.seek(0, os.SEEK_END) buffer_size = self.buffer.tell() # Check if a complete header is present if buffer_size < self.header_size: return (None, None) # Go to the beginning of the buffer self.buffer.seek(0) message_model = None message_header_serial = MessageHeaderSerializer() message_header = message_header_serial.deserialize(self.buffer) total_length = self.header_size + message_header.length # Incomplete message if buffer_size < total_length: self.buffer.seek(0, os.SEEK_END) return (message_header, None) payload = self.buffer.read(message_header.length) #print (codecs.encode (payload, 'hex')) remaining = self.buffer.read() self.buffer = BytesIO() self.buffer.write(remaining) payload_checksum = MessageHeaderSerializer.calc_checksum(payload) # Check if the checksum is valid if payload_checksum != message_header.checksum: msg = "Bad checksum for command %s" % message_header.command raise InvalidMessageChecksum(msg) if message_header.command in MESSAGE_MAPPING: #print (message_header.command) if message_header.command == 'block': message_model = Block.parse(BytesIO(payload)) #print (message_model.id ()) else: deserializer = MESSAGE_MAPPING[message_header.command]() message_model = deserializer.deserialize(BytesIO(payload)) return (message_header, message_model)
def got_message(self, message): if self.last_sent + 30 * 60 < time.time(): self.send_message(bitcoin.messages.msg_ping(self.ver_send)) self.print_debug("Received: %s" % repr(message)) if message.command == "version": self.send_message(bitcoin.messages.msg_verack(self.ver_send)) self.ver_send = min(self.ver_send, message.protover) elif message.command == "verack": self.ver_recv = self.ver_send elif message.command == "inv": self.request_objects(message.inv) elif message.command == "tx": self.new_tx_callback(Tx.tx_from_hex(message.tx.serialize().encode('hex'))) elif message.command == "block": self.new_block_callback(Block.parse(cStringIO.StringIO(message.block.serialize()))) # todo - use msg_block or block stream_serialize else: self.print_debug("received unknown message %s: %s" % (message.command, repr(message)))
def block_by_hash(digest): """ Get a block by hash. Args: digest: the hash of the block. Returns: A Block object. """ raw_block = get_block(digest) if raw_block is None: raw_block = requests.get( 'https://blockchain.info/rawblock/%s?format=hex' % digest).text raw_block = unhexlify(raw_block) put_block(digest, raw_block) block = Block.parse(io.BytesIO(raw_block)) return block
async def getblock(self, blockhash: str, mode: int=1): if mode == 2: raise NotImplementedError block_header = self.repository.headers.get_block_header(blockhash) if not block_header: return block = await self._get_block(block_header) if mode == 1: block_object = block.get('block_object', Block.parse(io.BytesIO(block['block_bytes']))) best_header = self.repository.headers.get_best_header() block['confirmations'] = best_header['block_height'] - block_header['block_height'] serialized = self._serialize_header(block_header) serialized['tx'] = [tx.id() for tx in block_object.txs] del block return serialized bb = block['block_bytes'] del block return binascii.hexlify(bb).decode()
def test_block(self): expected_checksum = '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1'.lower() block_data = h2b( "010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C552000000000" "007900A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796" "974CED66471B204C324703010000000100000000000000000000000000000000000000" "00000000000000000000000000FFFFFFFF0804ED66471B024001FFFFFFFF0100F2052A" "010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48AC178E1F5F7E" "EAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0" "EDAC000000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328" "E0D77C199CB3B57F010000008A4730440220556F61B84F16E637836D2E74B8CB784DE4" "0C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D4F3F7F831AC696748AD8D8E79AE" "B4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C2054E2F5" "96CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49" "ED0BA930743D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E9" "80ACE6FA885C5A89E4F27AA08988ACC0ADA41A000000001976A9145D17976537F30886" "5ED533CCCFDD76558CA3C8F088AC00000000010000000165148D894D3922EF5FFDA962" "BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EBF4" "834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377F" "D018281E77285EFC31E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0A" "A38C05FA33DD185F84C17F611E58A8658CE996D8B04395B99C7BE36529CAB7606900A0" "CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFFFFF02404B4C000000" "00001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE010000" "001976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000") # try to parse a block block = Block.parse(io.BytesIO(block_data)) print(block) assert b2h_rev(block.hash()) == expected_checksum for tx in block.txs: print(tx) for t in tx.txs_in: print(" %s" % t) for t in tx.txs_out: print(" %s" % t) block.check_merkle_hash()
'02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518'\ 'C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88'\ 'D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241'\ '1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000'\ '0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4'\ '830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED'\ '23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A'\ 'D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076'\ '3FD81A3DFBBB6FFFFFFFF02C05EECDE010000001976A914588554E6CC64E7343D77117DA7E01357A6111B798'\ '8AC404B4C00000000001976A914CA6EB218592F289999F13916EE32829AD587DBC588AC00000000010000000'\ '1BEF5C9225CB9FE3DEF929423FA36AAD9980B9D6F8F3070001ACF3A5FB389A69F000000004A493046022100F'\ 'B23B1E2F2FB8B96E04D220D385346290A9349F89BBBC5C225D5A56D931F8A8E022100F298EB28294B90C1BAF'\ '319DAB713E7CA721AAADD8FCC15F849DE7B0A6CF5412101FFFFFFFF0100F2052A010000001976A9146DDEA80'\ '71439951115469D0D2E2B80ECBCDD48DB88AC00000000') block_80971 = Block.parse(io.BytesIO(block_80971_data)) COINBASE_PUB_KEY_FROM_80971 = h2b("04cb6b6b4eadc96c7d08b21b29d0ada5f29f9378978cabdb602b8b65da08c8a93caab46"\ "f5abd59889bac704925942dd77a2116d10e0274cad944c71d3d1a670570") COINBASE_BYTES_FROM_80971 = h2b("04ed66471b02c301") def standard_tx(coins_from, coins_to): txs_in = [] unspents = [] for h, idx, tx_out in coins_from: txs_in.append(TxIn(h, idx)) unspents.append(tx_out) txs_out = [] for coin_value, bitcoin_address in coins_to:
import argparse from io import BytesIO from binascii import unhexlify from pycoin.block import Block from .models import merge_nulldatas_from_block_obj from .compatibility import bitcoind if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument('--block-hash', help='Notify of new block hash', type=str, required=True) args = parser.parse_args() block_hash = args.block_hash seralized_block = BytesIO(unhexlify(bitcoind.getblock(args.block_hash, False))) json_block = bitcoind.getblock(args.block_hash) block = Block.parse(seralized_block) merge_nulldatas_from_block_obj(block, block_hash, json_block['height'], verbose=True)
def test_validate(self): # block 80971 block_80971_cs = h2b( '00000000001126456C67A1F5F0FF0268F53B4F22E0531DC70C7B69746AF69DAC') block_80971_data = h2b('01000000950A1631FB9FAC411DFB173487B9E18018B7C6F7147E78C06258410000000000A881352F97F14B'\ 'F191B54915AE124E051B8FE6C3922C5082B34EAD503000FC34D891974CED66471B4016850A040100'\ '0000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF080'\ '4ED66471B02C301FFFFFFFF0100F2052A01000000434104CB6B6B4EADC96C7D08B21B29D0ADA5F29F937'\ '8978CABDB602B8B65DA08C8A93CAAB46F5ABD59889BAC704925942DD77A2116D10E0274CAD944C71D3D1A'\ '670570AC0000000001000000018C55ED829F16A4E43902940D3D33005264606D5F7D555B5F67EE4C033390'\ 'C2EB010000008A47304402202D1BF606648EDCDB124C1254930852D99188E1231715031CBEAEA80CCFD2B39A'\ '02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518'\ 'C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88'\ 'D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241'\ '1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000'\ '0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4'\ '830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED'\ '23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A'\ 'D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076'\ '3FD81A3DFBBB6FFFFFFFF02C05EECDE010000001976A914588554E6CC64E7343D77117DA7E01357A6111B798'\ '8AC404B4C00000000001976A914CA6EB218592F289999F13916EE32829AD587DBC588AC00000000010000000'\ '1BEF5C9225CB9FE3DEF929423FA36AAD9980B9D6F8F3070001ACF3A5FB389A69F000000004A493046022100F'\ 'B23B1E2F2FB8B96E04D220D385346290A9349F89BBBC5C225D5A56D931F8A8E022100F298EB28294B90C1BAF'\ '319DAB713E7CA721AAADD8FCC15F849DE7B0A6CF5412101FFFFFFFF0100F2052A010000001976A9146DDEA80'\ '71439951115469D0D2E2B80ECBCDD48DB88AC00000000') # block 80974 block_80974_cs = h2b( '0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1') block_80974_data = h2b('010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C55200000000000790'\ '0A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796974CED66471B204C3247030'\ '1000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0804ED6'\ '6471B024001FFFFFFFF0100F2052A010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48A'\ 'C178E1F5F7EEAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0EDAC000'\ '000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328E0D77C199CB3B57F010000008'\ 'A4730440220556F61B84F16E637836D2E74B8CB784DE40C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D'\ '4F3F7F831AC696748AD8D8E79AEB4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C'\ '2054E2F596CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49ED0BA930743'\ 'D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E980ACE6FA885C5A89E4F27AA08988AC'\ 'C0ADA41A000000001976A9145D17976537F308865ED533CCCFDD76558CA3C8F088AC000000000100000001651'\ '48D894D3922EF5FFDA962BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EB'\ 'F4834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377FD018281E77285EFC3'\ '1E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0AA38C05FA33DD185F84C17F611E58A8658CE'\ '996D8B04395B99C7BE36529CAB7606900A0CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFF'\ 'FFF02404B4C00000000001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE0100000'\ '01976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000') block_80971 = Block.parse(io.BytesIO(block_80971_data)) block_80974 = Block.parse(io.BytesIO(block_80974_data)) tx_db = {tx.hash(): tx for tx in block_80971.txs} tx_to_validate = block_80974.txs[2] self.assertEqual( "OP_DUP OP_HASH160 [d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb] OP_EQUALVERIFY OP_CHECKSIG", tools.disassemble(tx_to_validate.txs_out[0].script)) self.assertEqual( tx_to_validate.id(), "7c4f5385050c18aa8df2ba50da566bbab68635999cc99b75124863da1594195b") tx_to_validate.unspents_from_db(tx_db) self.assertEqual(tx_to_validate.bad_signature_count(), 0) # now, let's corrupt the Tx and see what happens tx_out = tx_to_validate.txs_out[1] disassembly = tools.disassemble(tx_out.script) tx_out.script = tools.compile(disassembly) self.assertEqual(tx_to_validate.bad_signature_count(), 0) disassembly = disassembly.replace( "9661a79ae1f6d487af3420c13e649d6df3747fc2", "9661a79ae1f6d487af3420c13e649d6df3747fc3") tx_out.script = tools.compile(disassembly) self.assertEqual(tx_to_validate.bad_signature_count(), 1) self.assertFalse(tx_to_validate.is_signature_ok(0))
def test_validate(self): # block 80971 block_80971_cs = h2b("00000000001126456C67A1F5F0FF0268F53B4F22E0531DC70C7B69746AF69DAC") block_80971_data = h2b( "01000000950A1631FB9FAC411DFB173487B9E18018B7C6F7147E78C06258410000000000A881352F97F14B" "F191B54915AE124E051B8FE6C3922C5082B34EAD503000FC34D891974CED66471B4016850A040100" "0000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF080" "4ED66471B02C301FFFFFFFF0100F2052A01000000434104CB6B6B4EADC96C7D08B21B29D0ADA5F29F937" "8978CABDB602B8B65DA08C8A93CAAB46F5ABD59889BAC704925942DD77A2116D10E0274CAD944C71D3D1A" "670570AC0000000001000000018C55ED829F16A4E43902940D3D33005264606D5F7D555B5F67EE4C033390" "C2EB010000008A47304402202D1BF606648EDCDB124C1254930852D99188E1231715031CBEAEA80CCFD2B39A" "02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518" "C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88" "D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241" "1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000" "0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4" "830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED" "23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A" "D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076" "3FD81A3DFBBB6FFFFFFFF02C05EECDE010000001976A914588554E6CC64E7343D77117DA7E01357A6111B798" "8AC404B4C00000000001976A914CA6EB218592F289999F13916EE32829AD587DBC588AC00000000010000000" "1BEF5C9225CB9FE3DEF929423FA36AAD9980B9D6F8F3070001ACF3A5FB389A69F000000004A493046022100F" "B23B1E2F2FB8B96E04D220D385346290A9349F89BBBC5C225D5A56D931F8A8E022100F298EB28294B90C1BAF" "319DAB713E7CA721AAADD8FCC15F849DE7B0A6CF5412101FFFFFFFF0100F2052A010000001976A9146DDEA80" "71439951115469D0D2E2B80ECBCDD48DB88AC00000000" ) # block 80974 block_80974_cs = h2b("0000000000089F7910F6755C10EA2795EC368A29B435D80770AD78493A6FECF1") block_80974_data = h2b( "010000007480150B299A16BBCE5CCDB1D1BBC65CFC5893B01E6619107C55200000000000790" "0A2B203D24C69710AB6A94BEB937E1B1ADD64C2327E268D8C3E5F8B41DBED8796974CED66471B204C3247030" "1000000010000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0804ED6" "6471B024001FFFFFFFF0100F2052A010000004341045FEE68BAB9915C4EDCA4C680420ED28BBC369ED84D48A" "C178E1F5F7EEAC455BBE270DABA06802145854B5E29F0A7F816E2DF906E0FE4F6D5B4C9B92940E4F0EDAC000" "000000100000001F7B30415D1A7BF6DB91CB2A272767C6799D721A4178AA328E0D77C199CB3B57F010000008" "A4730440220556F61B84F16E637836D2E74B8CB784DE40C28FE3EF93CCB7406504EE9C7CAA5022043BD4749D" "4F3F7F831AC696748AD8D8E79AEB4A1C539E742AA3256910FC88E170141049A414D94345712893A828DE57B4C" "2054E2F596CDCA9D0B4451BA1CA5F8847830B9BE6E196450E6ABB21C540EA31BE310271AA00A49ED0BA930743" "D1ED465BAD0FFFFFFFF0200E1F505000000001976A914529A63393D63E980ACE6FA885C5A89E4F27AA08988AC" "C0ADA41A000000001976A9145D17976537F308865ED533CCCFDD76558CA3C8F088AC000000000100000001651" "48D894D3922EF5FFDA962BE26016635C933D470C8B0AB7618E869E3F70E3C000000008B48304502207F5779EB" "F4834FEAEFF4D250898324EB5C0833B16D7AF4C1CB0F66F50FCF6E85022100B78A65377FD018281E77285EFC3" "1E5B9BA7CB7E20E015CF6B7FA3E4A466DD195014104072AD79E0AA38C05FA33DD185F84C17F611E58A8658CE" "996D8B04395B99C7BE36529CAB7606900A0CD5A7AEBC6B233EA8E0FE60943054C63620E05E5B85F0426FFFFF" "FFF02404B4C00000000001976A914D4CAA8447532CA8EE4C80A1AE1D230A01E22BFDB88AC8013A0DE0100000" "01976A9149661A79AE1F6D487AF3420C13E649D6DF3747FC288AC00000000" ) block_80971 = Block.parse(io.BytesIO(block_80971_data)) block_80974 = Block.parse(io.BytesIO(block_80974_data)) tx_db = {tx.hash(): tx for tx in block_80971.txs} def tx_out_for_hash_index_f(tx_hash, tx_out_idx): tx = tx_db.get(tx_hash) return tx.txs_out[tx_out_idx] tx_to_validate = block_80974.txs[2] self.assertEqual( "OP_DUP OP_HASH160 d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb OP_EQUALVERIFY OP_CHECKSIG", tools.disassemble(tx_to_validate.txs_out[0].script), ) self.assertEqual(tx_to_validate.id(), "7c4f5385050c18aa8df2ba50da566bbab68635999cc99b75124863da1594195b") tx_to_validate.validate(tx_out_for_hash_index_f) # now, let's corrupt the Tx and see what happens tx_out = tx_to_validate.txs_out[1] disassembly = tools.disassemble(tx_out.script) tx_out.script = tools.compile(disassembly) tx_to_validate.validate(tx_out_for_hash_index_f) disassembly = disassembly.replace( "9661a79ae1f6d487af3420c13e649d6df3747fc2", "9661a79ae1f6d487af3420c13e649d6df3747fc3" ) tx_out.script = tools.compile(disassembly) with self.assertRaises(ValidationFailureError) as cm: tx_to_validate.validate(tx_out_for_hash_index_f) exception = cm.exception self.assertEqual( exception.args[0], "Tx 3c0ef7e369e81876abb0c870d433c935660126be62a9fd5fef22394d898d1465 TxIn index 0 script did not verify", )
def block(args, parser): for f in args.block_file: block = Block.parse(f) dump_block(block) print('')
'02201FA9D6EE7A1763580E342474FC1AEF59B0468F98479953437F525063E25675DE014104A01F763CFBF5E518'\ 'C628939158AF3DC0CAAC35C4BA7BC1CE8B7E634E8CDC44E15F0296B250282BD649BAA8398D199F2424FCDCD88'\ 'D3A9ED186E4FD3CB9BF57CFFFFFFFFF02404B4C00000000001976A9148156FF75BEF24B35ACCE3C05289A241'\ '1E1B0E57988AC00AA38DF010000001976A914BC7E692A5FFE95A596712F5ED83393B3002E452E88AC000000'\ '0001000000019C97AFDF6C9A31FFA86D71EA79A079001E2B59EE408FD418498219400639AC0A010000008B4'\ '830450220363CFFAE09599397B21E6D8A8073FB1DFBE06B6ACDD0F2F7D3FEA86CA9C3F605022100FA255A6ED'\ '23FD825C759EF1A885A31CAD0989606CA8A3A16657D50FE3CEF5828014104FF444BAC08308B9EC97F56A652A'\ 'D8866E0BA804DA97868909999566CB377F4A2C8F1000E83B496868F3A282E1A34DF78565B65C15C3FA21A076'\ '3FD81A3DFBBB6FFFFFFFF02C05EECDE010000001976A914588554E6CC64E7343D77117DA7E01357A6111B798'\ '8AC404B4C00000000001976A914CA6EB218592F289999F13916EE32829AD587DBC588AC00000000010000000'\ '1BEF5C9225CB9FE3DEF929423FA36AAD9980B9D6F8F3070001ACF3A5FB389A69F000000004A493046022100F'\ 'B23B1E2F2FB8B96E04D220D385346290A9349F89BBBC5C225D5A56D931F8A8E022100F298EB28294B90C1BAF'\ '319DAB713E7CA721AAADD8FCC15F849DE7B0A6CF5412101FFFFFFFF0100F2052A010000001976A9146DDEA80'\ '71439951115469D0D2E2B80ECBCDD48DB88AC00000000'); block_80971 = Block.parse(io.BytesIO(block_80971_data)) COINBASE_PUB_KEY_FROM_80971 = h2b("04cb6b6b4eadc96c7d08b21b29d0ada5f29f9378978cabdb602b8b65da08c8a93caab46"\ "f5abd59889bac704925942dd77a2116d10e0274cad944c71d3d1a670570") COINBASE_BYTES_FROM_80971 = h2b("04ed66471b02c301") def standard_tx(coins_from, coins_to): txs_in = [] unspents = [] for h, idx, tx_out in coins_from: txs_in.append(TxIn(h, idx)) unspents.append(tx_out) txs_out = [] for coin_value, bitcoin_address in coins_to: txs_out.append(TxOut(coin_value, standard_tx_out_script(bitcoin_address)))
#!/usr/bin/env python3 import argparse import json import sys import io from binascii import unhexlify, hexlify from bitcoinrpc import connect_to_local from pycoin.block import Block from models import txs, known_txs, unprocessed_txs, addr_to_uid, Account, known_blocks, all_addresses from wallet import process_tx_initial parser = argparse.ArgumentParser() parser.add_argument('--blockhash') args = parser.parse_args() blockhash = args.blockhash if blockhash in known_blocks: sys.exit() bitcoind = connect_to_local() block_hex = bitcoind.getblock(blockhash, False) block = Block.parse(io.BytesIO(unhexlify(block_hex))) for tx in block.txs: process_tx_initial(tx) known_blocks.add(blockhash)
def block(args, parser): network = network_for_netcode(get_current_netcode()) for f in args.block_file: block = Block.parse(f) dump_block(block, network) print('')