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