예제 #1
0
 def parse(cls, s):
     version = little_endian_to_int(s.read(4))
     prev_block = s.read(32)[::-1]
     merkle_root = s.read(32)[::-1]
     timestamp = little_endian_to_int(s.read(4))
     bits = s.read(4)
     nonce = s.read(4)
     total = little_endian_to_int(s.read(4))
     num_hashes = read_varint(s)
     hashes = []
     for _ in range(num_hashes):
         hashes.append(s.read(32)[::-1])
     flags_length = read_varint(s)
     flags = s.read(flags_length)
     return cls(
         version,
         prev_block,
         merkle_root,
         timestamp,
         bits,
         nonce,
         total,
         hashes,
         flags,
     )
예제 #2
0
 def parse_segwit(cls, s, testnet=False):
     version = little_endian_to_int(s.read(4))
     marker = s.read(2)
     if marker != b"\x00\x01":
         raise RuntimeError("Not a segwit transaction {}".format(marker))
     num_inputs = read_varint(s)
     inputs = []
     for _ in range(num_inputs):
         inputs.append(TxIn.parse(s))
     num_outputs = read_varint(s)
     outputs = []
     for _ in range(num_outputs):
         outputs.append(TxOut.parse(s))
     for tx_in in inputs:
         num_items = read_varint(s)
         items = []
         for _ in range(num_items):
             item_len = read_varint(s)
             if item_len == 0:
                 items.append(0)
             else:
                 items.append(s.read(item_len))
         tx_in.witness = items
     locktime = little_endian_to_int(s.read(4))
     return cls(version, inputs, outputs, locktime, testnet=testnet, segwit=True)
예제 #3
0
파일: Script.py 프로젝트: pmuens/pybtc
 def parse(cls, s):
     length = read_varint(s)
     cmds = []
     count = 0
     while count < length:
         current = s.read(1)
         count += 1
         current_byte = current[0]
         if current_byte >= 1 and current_byte <= 75:
             n = current_byte
             cmds.append(s.read(n))
             count += n
         # OP_PUSHDATA1
         elif current_byte == 76:
             data_length = little_endian_to_int(s.read(1))
             cmds.append(s.read(data_length))
             count += data_length + 1
         # OP_PUSHDATA2
         elif current_byte == 77:
             data_length = little_endian_to_int(s.read(2))
             cmds.append(s.read(data_length))
             count += data_length + 2
         else:
             op_code = current_byte
             cmds.append(op_code)
     if count != length:
         raise SyntaxError("parsing script failed")
     return cls(cmds)
예제 #4
0
 def parse(cls, s):
     version = little_endian_to_int(s.read(4))
     prev_block = s.read(32)[::-1]
     merkle_root = s.read(32)[::-1]
     timestamp = little_endian_to_int(s.read(4))
     bits = s.read(4)
     nonce = s.read(4)
     return cls(version, prev_block, merkle_root, timestamp, bits, nonce)
예제 #5
0
 def parse_legacy(cls, s, testnet=False):
     version = little_endian_to_int(s.read(4))
     num_inputs = read_varint(s)
     inputs = []
     for _ in range(num_inputs):
         inputs.append(TxIn.parse(s))
     num_outputs = read_varint(s)
     outputs = []
     for _ in range(num_outputs):
         outputs.append(TxOut.parse(s))
     locktime = little_endian_to_int(s.read(4))
     return cls(version, inputs, outputs, locktime, testnet=testnet, segwit=False)
예제 #6
0
 def load_cache(cls, filename):
     disk_cache = json.loads(open(filename, "r").read())
     for k, raw_hex in disk_cache.items():
         raw = bytes.fromhex(raw_hex)
         if raw[4] == 0:
             raw = raw[:4] + raw[6:]
             tx = Tx.parse(BytesIO(raw))
             tx.locktime = little_endian_to_int(raw[-4:])
         else:
             tx = Tx.parse(BytesIO(raw))
         cls.cache[k] = tx
예제 #7
0
    def test_parse(self):
        from io import BytesIO

        hex_merkle_block = "00000020df3b053dc46f162a9b00c7f0d5124e2676d47bbe7c5d0793a500000000000000ef445fef2ed495c275892206ca533e7411907971013ab83e3b47bd0d692d14d4dc7c835b67d8001ac157e670bf0d00000aba412a0d1480e370173072c9562becffe87aa661c1e4a6dbc305d38ec5dc088a7cf92e6458aca7b32edae818f9c2c98c37e06bf72ae0ce80649a38655ee1e27d34d9421d940b16732f24b94023e9d572a7f9ab8023434a4feb532d2adfc8c2c2158785d1bd04eb99df2e86c54bc13e139862897217400def5d72c280222c4cbaee7261831e1550dbb8fa82853e9fe506fc5fda3f7b919d8fe74b6282f92763cef8e625f977af7c8619c32a369b832bc2d051ecd9c73c51e76370ceabd4f25097c256597fa898d404ed53425de608ac6bfe426f6e2bb457f1c554866eb69dcb8d6bf6f880e9a59b3cd053e6c7060eeacaacf4dac6697dac20e4bd3f38a2ea2543d1ab7953e3430790a9f81e1c67f5b58c825acf46bd02848384eebe9af917274cdfbb1a28a5d58a23a17977def0de10d644258d9c54f886d47d293a411cb6226103b55635"
        mb = MerkleBlock.parse(BytesIO(bytes.fromhex(hex_merkle_block)))
        version = 0x20000000
        self.assertEqual(mb.version, version)
        merkle_root_hex = (
            "ef445fef2ed495c275892206ca533e7411907971013ab83e3b47bd0d692d14d4")
        merkle_root = bytes.fromhex(merkle_root_hex)[::-1]
        self.assertEqual(mb.merkle_root, merkle_root)
        prev_block_hex = (
            "df3b053dc46f162a9b00c7f0d5124e2676d47bbe7c5d0793a500000000000000")
        prev_block = bytes.fromhex(prev_block_hex)[::-1]
        self.assertEqual(mb.prev_block, prev_block)
        timestamp = little_endian_to_int(bytes.fromhex("dc7c835b"))
        self.assertEqual(mb.timestamp, timestamp)
        bits = bytes.fromhex("67d8001a")
        self.assertEqual(mb.bits, bits)
        nonce = bytes.fromhex("c157e670")
        self.assertEqual(mb.nonce, nonce)
        total = little_endian_to_int(bytes.fromhex("bf0d0000"))
        self.assertEqual(mb.total, total)
        hex_hashes = [
            "ba412a0d1480e370173072c9562becffe87aa661c1e4a6dbc305d38ec5dc088a",
            "7cf92e6458aca7b32edae818f9c2c98c37e06bf72ae0ce80649a38655ee1e27d",
            "34d9421d940b16732f24b94023e9d572a7f9ab8023434a4feb532d2adfc8c2c2",
            "158785d1bd04eb99df2e86c54bc13e139862897217400def5d72c280222c4cba",
            "ee7261831e1550dbb8fa82853e9fe506fc5fda3f7b919d8fe74b6282f92763ce",
            "f8e625f977af7c8619c32a369b832bc2d051ecd9c73c51e76370ceabd4f25097",
            "c256597fa898d404ed53425de608ac6bfe426f6e2bb457f1c554866eb69dcb8d",
            "6bf6f880e9a59b3cd053e6c7060eeacaacf4dac6697dac20e4bd3f38a2ea2543",
            "d1ab7953e3430790a9f81e1c67f5b58c825acf46bd02848384eebe9af917274c",
            "dfbb1a28a5d58a23a17977def0de10d644258d9c54f886d47d293a411cb62261",
        ]
        hashes = [bytes.fromhex(h)[::-1] for h in hex_hashes]
        self.assertEqual(mb.hashes, hashes)
        flags = bytes.fromhex("b55635")
        self.assertEqual(mb.flags, flags)
예제 #8
0
 def fetch(cls, tx_id, testnet=False, fresh=False):
     if fresh or (tx_id not in cls.cache):
         url = "{}/tx/{}/hex".format(cls.get_url(testnet), tx_id)
         response = requests.get(url)
         try:
             raw = bytes.fromhex(response.text.strip())
         except ValueError:
             raise ValueError("unexpected response: {}".format(response.text))
         if raw[4] == 0:
             raw = raw[:4] + raw[6:]
             tx = Tx.parse(BytesIO(raw), testnet)
             tx.locktime = little_endian_to_int(raw[-4:])
         else:
             tx = Tx.parse(BytesIO(raw), testnet)
         if tx.id() != tx_id:
             raise ValueError("not the same id: {} vs {}".format(tx.id(), tx_id))
         cls.cache[tx_id] = tx
     cls.cache[tx_id].testnet = testnet
     return cls.cache[tx_id]
예제 #9
0
 def parse(cls, s, testnet=False):
     magic = s.read(4)
     if magic == b"":
         raise IOError("Connection reset!")
     if testnet:
         expected_magic = TESTNET_NETWORK_MAGIC
     else:
         expected_magic = NETWORK_MAGIC
     if magic != expected_magic:
         raise SyntaxError("magic is not right {} vs {}".format(
             magic.hex(), expected_magic.hex()))
     command = s.read(12)
     command = command.strip(b"\x00")
     payload_length = little_endian_to_int(s.read(4))
     checksum = s.read(4)
     payload = s.read(payload_length)
     calculated_checksum = hash256(payload)[:4]
     if calculated_checksum != checksum:
         raise IOError("checksum does not match")
     return cls(command, payload, testnet=testnet)
예제 #10
0
 def coinbase_height(self):
     if not self.is_coinbase():
         return None
     first_cmd = self.tx_ins[0].script_sig.cmds[0]
     return little_endian_to_int(first_cmd)
예제 #11
0
 def parse(cls, s):
     amount = little_endian_to_int(s.read(8))
     script_pubkey = Script.parse(s)
     return cls(amount, script_pubkey)
예제 #12
0
 def parse(cls, s):
     prev_tx = s.read(32)[::-1]
     prev_index = little_endian_to_int(s.read(4))
     script_sig = Script.parse(s)
     sequence = little_endian_to_int(s.read(4))
     return cls(prev_tx, prev_index, script_sig, sequence)
예제 #13
0
 def check_pow(self):
     sha = hash256(self.serialize())
     proof = little_endian_to_int(sha)
     return proof < self.target()