예제 #1
0
파일: tx.py 프로젝트: yeonuk44/bitcoinpy
def parse_segwit(s):
    tx = {
        "version": 1,
        "mark": None,
        "flag": None,
        "txi.count": 0,
        "txis": [],
        "txo.count": 0,
        "txos": [],
        # "wits": append to each txi
        "locktime": 0,
        "hash_all": None
    }
    tx["version"] = util.little_endian_to_int(s.read(4))
    tx["mark"] = s.read(1)
    tx["flag"] = s.read(1)
    if tx["mark"] != b"\x00" and tx["flag"] != b"\x01":
        raise RuntimeError('not a segwit transaction {}'.format(tx["flag"]))
    tx["txi.count"] = util.read_varint(s)
    for _ in range(tx["txi.count"]):
        tx["txis"].append(parse_txi(s))
    tx["txo.count"] = util.read_varint(s)
    for _ in range(tx["txo.count"]):
        tx["txos"].append(parse_txo(s))
    # parse witness script
    for txi in tx["txis"]:
        count = util.read_varint(s)
        for _ in range(count):
            length = util.read_varint(s)
            if length == 0:  # ?
                txi["wits"].append(0)
            else:
                txi["wits"].append(s.read(length))
    tx["locktime"] = util.little_endian_to_int(s.read(4))  # locktime is an integer in 4 bytes, little-endian
    return tx
예제 #2
0
    def _read_msg(self):
        msg_type = read_varint(self.istream)
        if msg_type == MSG_TICK or msg_type == MSG_STRINGS:
            raise Exception('_read_msg called for INTERNAL msg_type:{}'.format(msg_type))

        msg_size = read_varint(self.istream)
        if msg_size <= MAX_MSG_SIZE:
            msg = self.msg_cls()
            msg.ParseFromString(self.istream.read(msg_size))
            return Msg(msg, self.lookup_string)
예제 #3
0
def parse_headers(s):
    # number of headers is in a varint
    num_headers = util.read_varint(s)
    # initialize the blocks array
    blocks = []
    # loop through number of headers times
    for _ in range(num_headers):
        # add a block to the blocks array by parsing the stream
        blocks.append(block.parse(s))
        # read the next varint (num_txs)
        num_txs = util.read_varint(s)
        # num_txs should be 0 or raise a RuntimeError
        if num_txs != 0:
            raise RuntimeError('number of txs not 0')

    return {'blocks': blocks}
예제 #4
0
    def _has_next(self):
        try:
            while True:
                pos = self.istream.tell()
                msg_type = read_varint(self.istream)

                if   msg_type == MSG_TICK:
                    self.tick = read_varint(self.istream)
                elif msg_type == MSG_STRINGS:
                    return False # at end of file
                elif msg_type == self.msg_id:
                    self.istream.seek(pos)
                    return True
                else:
                    raise MalformedAspect('Invalid msg_type:{}, expected [{},{},{}]'.format(msg_type, self.msg_id, MSG_TICK, MSG_STRINGS))

        except Exception as e:
            log.warning('Exception: {}'.format(e))
            return False
예제 #5
0
파일: tx.py 프로젝트: yeonuk44/bitcoinpy
def parse_legacy(s):
    tx = {
        "version": 1,
        # "mark": None,
        # "flag": None,
        "txi.count": 0,
        "txis": [],
        "txo.count": 0,
        "txos": [],
        # "wits": None,
        "locktime": 0
    }
    tx["version"] = util.little_endian_to_int(s.read(4))
    tx["txi.count"] = util.read_varint(s)
    for _ in range(tx["txi.count"]):
        tx["txis"].append(parse_txi(s))
    tx["txo.count"] = util.read_varint(s)
    for _ in range(tx["txo.count"]):
        tx["txos"].append(parse_txo(s))
    tx["locktime"] = util.little_endian_to_int(s.read(4))  # locktime is an integer in 4 bytes, little-endian
    return tx
예제 #6
0
def parse_merkleblock(s):
    """Takes a byte stream and parses a merkle block. Returns a Merkle Block object"""
    # version - 4 bytes, Little-Endian integer
    version = util.little_endian_to_int(s.read(4))
    # prev_block - 32 bytes, Little-Endian (use [::-1])
    prev_block_hash = s.read(32)[::-1]
    # merkle_root - 32 bytes, Little-Endian (use [::-1])
    merkle_root = s.read(32)[::-1]
    # timestamp - 4 bytes, Little-Endian integer
    timestamp = util.little_endian_to_int(s.read(4))
    # bits - 4 bytes
    bits = s.read(4)
    # nonce - 4 bytes
    nonce = s.read(4)
    # total transactions in block - 4 bytes, Little-Endian integer
    total = util.little_endian_to_int(s.read(4))
    # number of transaction hashes - varint
    num_hashes = util.read_varint(s)
    # each transaction is 32 bytes, Little-Endian
    hashes = []
    for _ in range(num_hashes):
        hashes.append(s.read(32)[::-1])
    # length of flags field - varint
    flags_length = util.read_varint(s)
    # read the flags field
    flags = s.read(flags_length)

    return {
        'version': version,
        'prev_block_hash': prev_block_hash,
        'merkle_root': merkle_root,
        'timestamp': timestamp,
        'bits': bits,
        'nonce': nonce,
        'total': total,
        'hashes': hashes,
        'flags': flags
    }
예제 #7
0
    def __init__(self, aspect_path, raw_reader):
        try:
            self.msg_cls = mapper.aspect_map[aspect_path]['cls']
            self.msg_id  = mapper.aspect_map[aspect_path]['id']
        except KeyError as e:
            raise err.UnknownAspectPath(aspect_path)

        self.raw = raw_reader

        self.aspect_path = aspect_path
        self.string_table = self.raw.read_string_table()
        self.tick = 0

        self.istream = self.raw.get_stream()
        try:
            self.replay_id = read_varint(self.istream)
        except Exception as e:
            raise err.MalformedAspect(e)
예제 #8
0
def parse(s):
    length = util.read_varint(s)
    commands = []  # initialize the commands array
    count = 0  # initialize the number of bytes we've read to 0
    while count < length:  # loop until we've read length bytes
        temp = s.read(1)[0]  # get code
        count += 1  # increment the bytes we've read
        if 1 <= temp <= 75:  # if the current byte is between 1 and 75 inclusive
            commands.append(s.read(temp))  # add the next n bytes as an cmd
            count += temp  # increase the count by n
        elif temp == 76:  # op_pushdata1
            data_length = util.little_endian_to_int(s.read(1))
            commands.append(s.read(data_length))
            count += data_length + 1
        elif temp == 77:  # op_pushdata2
            data_length = util.little_endian_to_int(s.read(2))
            commands.append(s.read(data_length))
            count += data_length + 2
        else:  # we have an op_code. set the current byte to op_code
            commands.append(temp)  # add the op_code to the list of commands
    if count != length:
        raise SyntaxError('parsing script failed')

    return length, commands