예제 #1
0
 def parse(cls, s, version_msg=False):
     # Documentation says that the `time` field ins't present in version messages ...
     if version_msg:
         time = None
     else:
         time = little_endian_to_int(s.read(4))
     services = little_endian_to_int(s.read(8))
     ip = little_endian_to_int(s.read(16))
     port = little_endian_to_int(s.read(2))
     return cls(services, ip, port, time)
예제 #2
0
 def parse(cls, s):
     version = little_endian_to_int(s.read(4))
     #prev_block = s.read(32)[::-1]  # little endian
     prev_block = little_endian_to_int(s.read(32))
     #merkle_root = s.read(32)[::-1]  # little endian
     merkle_root = little_endian_to_int(s.read(32))
     timestamp = little_endian_to_int(s.read(4))
     bits = s.read(4)
     nonce = s.read(4)
     txn_count = read_varint(s)  # apparently this is always 0?
     return cls(version, prev_block, merkle_root, timestamp, bits, nonce,
                txn_count)
예제 #3
0
 def parse(cls, s):
     '''Takes a byte stream and parses the tx_input at the start
     return a TxIn object
     '''
     # s.read(n) will return n bytes
     # prev_tx is 32 bytes, little endian
     prev_tx = s.read(32)[::-1]
     # prev_index is 4 bytes, little endian, interpret as int
     prev_index = little_endian_to_int(s.read(4))
     # script_sig is a variable field (length followed by the data)
     # get the length by using read_varint(s)
     script_sig_length = read_varint(s)
     script_sig = s.read(script_sig_length)
     # sequence is 4 bytes, little-endian, interpret as int
     sequence = little_endian_to_int(s.read(4))
     # return an instance of the class (cls(...))
     return cls(prev_tx, prev_index, script_sig, sequence)
예제 #4
0
 def target(self):
     '''Returns the proof-of-work target based on the bits'''
     # last byte is exponent
     exponent = self.bits[-1]
     # the first three bytes are the coefficient in little endian
     coefficient = little_endian_to_int(self.bits[:-1])
     # the formula is:
     # coefficient * 2**(8*(exponent-3))
     return coefficient * 2**(8 * (exponent - 3))
예제 #5
0
async def read_message(reader):
    magic = await reader.read(4)
    if magic != NETWORK_MAGIC:
        raise RuntimeError("Network Magic not at beginning of stream")
    command = await reader.read(12)
    payload_length = little_endian_to_int(await reader.read(4))
    checksum = await reader.read(4)
    payload = await reader.read(payload_length)
    if double_sha256(payload)[:4] != checksum:
        raise RuntimeError("Payload and Checksum do not match")
    return Message(command, payload)
예제 #6
0
 def parse(cls, s):
     '''Takes a byte stream and parses the tx_output at the start
     return a TxOut object
     '''
     # s.read(n) will return n bytes
     # amount is 8 bytes, little endian, interpret as int
     amount = little_endian_to_int(s.read(8))
     # script_pubkey is a variable field (length followed by the data)
     # get the length by using read_varint(s)
     script_pubkey_length = read_varint(s)
     script_pubkey = s.read(script_pubkey_length)
     # return an instance of the class (cls(...))
     return cls(amount, script_pubkey)
예제 #7
0
 def parse(cls, s):
     '''Takes a byte stream and parses the transaction at the start
     return a Tx object
     '''
     # s.read(n) will return n bytes
     # version has 4 bytes, little-endian, interpret as int
     version = little_endian_to_int(s.read(4))
     # num_inputs is a varint, use read_varint(s)
     num_inputs = read_varint(s)
     # each input needs parsing
     inputs = []
     for _ in range(num_inputs):
         inputs.append(TxIn.parse(s))
     # num_outputs is a varint, use read_varint(s)
     num_outputs = read_varint(s)
     # each output needs parsing
     outputs = []
     for _ in range(num_outputs):
         outputs.append(TxOut.parse(s))
     # locktime is 4 bytes, little-endian
     locktime = little_endian_to_int(s.read(4))
     # return an instance of the class (cls(...))
     return cls(version, inputs, outputs, locktime)
예제 #8
0
 def parse(cls, s):
     version = little_endian_to_int(s.read(4))
     services = little_endian_to_int(s.read(8))
     timestamp = little_endian_to_int(s.read(8))
     addr_recv = Address.parse(io.BytesIO(s.read(26)), version_msg=True)
     addr_from = Address.parse(io.BytesIO(s.read(26)), version_msg=True)
     nonce = little_endian_to_int(s.read(8))
     user_agent = read_varstr(
         s)  # Should we convert stuff like to to strings?
     start_height = little_endian_to_int(s.read(4))
     relay = little_endian_to_int(s.read(1))
     return cls(version, services, timestamp, addr_recv, addr_from, nonce,
                user_agent, start_height, relay)
예제 #9
0
    def parse(cls, s):
        magic = consume_stream(s, 4)
        if magic != NETWORK_MAGIC:
            raise ValueError('magic is not right')

        command = parse_command(consume_stream(s, 12))
        payload_length = little_endian_to_int(consume_stream(s, 4))
        checksum = consume_stream(s, 4)
        payload = consume_stream(s, payload_length)
        calculated_checksum = double_sha256(payload)[:4]

        if calculated_checksum != checksum:
            raise RuntimeError('checksum does not match')

        if payload_length != len(payload):
            raise RuntimeError(
                "Tried to read {payload_length} bytes, only received {len(payload)} bytes"
            )

        return cls(command, payload)
예제 #10
0
 def pow(self):
     s = self.serialize()
     sha = double_sha256(s)
     return little_endian_to_int(sha)
예제 #11
0
 def parse(cls, s):
     type_ = little_endian_to_int(s.read(4))
     hash_ = s.read(32)
     return cls(type_, hash_)