ttest_transaction.py - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- ttest_transaction.py (121147B) --- 1 from typing import NamedTuple, Union 2 3 from electrum import transaction, bitcoin 4 from electrum.transaction import (convert_raw_tx_to_hex, tx_from_any, Transaction, 5 PartialTransaction, TxOutpoint, PartialTxInput, 6 PartialTxOutput) 7 from electrum.util import bh2u, bfh 8 from electrum.bitcoin import (deserialize_privkey, opcodes, 9 construct_script, construct_witness) 10 from electrum.ecc import ECPrivkey 11 12 from . import ElectrumTestCase, TestCaseForTestnet 13 14 signed_blob = '01000000012a5c9a94fcde98f5581cd00162c60a13936ceb75389ea65bf38633b424eb4031000000006c493046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d985012102e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae35cdb84d2f6ffffffff0140420f00000000001976a914230ac37834073a42146f11ef8414ae929feaafc388ac00000000' 15 v2_blob = "0200000001191601a44a81e061502b7bfbc6eaa1cef6d1e6af5308ef96c9342f71dbf4b9b5000000006b483045022100a6d44d0a651790a477e75334adfb8aae94d6612d01187b2c02526e340a7fd6c8022028bdf7a64a54906b13b145cd5dab21a26bd4b85d6044e9b97bceab5be44c2a9201210253e8e0254b0c95776786e40984c1aa32a7d03efa6bdacdea5f421b774917d346feffffff026b20fa04000000001976a914024db2e87dd7cfd0e5f266c5f212e21a31d805a588aca0860100000000001976a91421919b94ae5cefcdf0271191459157cdb41c4cbf88aca6240700" 16 signed_segwit_blob = "01000000000101b66d722484f2db63e827ebf41d02684fed0c6550e85015a6c9d41ef216a8a6f00000000000fdffffff0280c3c90100000000160014b65ce60857f7e7892b983851c2a8e3526d09e4ab64bac30400000000160014c478ebbc0ab2097706a98e10db7cf101839931c4024730440220789c7d47f876638c58d98733c30ae9821c8fa82b470285dcdf6db5994210bf9f02204163418bbc44af701212ad42d884cc613f3d3d831d2d0cc886f767cca6e0235e012103083a6dc250816d771faa60737bfe78b23ad619f6b458e0a1f1688e3a0605e79c00000000" 17 18 signed_blob_signatures = ['3046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d98501', ] 19 20 class TestBCDataStream(ElectrumTestCase): 21 22 def test_compact_size(self): 23 s = transaction.BCDataStream() 24 values = [0, 1, 252, 253, 2**16-1, 2**16, 2**32-1, 2**32, 2**64-1] 25 for v in values: 26 s.write_compact_size(v) 27 28 with self.assertRaises(transaction.SerializationError): 29 s.write_compact_size(-1) 30 31 self.assertEqual(bh2u(s.input), 32 '0001fcfdfd00fdfffffe00000100feffffffffff0000000001000000ffffffffffffffffff') 33 for v in values: 34 self.assertEqual(s.read_compact_size(), v) 35 36 with self.assertRaises(transaction.SerializationError): 37 s.read_compact_size() 38 39 def test_string(self): 40 s = transaction.BCDataStream() 41 with self.assertRaises(transaction.SerializationError): 42 s.read_string() 43 44 msgs = ['Hello', ' ', 'World', '', '!'] 45 for msg in msgs: 46 s.write_string(msg) 47 for msg in msgs: 48 self.assertEqual(s.read_string(), msg) 49 50 with self.assertRaises(transaction.SerializationError): 51 s.read_string() 52 53 def test_bytes(self): 54 s = transaction.BCDataStream() 55 with self.assertRaises(transaction.SerializationError): 56 s.read_bytes(1) 57 s.write(b'foobar') 58 self.assertEqual(s.read_bytes(3), b'foo') 59 self.assertEqual(s.read_bytes(2), b'ba') 60 with self.assertRaises(transaction.SerializationError): 61 s.read_bytes(4) 62 self.assertEqual(s.read_bytes(0), b'') 63 self.assertEqual(s.read_bytes(1), b'r') 64 self.assertEqual(s.read_bytes(0), b'') 65 66 def test_bool(self): 67 s = transaction.BCDataStream() 68 s.write(b'f\x00\x00b') 69 self.assertTrue(s.read_boolean()) 70 self.assertFalse(s.read_boolean()) 71 self.assertFalse(s.read_boolean()) 72 self.assertTrue(s.read_boolean()) 73 s.write_boolean(True) 74 s.write_boolean(False) 75 self.assertEqual(b'\x01\x00', s.read_bytes(2)) 76 self.assertFalse(s.can_read_more()) 77 78 79 class TestTransaction(ElectrumTestCase): 80 81 def test_tx_update_signatures(self): 82 tx = tx_from_any("cHNidP8BAFUBAAAAASpcmpT83pj1WBzQAWLGChOTbOt1OJ6mW/OGM7Qk60AxAAAAAAD/////AUBCDwAAAAAAGXapFCMKw3g0BzpCFG8R74QUrpKf6q/DiKwAAAAAAAAA") 83 tx.inputs()[0].script_type = 'p2pkh' 84 tx.inputs()[0].pubkeys = [bfh('02e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae35cdb84d2f6')] 85 tx.inputs()[0].num_sig = 1 86 tx.update_signatures(signed_blob_signatures) 87 self.assertEqual(tx.serialize(), signed_blob) 88 89 def test_tx_setting_locktime_invalidates_ser_cache(self): 90 tx = tx_from_any("cHNidP8BAJICAAAAAdAEtnw/IOVkr4oexG2xYnm+Vevsn3J7nbZsGpiBWS8MAQAAAAD9////A2Q5AwAAAAAAF6kUF6jKG6BuNVhq1RilflIDCitepw6H/NEEAAAAAAAXqRQx9SsFxDAaaOWbLB2ely1ZoZ61DYeIbQoAAAAAABYAFItCjFDsC28Z1R3tFaoi//pcInvnI3AZAAABAR+weRIAAAAAABYAFEK0I6qyqoA/lXCEgysQNZvqokaQIgYC9tgRn6/8hlDLEvEg3lKD1HmNim0gGRYwt4x3aJURIq4MqAq7DwEAAAAUAAAAAAAAIgICXYdVjyDIufLQ3yeDA4M8016luFER2SWaGPk6UF8CbuQMqAq7DwEAAAAXAAAAAA==") 91 self.assertEqual("2774c819a05e44861a0555401d2741e6c03079cc4d892c69b910c0f52f407859", tx.txid()) 92 tx.locktime = 111222333 93 self.assertEqual("3d33a69c3f7717840b266c24ae1a6d29486820249b47261232e93ee118a6565b", tx.txid()) 94 95 def test_tx_setting_version_invalidates_ser_cache(self): 96 tx = tx_from_any("cHNidP8BAJICAAAAAdAEtnw/IOVkr4oexG2xYnm+Vevsn3J7nbZsGpiBWS8MAQAAAAD9////A2Q5AwAAAAAAF6kUF6jKG6BuNVhq1RilflIDCitepw6H/NEEAAAAAAAXqRQx9SsFxDAaaOWbLB2ely1ZoZ61DYeIbQoAAAAAABYAFItCjFDsC28Z1R3tFaoi//pcInvnI3AZAAABAR+weRIAAAAAABYAFEK0I6qyqoA/lXCEgysQNZvqokaQIgYC9tgRn6/8hlDLEvEg3lKD1HmNim0gGRYwt4x3aJURIq4MqAq7DwEAAAAUAAAAAAAAIgICXYdVjyDIufLQ3yeDA4M8016luFER2SWaGPk6UF8CbuQMqAq7DwEAAAAXAAAAAA==") 97 self.assertEqual("2774c819a05e44861a0555401d2741e6c03079cc4d892c69b910c0f52f407859", tx.txid()) 98 tx.version = 555 99 self.assertEqual("8a9b89a1a7aac1995dd013069d9866197d77c14c22315958d612fc02fd4b596a", tx.txid()) 100 101 def test_tx_deserialize_for_signed_network_tx(self): 102 tx = transaction.Transaction(signed_blob) 103 tx.deserialize() 104 self.assertEqual(1, tx.version) 105 self.assertEqual(0, tx.locktime) 106 self.assertEqual(1, len(tx.inputs())) 107 self.assertEqual(4294967295, tx.inputs()[0].nsequence) 108 self.assertEqual(bfh('493046022100a82bbc57a0136751e5433f41cf000b3f1a99c6744775e76ec764fb78c54ee100022100f9e80b7de89de861dc6fb0c1429d5da72c2b6b2ee2406bc9bfb1beedd729d985012102e61d176da16edd1d258a200ad9759ef63adf8e14cd97f53227bae35cdb84d2f6'), 109 tx.inputs()[0].script_sig) 110 self.assertEqual(None, tx.inputs()[0].witness) 111 self.assertEqual('3140eb24b43386f35ba69e3875eb6c93130ac66201d01c58f598defc949a5c2a:0', tx.inputs()[0].prevout.to_str()) 112 self.assertEqual(1, len(tx.outputs())) 113 self.assertEqual(bfh('76a914230ac37834073a42146f11ef8414ae929feaafc388ac'), tx.outputs()[0].scriptpubkey) 114 self.assertEqual('14CHYaaByjJZpx4oHBpfDMdqhTyXnZ3kVs', tx.outputs()[0].address) 115 self.assertEqual(1000000, tx.outputs()[0].value) 116 117 self.assertEqual(tx.serialize(), signed_blob) 118 119 def test_estimated_tx_size(self): 120 tx = transaction.Transaction(signed_blob) 121 122 self.assertEqual(tx.estimated_total_size(), 193) 123 self.assertEqual(tx.estimated_base_size(), 193) 124 self.assertEqual(tx.estimated_witness_size(), 0) 125 self.assertEqual(tx.estimated_weight(), 772) 126 self.assertEqual(tx.estimated_size(), 193) 127 128 def test_estimated_output_size(self): 129 estimated_output_size = transaction.Transaction.estimated_output_size_for_address 130 self.assertEqual(estimated_output_size('14gcRovpkCoGkCNBivQBvw7eso7eiNAbxG'), 34) 131 self.assertEqual(estimated_output_size('35ZqQJcBQMZ1rsv8aSuJ2wkC7ohUCQMJbT'), 32) 132 self.assertEqual(estimated_output_size('bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af'), 31) 133 self.assertEqual(estimated_output_size('bc1qnvks7gfdu72de8qv6q6rhkkzu70fqz4wpjzuxjf6aydsx7wxfwcqnlxuv3'), 43) 134 135 # TODO other tests for segwit tx 136 def test_tx_signed_segwit(self): 137 tx = transaction.Transaction(signed_segwit_blob) 138 139 self.assertEqual(tx.estimated_total_size(), 222) 140 self.assertEqual(tx.estimated_base_size(), 113) 141 self.assertEqual(tx.estimated_witness_size(), 109) 142 self.assertEqual(tx.estimated_weight(), 561) 143 self.assertEqual(tx.estimated_size(), 141) 144 145 def test_version_field(self): 146 tx = transaction.Transaction(v2_blob) 147 self.assertEqual(tx.txid(), "b97f9180173ab141b61b9f944d841e60feec691d6daab4d4d932b24dd36606fe") 148 149 def test_convert_raw_tx_to_hex(self): 150 # raw hex 151 self.assertEqual('020000000001012005273af813ba23b0c205e4b145e525c280dd876e061f35bff7db9b2e0043640100000000fdffffff02d885010000000000160014e73f444b8767c84afb46ef4125d8b81d2542a53d00e1f5050000000017a914052ed032f5c74a636ed5059611bb90012d40316c870247304402200c628917673d75f05db893cc377b0a69127f75e10949b35da52aa1b77a14c350022055187adf9a668fdf45fc09002726ba7160e713ed79dddcd20171308273f1a2f1012103cb3e00561c3439ccbacc033a72e0513bcfabff8826de0bc651d661991ade6171049e1600', 152 convert_raw_tx_to_hex('020000000001012005273af813ba23b0c205e4b145e525c280dd876e061f35bff7db9b2e0043640100000000fdffffff02d885010000000000160014e73f444b8767c84afb46ef4125d8b81d2542a53d00e1f5050000000017a914052ed032f5c74a636ed5059611bb90012d40316c870247304402200c628917673d75f05db893cc377b0a69127f75e10949b35da52aa1b77a14c350022055187adf9a668fdf45fc09002726ba7160e713ed79dddcd20171308273f1a2f1012103cb3e00561c3439ccbacc033a72e0513bcfabff8826de0bc651d661991ade6171049e1600')) 153 # base43 154 self.assertEqual('020000000001012005273af813ba23b0c205e4b145e525c280dd876e061f35bff7db9b2e0043640100000000fdffffff02d885010000000000160014e73f444b8767c84afb46ef4125d8b81d2542a53d00e1f5050000000017a914052ed032f5c74a636ed5059611bb90012d40316c870247304402200c628917673d75f05db893cc377b0a69127f75e10949b35da52aa1b77a14c350022055187adf9a668fdf45fc09002726ba7160e713ed79dddcd20171308273f1a2f1012103cb3e00561c3439ccbacc033a72e0513bcfabff8826de0bc651d661991ade6171049e1600', 155 convert_raw_tx_to_hex('64XF-8+PM6*4IYN-QWW$B2QLNW+:C8-$I$-+T:L.6DKXTSWSFFONDP1J/MOS3SPK0-SYVW38U9.3+A1/*2HTHQTJGP79LVEK-IITQJ1H.C/X$NSOV$8DWR6JAFWXD*LX4-EN0.BDOF+PPYPH16$NM1H.-MAA$V1SCP0Q.6Y5FR822S6K-.5K5F.Z4Q:0SDRG-4GEBLAO4W9Z*H-$1-KDYAFOGF675W0:CK5M1LT92IG:3X60P3GKPM:X2$SP5A7*LT9$-TTEG0/DRZYV$7B4ADL9CVS5O7YG.J64HLZ24MVKO/-GV:V.T/L$D3VQ:MR8--44HK8W')) 156 157 def test_get_address_from_output_script(self): 158 # the inverse of this test is in test_bitcoin: test_address_to_script 159 addr_from_script = lambda script: transaction.get_address_from_output_script(bfh(script)) 160 161 # bech32 native segwit 162 # test vectors from BIP-0173 163 self.assertEqual('bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4', addr_from_script('0014751e76e8199196d454941c45d1b3a323f1433bd6')) 164 self.assertEqual('bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx', addr_from_script('5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6')) 165 self.assertEqual('bc1sw50qa3jx3s', addr_from_script('6002751e')) 166 self.assertEqual('bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj', addr_from_script('5210751e76e8199196d454941c45d1b3a323')) 167 # almost but not quite 168 self.assertEqual(None, addr_from_script('0013751e76e8199196d454941c45d1b3a323f1433b')) 169 170 # base58 p2pkh 171 self.assertEqual('14gcRovpkCoGkCNBivQBvw7eso7eiNAbxG', addr_from_script('76a91428662c67561b95c79d2257d2a93d9d151c977e9188ac')) 172 self.assertEqual('1BEqfzh4Y3zzLosfGhw1AsqbEKVW6e1qHv', addr_from_script('76a914704f4b81cadb7bf7e68c08cd3657220f680f863c88ac')) 173 # almost but not quite 174 self.assertEqual(None, addr_from_script('76a9130000000000000000000000000000000000000088ac')) 175 176 # base58 p2sh 177 self.assertEqual('35ZqQJcBQMZ1rsv8aSuJ2wkC7ohUCQMJbT', addr_from_script('a9142a84cf00d47f699ee7bbc1dea5ec1bdecb4ac15487')) 178 self.assertEqual('3PyjzJ3im7f7bcV724GR57edKDqoZvH7Ji', addr_from_script('a914f47c8954e421031ad04ecd8e7752c9479206b9d387')) 179 # almost but not quite 180 self.assertEqual(None, addr_from_script('a912f47c8954e421031ad04ecd8e7752c947920687')) 181 182 # p2pk 183 self.assertEqual(None, addr_from_script('210289e14468d94537493c62e2168318b568912dec0fb95609afd56f2527c2751c8bac')) 184 self.assertEqual(None, addr_from_script('41045485b0b076848af1209e788c893522a90f3df77c1abac2ca545846a725e6c3da1f7743f55a1bc3b5f0c7e0ee4459954ec0307022742d60032b13432953eb7120ac')) 185 # almost but not quite 186 self.assertEqual(None, addr_from_script('200289e14468d94537493c62e2168318b568912dec0fb95609afd56f2527c2751cac')) 187 self.assertEqual(None, addr_from_script('210589e14468d94537493c62e2168318b568912dec0fb95609afd56f2527c2751c8bac')) 188 189 def test_tx_serialize_methods_for_psbt(self): parazyd.org:70 /git/electrum/file/electrum/tests/test_transaction.py.gph:199: line too long