1
0
mirror of https://github.com/bitcoin/bips.git synced 2026-05-04 16:41:51 +00:00

BIP69: fix output inconsistency and update to python3

- Fix print_outputs() to use sorted output tuples instead of unsorted
- Add Python 3 compatibility using functools.cmp_to_key()
- Convert string hashes to byte arrays in second example
- Make file executable with shebang for python3
- Add clearer output formatting with transaction hashes and section headers
This commit is contained in:
Alvarez
2025-08-22 15:56:04 +02:00
committed by prestoalvarez
parent 2e3dd3f273
commit ba843e29b1

View File

@@ -1,4 +1,6 @@
#!/usr/bin/env python3
import binascii import binascii
from functools import cmp_to_key
#returns -1 if barr1 is less, 1 if barr1 is greater, and 0 if equal #returns -1 if barr1 is less, 1 if barr1 is greater, and 0 if equal
def bytearr_cmp(barr1, barr2): def bytearr_cmp(barr1, barr2):
@@ -32,9 +34,10 @@ def input_cmp(input_tuple1, input_tuple2):
raise ValueError('Matching previous transaction hash and previous transaction output index for two distinct inputs. Invalid!') raise ValueError('Matching previous transaction hash and previous transaction output index for two distinct inputs. Invalid!')
def sort_inputs(input_tuples): def sort_inputs(input_tuples):
return sorted(input_tuples, cmp=input_cmp) return sorted(input_tuples, key=cmp_to_key(input_cmp))
def print_inputs(ordered_input_tuples): def print_inputs(ordered_input_tuples):
print("inputs")
index = 0 index = 0
for prev_tx_hash_byte_arr_little_endian, prev_tx_output_index in ordered_input_tuples: for prev_tx_hash_byte_arr_little_endian, prev_tx_output_index in ordered_input_tuples:
prev_tx_hash_hex = binascii.hexlify(bytearray(prev_tx_hash_byte_arr_little_endian)) prev_tx_hash_hex = binascii.hexlify(bytearray(prev_tx_hash_byte_arr_little_endian))
@@ -52,9 +55,10 @@ def output_cmp(output_tuple1, output_tuple2):
return bytearr_cmp(output_tuple1[1], output_tuple2[1]) return bytearr_cmp(output_tuple1[1], output_tuple2[1])
def sort_outputs(output_tuples): def sort_outputs(output_tuples):
return sorted(output_tuples, cmp=output_cmp) return sorted(output_tuples, key=cmp_to_key(output_cmp))
def print_outputs(ordered_output_tuples): def print_outputs(ordered_output_tuples):
print("outputs")
index = 0 index = 0
for amount, scriptPubKey_byte_arr in ordered_output_tuples: for amount, scriptPubKey_byte_arr in ordered_output_tuples:
scriptPubKey_hex = binascii.hexlify(bytearray(scriptPubKey_byte_arr)) scriptPubKey_hex = binascii.hexlify(bytearray(scriptPubKey_byte_arr))
@@ -82,6 +86,7 @@ def main():
([0x7d, 0x03, 0x7c, 0xeb, 0x2e, 0xe0, 0xdc, 0x03, 0xe8, 0x2f, 0x17, 0xbe, 0x79, 0x35, 0xd2, 0x38, 0xb3, 0x5d, 0x1d, 0xea, 0xbf, 0x95, 0x3a, 0x89, 0x2a, 0x45, 0x07, 0xbf, 0xbe, 0xeb, 0x3b, 0xa4], 1), ([0x7d, 0x03, 0x7c, 0xeb, 0x2e, 0xe0, 0xdc, 0x03, 0xe8, 0x2f, 0x17, 0xbe, 0x79, 0x35, 0xd2, 0x38, 0xb3, 0x5d, 0x1d, 0xea, 0xbf, 0x95, 0x3a, 0x89, 0x2a, 0x45, 0x07, 0xbf, 0xbe, 0xeb, 0x3b, 0xa4], 1),
([0x6c, 0x1d, 0x56, 0xf3, 0x1b, 0x2d, 0xe4, 0xbf, 0xc6, 0xaa, 0xea, 0x28, 0x39, 0x6b, 0x33, 0x31, 0x02, 0xb1, 0xf6, 0x00, 0xda, 0x9c, 0x6d, 0x61, 0x49, 0xe9, 0x6c, 0xa4, 0x3f, 0x11, 0x02, 0xb1], 1), ([0x6c, 0x1d, 0x56, 0xf3, 0x1b, 0x2d, 0xe4, 0xbf, 0xc6, 0xaa, 0xea, 0x28, 0x39, 0x6b, 0x33, 0x31, 0x02, 0xb1, 0xf6, 0x00, 0xda, 0x9c, 0x6d, 0x61, 0x49, 0xe9, 0x6c, 0xa4, 0x3f, 0x11, 0x02, 0xb1], 1),
([0xb4, 0x11, 0x2b, 0x8f, 0x90, 0x0a, 0x7c, 0xa0, 0xc8, 0xb0, 0xe7, 0xc4, 0xdf, 0xad, 0x35, 0xc6, 0xbe, 0x5f, 0x6b, 0xe4, 0x6b, 0x34, 0x58, 0x97, 0x49, 0x88, 0xe1, 0xcd, 0xb2, 0xfa, 0x61, 0xb8], 0)] ([0xb4, 0x11, 0x2b, 0x8f, 0x90, 0x0a, 0x7c, 0xa0, 0xc8, 0xb0, 0xe7, 0xc4, 0xdf, 0xad, 0x35, 0xc6, 0xbe, 0x5f, 0x6b, 0xe4, 0x6b, 0x34, 0x58, 0x97, 0x49, 0x88, 0xe1, 0xcd, 0xb2, 0xfa, 0x61, 0xb8], 0)]
print("\ntx 0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3")
tx_0a6a_sorted_input_tuples = sort_inputs(tx_0a6a_input_tuples) tx_0a6a_sorted_input_tuples = sort_inputs(tx_0a6a_input_tuples)
print_inputs(tx_0a6a_sorted_input_tuples) print_inputs(tx_0a6a_sorted_input_tuples)
@@ -94,10 +99,11 @@ def main():
#reference data: https://blockchain.info/rawtx/28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f thanks @quantabytes! #reference data: https://blockchain.info/rawtx/28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f thanks @quantabytes!
tx_2820_input_tuples = [ tx_2820_input_tuples = [
# (prev_tx_hash, prev_tx_output_index) # (prev_tx_hash_byte_arr_little_endian, prev_tx_output_index)
("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 0), ([0x55, 0x60, 0x5d, 0xc6, 0x5f, 0x3c, 0xcc, 0x4d, 0xb1, 0xd8, 0x56, 0x4a, 0x28, 0x04, 0x2b, 0xdb, 0x2c, 0x2b, 0xe3, 0x85, 0xea, 0xb2, 0xeb, 0xea, 0x41, 0x19, 0xee, 0x9c, 0x26, 0x8d, 0x28, 0x35], 0),
("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 1)] #duplicate prev_tx_hash ([0x55, 0x60, 0x5d, 0xc6, 0x5f, 0x3c, 0xcc, 0x4d, 0xb1, 0xd8, 0x56, 0x4a, 0x28, 0x04, 0x2b, 0xdb, 0x2c, 0x2b, 0xe3, 0x85, 0xea, 0xb2, 0xeb, 0xea, 0x41, 0x19, 0xee, 0x9c, 0x26, 0x8d, 0x28, 0x35], 1)] #duplicate prev_tx_hash
print("\ntx 28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f")
tx_2820_sorted_input_tuples = sort_inputs(tx_2820_input_tuples) tx_2820_sorted_input_tuples = sort_inputs(tx_2820_input_tuples)
print_inputs(tx_2820_sorted_input_tuples) print_inputs(tx_2820_sorted_input_tuples)
@@ -106,7 +112,7 @@ def main():
(100000000, [0x41, 0x04, 0x6a, 0x07, 0x65, 0xb5, 0x86, 0x56, 0x41, 0xce, 0x08, 0xdd, 0x39, 0x69, 0x0a, 0xad, 0xe2, 0x6d, 0xfb, 0xf5, 0x51, 0x14, 0x30, 0xca, 0x42, 0x8a, 0x30, 0x89, 0x26, 0x13, 0x61, 0xce, 0xf1, 0x70, 0xe3, 0x92, 0x9a, 0x68, 0xae, 0xe3, 0xd8, 0xd4, 0x84, 0x8b, 0x0c, 0x51, 0x11, 0xb0, 0xa3, 0x7b, 0x82, 0xb8, 0x6a, 0xd5, 0x59, 0xfd, 0x2a, 0x74, 0x5b, 0x44, 0xd8, 0xe8, 0xd9, 0xdf, 0xdc, 0x0c, 0xac]), (100000000, [0x41, 0x04, 0x6a, 0x07, 0x65, 0xb5, 0x86, 0x56, 0x41, 0xce, 0x08, 0xdd, 0x39, 0x69, 0x0a, 0xad, 0xe2, 0x6d, 0xfb, 0xf5, 0x51, 0x14, 0x30, 0xca, 0x42, 0x8a, 0x30, 0x89, 0x26, 0x13, 0x61, 0xce, 0xf1, 0x70, 0xe3, 0x92, 0x9a, 0x68, 0xae, 0xe3, 0xd8, 0xd4, 0x84, 0x8b, 0x0c, 0x51, 0x11, 0xb0, 0xa3, 0x7b, 0x82, 0xb8, 0x6a, 0xd5, 0x59, 0xfd, 0x2a, 0x74, 0x5b, 0x44, 0xd8, 0xe8, 0xd9, 0xdf, 0xdc, 0x0c, 0xac]),
(2400000000, [0x41, 0x04, 0x4a, 0x65, 0x6f, 0x06, 0x58, 0x71, 0xa3, 0x53, 0xf2, 0x16, 0xca, 0x26, 0xce, 0xf8, 0xdd, 0xe2, 0xf0, 0x3e, 0x8c, 0x16, 0x20, 0x2d, 0x2e, 0x8a, 0xd7, 0x69, 0xf0, 0x20, 0x32, 0xcb, 0x86, 0xa5, 0xeb, 0x5e, 0x56, 0x84, 0x2e, 0x92, 0xe1, 0x91, 0x41, 0xd6, 0x0a, 0x01, 0x92, 0x8f, 0x8d, 0xd2, 0xc8, 0x75, 0xa3, 0x90, 0xf6, 0x7c, 0x1f, 0x6c, 0x94, 0xcf, 0xc6, 0x17, 0xc0, 0xea, 0x45, 0xaf, 0xac])] (2400000000, [0x41, 0x04, 0x4a, 0x65, 0x6f, 0x06, 0x58, 0x71, 0xa3, 0x53, 0xf2, 0x16, 0xca, 0x26, 0xce, 0xf8, 0xdd, 0xe2, 0xf0, 0x3e, 0x8c, 0x16, 0x20, 0x2d, 0x2e, 0x8a, 0xd7, 0x69, 0xf0, 0x20, 0x32, 0xcb, 0x86, 0xa5, 0xeb, 0x5e, 0x56, 0x84, 0x2e, 0x92, 0xe1, 0x91, 0x41, 0xd6, 0x0a, 0x01, 0x92, 0x8f, 0x8d, 0xd2, 0xc8, 0x75, 0xa3, 0x90, 0xf6, 0x7c, 0x1f, 0x6c, 0x94, 0xcf, 0xc6, 0x17, 0xc0, 0xea, 0x45, 0xaf, 0xac])]
tx_2820_sorted_output_tuples = sort_outputs(tx_2820_output_tuples) tx_2820_sorted_output_tuples = sort_outputs(tx_2820_output_tuples)
print_outputs(tx_2820_output_tuples) print_outputs(tx_2820_sorted_output_tuples)
if __name__ == "__main__": if __name__ == "__main__":
main() main()