I'm reading Programming Bitcoin. And in Chapter13, I am confused with how the witness part is serialized and parsed. The auther gives the following method 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 serialize 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 can't understand are the last for loops in both methods. In my understanding, these are where segwit part get serialized and deserialized, and these codes should be in one-to-one correspondence. As they do in the first half part. But they don't match in the for loops of the last half part. I mean:
- For "num_items = read_varint(s)", there should be a "result += encode_varint(len(tx_in.witness))".
- For "item_len = read_varint(s)", there should be a "result += encode_varint(len(item))".
- And for "if item_len == 0:", I don't know what this if do and where the corresponding serialization logic is.
So is anything wrong with my understanding of the segwit part logic?