/ test / functional / rpc_decodescript.py
rpc_decodescript.py
  1  #!/usr/bin/env python3
  2  # Copyright (c) 2015-present The Bitcoin Core developers
  3  # Distributed under the MIT software license, see the accompanying
  4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5  """Test decoding scripts via decodescript RPC command."""
  6  
  7  import json
  8  import os
  9  
 10  from test_framework.messages import (
 11      sha256,
 12      tx_from_hex,
 13  )
 14  from test_framework.test_framework import BitcoinTestFramework
 15  from test_framework.util import (
 16      assert_equal,
 17  )
 18  
 19  
 20  class DecodeScriptTest(BitcoinTestFramework):
 21      def set_test_params(self):
 22          self.setup_clean_chain = True
 23          self.num_nodes = 1
 24  
 25      def decodescript_script_sig(self):
 26          signature = '304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001'
 27          push_signature = '48' + signature
 28          public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2'
 29          push_public_key = '21' + public_key
 30  
 31          # below are test cases for all of the standard transaction types
 32  
 33          self.log.info("- P2PK")
 34          # the scriptSig of a public key scriptPubKey simply pushes a signature onto the stack
 35          rpc_result = self.nodes[0].decodescript(push_signature)
 36          assert_equal(signature, rpc_result['asm'])
 37  
 38          self.log.info("- P2PKH")
 39          rpc_result = self.nodes[0].decodescript(push_signature + push_public_key)
 40          assert_equal(signature + ' ' + public_key, rpc_result['asm'])
 41  
 42          self.log.info("- multisig")
 43          # this also tests the leading portion of a P2SH multisig scriptSig
 44          # OP_0 <A sig> <B sig>
 45          rpc_result = self.nodes[0].decodescript('00' + push_signature + push_signature)
 46          assert_equal('0 ' + signature + ' ' + signature, rpc_result['asm'])
 47  
 48          self.log.info("- P2SH")
 49          # an empty P2SH redeemScript is valid and makes for a very simple test case.
 50          # thus, such a spending scriptSig would just need to pass the outer redeemScript
 51          # hash test and leave true on the top of the stack.
 52          rpc_result = self.nodes[0].decodescript('5100')
 53          assert_equal('1 0', rpc_result['asm'])
 54  
 55          # null data scriptSig - no such thing because null data scripts cannot be spent.
 56          # thus, no test case for that standard transaction type is here.
 57  
 58      def decodescript_script_pub_key(self):
 59          public_key = '03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2'
 60          push_public_key = '21' + public_key
 61          public_key_hash = '5dd1d3a048119c27b28293056724d9522f26d945'
 62          push_public_key_hash = '14' + public_key_hash
 63          uncompressed_public_key = '04b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb25e01fc8fde47c96c98a4f3a8123e33a38a50cf9025cc8c4494a518f991792bb7'
 64          push_uncompressed_public_key = '41' + uncompressed_public_key
 65          p2wsh_p2pk_script_hash = 'd8590cf8ea0674cf3d49fd7ca249b85ef7485dea62c138468bddeb20cd6519f7'
 66  
 67          # below are test cases for all of the standard transaction types
 68  
 69          self.log.info("- P2PK")
 70          # <pubkey> OP_CHECKSIG
 71          rpc_result = self.nodes[0].decodescript(push_public_key + 'ac')
 72          assert_equal(public_key + ' OP_CHECKSIG', rpc_result['asm'])
 73          assert_equal('pubkey', rpc_result['type'])
 74          # P2PK is translated to P2WPKH
 75          assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
 76  
 77          self.log.info("- P2PKH")
 78          # OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
 79          rpc_result = self.nodes[0].decodescript('76a9' + push_public_key_hash + '88ac')
 80          assert_equal('pubkeyhash', rpc_result['type'])
 81          assert_equal('OP_DUP OP_HASH160 ' + public_key_hash + ' OP_EQUALVERIFY OP_CHECKSIG', rpc_result['asm'])
 82          # P2PKH is translated to P2WPKH
 83          assert_equal('witness_v0_keyhash', rpc_result['segwit']['type'])
 84          assert_equal('0 ' + public_key_hash, rpc_result['segwit']['asm'])
 85  
 86          self.log.info("- multisig")
 87          # <m> <A pubkey> <B pubkey> <C pubkey> <n> OP_CHECKMULTISIG
 88          # just imagine that the pub keys used below are different.
 89          # for our purposes here it does not matter that they are the same even though it is unrealistic.
 90          multisig_script = '52' + push_public_key + push_public_key + push_public_key + '53ae'
 91          rpc_result = self.nodes[0].decodescript(multisig_script)
 92          assert_equal('multisig', rpc_result['type'])
 93          assert_equal('2 ' + public_key + ' ' + public_key + ' ' + public_key +  ' 3 OP_CHECKMULTISIG', rpc_result['asm'])
 94          # multisig in P2WSH
 95          multisig_script_hash = sha256(bytes.fromhex(multisig_script)).hex()
 96          assert_equal('witness_v0_scripthash', rpc_result['segwit']['type'])
 97          assert_equal('0 ' + multisig_script_hash, rpc_result['segwit']['asm'])
 98  
 99          self.log.info ("- P2SH")
100          # OP_HASH160 <Hash160(redeemScript)> OP_EQUAL.
101          # push_public_key_hash here should actually be the hash of a redeem script.
102          # but this works the same for purposes of this test.
103          rpc_result = self.nodes[0].decodescript('a9' + push_public_key_hash + '87')
104          assert_equal('scripthash', rpc_result['type'])
105          assert_equal('OP_HASH160 ' + public_key_hash + ' OP_EQUAL', rpc_result['asm'])
106          # P2SH does not work in segwit secripts. decodescript should not return a result for it.
107          assert 'segwit' not in rpc_result
108  
109          self.log.info("- null data")
110          # use a signature look-alike here to make sure that we do not decode random data as a signature.
111          # this matters if/when signature sighash decoding comes along.
112          # would want to make sure that no such decoding takes place in this case.
113          signature_imposter = '48304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001'
114          # OP_RETURN <data>
115          rpc_result = self.nodes[0].decodescript('6a' + signature_imposter)
116          assert_equal('nulldata', rpc_result['type'])
117          assert_equal('OP_RETURN ' + signature_imposter[2:], rpc_result['asm'])
118  
119          self.log.info("- CLTV redeem script")
120          # redeem scripts are in-effect scriptPubKey scripts, so adding a test here.
121          # OP_NOP2 is also known as OP_CHECKLOCKTIMEVERIFY.
122          # just imagine that the pub keys used below are different.
123          # for our purposes here it does not matter that they are the same even though it is unrealistic.
124          #
125          # OP_IF
126          #   <receiver-pubkey> OP_CHECKSIGVERIFY
127          # OP_ELSE
128          #   <lock-until> OP_CHECKLOCKTIMEVERIFY OP_DROP
129          # OP_ENDIF
130          # <sender-pubkey> OP_CHECKSIG
131          #
132          # lock until block 500,000
133          cltv_script = '63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac'
134          rpc_result = self.nodes[0].decodescript(cltv_script)
135          assert_equal('nonstandard', rpc_result['type'])
136          assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
137          # CLTV script in P2WSH
138          cltv_script_hash = sha256(bytes.fromhex(cltv_script)).hex()
139          assert_equal('0 ' + cltv_script_hash, rpc_result['segwit']['asm'])
140  
141          self.log.info("- P2PK with uncompressed pubkey")
142          # <pubkey> OP_CHECKSIG
143          rpc_result = self.nodes[0].decodescript(push_uncompressed_public_key + 'ac')
144          assert_equal('pubkey', rpc_result['type'])
145          assert_equal(uncompressed_public_key + ' OP_CHECKSIG', rpc_result['asm'])
146          # uncompressed pubkeys are invalid for checksigs in segwit scripts.
147          # decodescript should not return a P2WPKH equivalent.
148          assert 'segwit' not in rpc_result
149  
150          self.log.info("- multisig with uncompressed pubkey")
151          # <m> <A pubkey> <B pubkey> <n> OP_CHECKMULTISIG
152          # just imagine that the pub keys used below are different.
153          # the purpose of this test is to check that a segwit script is not returned for bare multisig scripts
154          # with an uncompressed pubkey in them.
155          rpc_result = self.nodes[0].decodescript('52' + push_public_key + push_uncompressed_public_key +'52ae')
156          assert_equal('multisig', rpc_result['type'])
157          assert_equal('2 ' + public_key + ' ' + uncompressed_public_key + ' 2 OP_CHECKMULTISIG', rpc_result['asm'])
158          # uncompressed pubkeys are invalid for checksigs in segwit scripts.
159          # decodescript should not return a P2WPKH equivalent.
160          assert 'segwit' not in rpc_result
161  
162          self.log.info("- P2WPKH")
163          # 0 <PubKeyHash>
164          rpc_result = self.nodes[0].decodescript('00' + push_public_key_hash)
165          assert_equal('witness_v0_keyhash', rpc_result['type'])
166          assert_equal('0 ' + public_key_hash, rpc_result['asm'])
167          # segwit scripts do not work nested into each other.
168          # a nested segwit script should not be returned in the results.
169          assert 'segwit' not in rpc_result
170  
171          self.log.info("- P2WSH")
172          # 0 <ScriptHash>
173          # even though this hash is of a P2PK script which is better used as bare P2WPKH, it should not matter
174          # for the purpose of this test.
175          rpc_result = self.nodes[0].decodescript('0020' + p2wsh_p2pk_script_hash)
176          assert_equal('witness_v0_scripthash', rpc_result['type'])
177          assert_equal('0 ' + p2wsh_p2pk_script_hash, rpc_result['asm'])
178          # segwit scripts do not work nested into each other.
179          # a nested segwit script should not be returned in the results.
180          assert 'segwit' not in rpc_result
181  
182          self.log.info("- P2TR")
183          # 1 <x-only pubkey>
184          xonly_public_key = '01'*32  # first ever P2TR output on mainnet
185          rpc_result = self.nodes[0].decodescript('5120' + xonly_public_key)
186          assert_equal('witness_v1_taproot', rpc_result['type'])
187          assert_equal('1 ' + xonly_public_key, rpc_result['asm'])
188          assert 'segwit' not in rpc_result
189  
190          self.log.info("- P2A (anchor)")
191          # 1 <4e73>
192          witprog_hex = '4e73'
193          rpc_result = self.nodes[0].decodescript('5102' + witprog_hex)
194          assert_equal('anchor', rpc_result['type'])
195          # in the disassembly, the witness program is shown as single decimal due to its small size
196          witprog_as_decimal = int.from_bytes(bytes.fromhex(witprog_hex), 'little')
197          assert_equal(f'1 {witprog_as_decimal}', rpc_result['asm'])
198          assert_equal('bcrt1pfeesnyr2tx', rpc_result['address'])
199  
200      def decoderawtransaction_asm_sighashtype(self):
201          """Test decoding scripts via RPC command "decoderawtransaction".
202  
203          This test is in with the "decodescript" tests because they are testing the same "asm" script decodes.
204          """
205  
206          self.log.info("- various mainnet txs")
207          # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs.
208          tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000'
209          rpc_result = self.nodes[0].decoderawtransaction(tx)
210          assert_equal('304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536', rpc_result['vin'][0]['scriptSig']['asm'])
211  
212          # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs.
213          # it's from James D'Angelo's awesome introductory videos about multisig: https://www.youtube.com/watch?v=zIbUSaZBJgU and https://www.youtube.com/watch?v=OSA1pwlaypc
214          # verify that we have not altered scriptPubKey decoding.
215          tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914dc863734a218bfe83ef770ee9d41a27f824a6e5688acee2a02000000000017a9142a5edea39971049a540474c6a99edf0aa4074c588700000000'
216          rpc_result = self.nodes[0].decoderawtransaction(tx)
217          assert_equal('8e3730608c3b0bb5df54f09076e196bc292a8e39a78e73b44b6ba08c78f5cbb0', rpc_result['txid'])
218          assert_equal('0 3045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea[ALL] 3045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75[ALL] 5221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53ae', rpc_result['vin'][0]['scriptSig']['asm'])
219          assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm'])
220          assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
221          txSave = tx_from_hex(tx)
222  
223          self.log.info("- tx not passing DER signature checks")
224          # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
225          tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
226          rpc_result = self.nodes[0].decoderawtransaction(tx)
227          assert_equal('OP_RETURN 300602010002010001', rpc_result['vout'][0]['scriptPubKey']['asm'])
228  
229          self.log.info("- tx passing DER signature checks")
230          # verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks
231          tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000'
232          rpc_result = self.nodes[0].decoderawtransaction(tx)
233          assert_equal('OP_DUP OP_HASH160 3011020701010101010101020601010101010101 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm'])
234          assert_equal('OP_HASH160 3011020701010101010101020601010101010101 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
235  
236          # some more full transaction tests of varying specific scriptSigs. used instead of
237          # tests in decodescript_script_sig because the decodescript RPC is specifically
238          # for working on scriptPubKeys (argh!).
239          push_signature = txSave.vin[0].scriptSig.hex()[2:(0x48*2+4)]
240          signature = push_signature[2:]
241          der_signature = signature[:-2]
242          signature_sighash_decoded = der_signature + '[ALL]'
243          signature_2 = der_signature + '82'
244          push_signature_2 = '48' + signature_2
245          signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
246  
247          self.log.info("- P2PK scriptSig")
248          txSave.vin[0].scriptSig = bytes.fromhex(push_signature)
249          rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
250          assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
251  
252          # make sure that the sighash decodes come out correctly for a more complex / lesser used case.
253          txSave.vin[0].scriptSig = bytes.fromhex(push_signature_2)
254          rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
255          assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
256  
257          self.log.info("- multisig scriptSig")
258          txSave.vin[0].scriptSig = bytes.fromhex('00' + push_signature + push_signature_2)
259          rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
260          assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
261  
262          self.log.info("- scriptSig that contains more than push operations")
263          # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
264          txSave.vin[0].scriptSig = bytes.fromhex('6a143011020701010101010101020601010101010101')
265          rpc_result = self.nodes[0].decoderawtransaction(txSave.serialize().hex())
266          assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
267  
268      def decodescript_datadriven_tests(self):
269          with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_decodescript.json')) as f:
270              dd_tests = json.load(f)
271  
272          for script, result in dd_tests:
273              rpc_result = self.nodes[0].decodescript(script)
274              assert_equal(result, rpc_result)
275  
276      def decodescript_miniscript(self):
277          """Check that a Miniscript is decoded when possible under P2WSH context."""
278          # Sourced from https://github.com/bitcoin/bitcoin/pull/27037#issuecomment-1416151907.
279          # Miniscript-compatible offered HTLC
280          res = self.nodes[0].decodescript("82012088a914ffffffffffffffffffffffffffffffffffffffff88210250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0ad51b2")
281          assert res["segwit"]["desc"] == "wsh(and_v(and_v(v:hash160(ffffffffffffffffffffffffffffffffffffffff),v:pk(0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)),older(1)))#gm8xz4fl"
282          # Miniscript-incompatible offered HTLC
283          res = self.nodes[0].decodescript("82012088a914ffffffffffffffffffffffffffffffffffffffff882102ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffacb2")
284          assert res["segwit"]["desc"] == "addr(bcrt1q73qyfypp47hvgnkjqnav0j3k2lq3v76wg22dk8tmwuz5sfgv66xsvxg6uu)#9p3q328s"
285          # Miniscript-compatible multisig bigger than 520 byte P2SH limit.
286          res = self.nodes[0].decodescript("5b21020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b678172612102675333a4e4b8fb51d9d4e22fa5a8eaced3fdac8a8cbf9be8c030f75712e6af992102896807d54bc55c24981f24a453c60ad3e8993d693732288068a23df3d9f50d4821029e51a5ef5db3137051de8323b001749932f2ff0d34c82e96a2c2461de96ae56c2102a4e1a9638d46923272c266631d94d36bdb03a64ee0e14c7518e49d2f29bc401021031c41fdbcebe17bec8d49816e00ca1b5ac34766b91c9f2ac37d39c63e5e008afb2103079e252e85abffd3c401a69b087e590a9b86f33f574f08129ccbd3521ecf516b2103111cf405b627e22135b3b3733a4a34aa5723fb0f58379a16d32861bf576b0ec2210318f331b3e5d38156da6633b31929c5b220349859cc9ca3d33fb4e68aa08401742103230dae6b4ac93480aeab26d000841298e3b8f6157028e47b0897c1e025165de121035abff4281ff00660f99ab27bb53e6b33689c2cd8dcd364bc3c90ca5aea0d71a62103bd45cddfacf2083b14310ae4a84e25de61e451637346325222747b157446614c2103cc297026b06c71cbfa52089149157b5ff23de027ac5ab781800a578192d175462103d3bde5d63bdb3a6379b461be64dad45eabff42f758543a9645afd42f6d4248282103ed1e8d5109c9ed66f7941bc53cc71137baa76d50d274bda8d5e8ffbd6e61fe9a5fae736402c00fb269522103aab896d53a8e7d6433137bbba940f9c521e085dd07e60994579b64a6d992cf79210291b7d0b1b692f8f524516ed950872e5da10fb1b808b5a526dedc6fed1cf29807210386aa9372fbab374593466bc5451dc59954e90787f08060964d95c87ef34ca5bb53ae68")
287          assert_equal(res["segwit"]["desc"], "wsh(or_d(multi(11,020e0338c96a8870479f2396c373cc7696ba124e8635d41b0ea581112b67817261,02675333a4e4b8fb51d9d4e22fa5a8eaced3fdac8a8cbf9be8c030f75712e6af99,02896807d54bc55c24981f24a453c60ad3e8993d693732288068a23df3d9f50d48,029e51a5ef5db3137051de8323b001749932f2ff0d34c82e96a2c2461de96ae56c,02a4e1a9638d46923272c266631d94d36bdb03a64ee0e14c7518e49d2f29bc4010,031c41fdbcebe17bec8d49816e00ca1b5ac34766b91c9f2ac37d39c63e5e008afb,03079e252e85abffd3c401a69b087e590a9b86f33f574f08129ccbd3521ecf516b,03111cf405b627e22135b3b3733a4a34aa5723fb0f58379a16d32861bf576b0ec2,0318f331b3e5d38156da6633b31929c5b220349859cc9ca3d33fb4e68aa0840174,03230dae6b4ac93480aeab26d000841298e3b8f6157028e47b0897c1e025165de1,035abff4281ff00660f99ab27bb53e6b33689c2cd8dcd364bc3c90ca5aea0d71a6,03bd45cddfacf2083b14310ae4a84e25de61e451637346325222747b157446614c,03cc297026b06c71cbfa52089149157b5ff23de027ac5ab781800a578192d17546,03d3bde5d63bdb3a6379b461be64dad45eabff42f758543a9645afd42f6d424828,03ed1e8d5109c9ed66f7941bc53cc71137baa76d50d274bda8d5e8ffbd6e61fe9a),and_v(v:older(4032),multi(2,03aab896d53a8e7d6433137bbba940f9c521e085dd07e60994579b64a6d992cf79,0291b7d0b1b692f8f524516ed950872e5da10fb1b808b5a526dedc6fed1cf29807,0386aa9372fbab374593466bc5451dc59954e90787f08060964d95c87ef34ca5bb))))#7jwwklk4")
288  
289      def run_test(self):
290          self.log.info("Test decoding of standard input scripts [scriptSig]")
291          self.decodescript_script_sig()
292          self.log.info("Test decoding of standard output scripts [scriptPubKey]")
293          self.decodescript_script_pub_key()
294          self.log.info("Test 'asm' script decoding of transactions")
295          self.decoderawtransaction_asm_sighashtype()
296          self.log.info("Data-driven tests")
297          self.decodescript_datadriven_tests()
298          self.log.info("Miniscript descriptor decoding")
299          self.decodescript_miniscript()
300  
301  if __name__ == '__main__':
302      DecodeScriptTest(__file__).main()