Separate watch – How is the SetWit portion of a transaction serialized and parsed?


I read Bitcoin programming. And in Chapter 13, I get confused about how the witness portion is sequenced and analyzed. auther gives the following way to parse it:

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:        # where I can't understand 
                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)

And the following code to concatenate it:

def serialize_segwit(self):
    result = int_to_little_endian(self.version, 4)
    result += b'\x00\x01'  
    result += encode_varint(len(self.tx_ins))
    for tx_in in self.tx_ins:
        result += tx_in.serialize()
    result += encode_varint(len(self.tx_outs))
    for tx_out in self.tx_outs:
        result += tx_out.serialize()
    for tx_in in self.tx_ins:  
        result += int_to_little_endian(len(tx_in.witness), 1)
        for item in tx_in.witness:
            if type(item) == int:
                result += int_to_little_endian(item, 1)
            else:
                result += encode_varint(len(item)) + item
    result += int_to_little_endian(self.locktime, 4)
    return result

What I don’t understand is the last for loops in both methods. To my understanding, these are the places where the segwit part is serialized and deserialized, and these codes should be in one-to-one correspondence. As they did in the first half. But they don’t match in for loops in the last part of the half. I mean:

  • For “num_items = read_varint(s)” there should be “result + = encode_varint (len (tx_in.witness))”.
  • For “item_len = read_varint(s)” there should be “result + = encode_varint (len(item))”.
  • And for “if item_len == 0:” , I don’t know if this is happening and where the corresponding chaining logic is.

So is there something wrong with my understanding of the segwit part logic?



Source link

Related Posts