@@ -91,30 +91,87 @@ def write(self, file, item):
91
91
('port' , pack .IntType (16 , 'big' )),
92
92
])
93
93
94
- tx_type = pack .ComposedType ([
95
- ('version' , pack .IntType (32 )),
96
- ('tx_ins' , pack .ListType (pack .ComposedType ([
97
- ('previous_output' , pack .PossiblyNoneType (dict (hash = 0 , index = 2 ** 32 - 1 ), pack .ComposedType ([
98
- ('hash' , pack .IntType (256 )),
99
- ('index' , pack .IntType (32 )),
100
- ]))),
101
- ('script' , pack .VarStrType ()),
102
- ('sequence' , pack .PossiblyNoneType (2 ** 32 - 1 , pack .IntType (32 ))),
103
- ]))),
104
- ('tx_outs' , pack .ListType (pack .ComposedType ([
105
- ('value' , pack .IntType (64 )),
106
- ('script' , pack .VarStrType ()),
94
+ def is_segwit_tx (tx ):
95
+ return tx .get ('marker' , - 1 ) == 0 and tx .get ('flag' , - 1 ) >= 1
96
+
97
+ tx_in_type = pack .ComposedType ([
98
+ ('previous_output' , pack .PossiblyNoneType (dict (hash = 0 , index = 2 ** 32 - 1 ), pack .ComposedType ([
99
+ ('hash' , pack .IntType (256 )),
100
+ ('index' , pack .IntType (32 )),
107
101
]))),
108
- ('lock_time' , pack .IntType (32 )),
102
+ ('script' , pack .VarStrType ()),
103
+ ('sequence' , pack .PossiblyNoneType (2 ** 32 - 1 , pack .IntType (32 ))),
109
104
])
110
105
106
+ tx_out_type = pack .ComposedType ([
107
+ ('value' , pack .IntType (64 )),
108
+ ('script' , pack .VarStrType ()),
109
+ ])
110
+
111
+ tx_id_type = pack .ComposedType ([
112
+ ('version' , pack .IntType (32 )),
113
+ ('tx_ins' , pack .ListType (tx_in_type )),
114
+ ('tx_outs' , pack .ListType (tx_out_type )),
115
+ ('lock_time' , pack .IntType (32 ))
116
+ ])
117
+
118
+ class TransactionType (pack .Type ):
119
+ _int_type = pack .IntType (32 )
120
+ _varint_type = pack .VarIntType ()
121
+ _witness_type = pack .ListType (pack .VarStrType ())
122
+ _wtx_type = pack .ComposedType ([
123
+ ('flag' , pack .IntType (8 )),
124
+ ('tx_ins' , pack .ListType (tx_in_type )),
125
+ ('tx_outs' , pack .ListType (tx_out_type ))
126
+ ])
127
+ _ntx_type = pack .ComposedType ([
128
+ ('tx_outs' , pack .ListType (tx_out_type )),
129
+ ('lock_time' , _int_type )
130
+ ])
131
+ _write_type = pack .ComposedType ([
132
+ ('version' , _int_type ),
133
+ ('marker' , pack .IntType (8 )),
134
+ ('flag' , pack .IntType (8 )),
135
+ ('tx_ins' , pack .ListType (tx_in_type )),
136
+ ('tx_outs' , pack .ListType (tx_out_type ))
137
+ ])
138
+
139
+ def read (self , file ):
140
+ version , file = self ._int_type .read (file )
141
+ marker , file = self ._varint_type .read (file )
142
+ if marker == 0 :
143
+ next , file = self ._wtx_type .read (file )
144
+ witness = [None ]* len (next ['tx_ins' ])
145
+ for i in xrange (len (next ['tx_ins' ])):
146
+ witness [i ], file = self ._witness_type .read (file )
147
+ locktime , file = self ._int_type .read (file )
148
+ return dict (version = version , marker = marker , flag = next ['flag' ], tx_ins = next ['tx_ins' ], tx_outs = next ['tx_outs' ], witness = witness , lock_time = locktime ), file
149
+ else :
150
+ tx_ins = [None ]* marker
151
+ for i in xrange (marker ):
152
+ tx_ins [i ], file = tx_in_type .read (file )
153
+ next , file = self ._ntx_type .read (file )
154
+ return dict (version = version , tx_ins = tx_ins , tx_outs = next ['tx_outs' ], lock_time = next ['lock_time' ]), file
155
+
156
+ def write (self , file , item ):
157
+ if is_segwit_tx (item ):
158
+ assert len (item ['tx_ins' ]) == len (item ['witness' ])
159
+ res = self ._write_type .pack (item )
160
+ for w in item ['witness' ]:
161
+ res += self ._witness_type .pack (w )
162
+ res += self ._int_type .pack (item ['lock_time' ])
163
+ return file , res
164
+ return tx_id_type .write (file , item )
165
+
166
+ tx_type = TransactionType ()
167
+
111
168
merkle_link_type = pack .ComposedType ([
112
169
('branch' , pack .ListType (pack .IntType (256 ))),
113
170
('index' , pack .IntType (32 )),
114
171
])
115
172
116
173
merkle_tx_type = pack .ComposedType ([
117
- ('tx' , tx_type ),
174
+ ('tx' , tx_id_type ), # used only in aux_pow_type
118
175
('block_hash' , pack .IntType (256 )),
119
176
('merkle_link' , merkle_link_type ),
120
177
])
@@ -133,6 +190,11 @@ def write(self, file, item):
133
190
('txs' , pack .ListType (tx_type )),
134
191
])
135
192
193
+ stripped_block_type = pack .ComposedType ([
194
+ ('header' , block_header_type ),
195
+ ('txs' , pack .ListType (tx_id_type )),
196
+ ])
197
+
136
198
# merged mining
137
199
138
200
aux_pow_type = pack .ComposedType ([
@@ -264,6 +326,22 @@ def address_to_pubkey_hash(address, net):
264
326
265
327
# transactions
266
328
329
+ def get_witness_commitment_hash (witness_root_hash , witness_reserved_value ):
330
+ return hash256 (merkle_record_type .pack (dict (left = witness_root_hash , right = witness_reserved_value )))
331
+
332
+ def get_wtxid (tx , txid = None , txhash = None ):
333
+ has_witness = False
334
+ if is_segwit_tx (tx ):
335
+ assert len (tx ['tx_ins' ]) == len (tx ['witness' ])
336
+ has_witness = any (len (w ) > 0 for w in tx ['witness' ])
337
+ if has_witness :
338
+ return hash256 (tx_type .pack (tx )) if txhash is None else txhash
339
+ else :
340
+ return hash256 (tx_id_type .pack (tx )) if txid is None else txid
341
+
342
+ def get_txid (tx ):
343
+ return hash256 (tx_id_type .pack (tx ))
344
+
267
345
def pubkey_to_script2 (pubkey ):
268
346
assert len (pubkey ) <= 75
269
347
return (chr (len (pubkey )) + pubkey ) + '\xac '
0 commit comments