6
6
7
7
from test_framework .test_framework import BitcoinTestFramework
8
8
from test_framework .util import *
9
- from test_framework .mininode import sha256 , ripemd160 , CTransaction , CTxIn , COutPoint , CTxOut
9
+ from test_framework .mininode import sha256 , ripemd160 , CTransaction , CTxIn , COutPoint , CTxOut , COIN
10
10
from test_framework .address import script_to_p2sh , key_to_p2pkh
11
- from test_framework .script import CScript , OP_HASH160 , OP_CHECKSIG , OP_0 , hash160 , OP_EQUAL , OP_DUP , OP_EQUALVERIFY , OP_1 , OP_2 , OP_CHECKMULTISIG
11
+ from test_framework .script import CScript , OP_HASH160 , OP_CHECKSIG , OP_0 , hash160 , OP_EQUAL , OP_DUP , OP_EQUALVERIFY , OP_1 , OP_2 , OP_CHECKMULTISIG , hash160
12
12
from io import BytesIO
13
- from test_framework .mininode import FromHex
13
+ from test_framework .mininode import FromHex , ToHex
14
14
15
15
NODE_0 = 0
16
16
NODE_1 = 1
17
17
NODE_2 = 2
18
18
WIT_V0 = 0
19
19
WIT_V1 = 1
20
20
21
- def witness_script ( version , pubkey ):
22
- if ( version == 0 ):
23
- pubkeyhash = bytes_to_hex_str ( ripemd160 ( sha256 ( hex_str_to_bytes ( pubkey ))))
24
- pkscript = "0014" + pubkeyhash
25
- elif ( version == 1 ):
26
- # 1-of-1 multisig
27
- scripthash = bytes_to_hex_str ( sha256 ( hex_str_to_bytes ("5121" + pubkey + "51ae" ) ))
28
- pkscript = "0020" + scripthash
21
+ # Create a scriptPubKey corresponding to either a P2WPKH output for the
22
+ # given pubkey, or a P2WSH output of a 1-of-1 multisig for the given
23
+ # pubkey. Returns the hex encoding of the scriptPubKey.
24
+ def witness_script ( use_p2wsh , pubkey ):
25
+ if ( use_p2wsh == False ):
26
+ # P2WPKH instead
27
+ pubkeyhash = hash160 ( hex_str_to_bytes (pubkey ))
28
+ pkscript = CScript ([ OP_0 , pubkeyhash ])
29
29
else :
30
- assert ( "Wrong version" == "0 or 1" )
31
- return pkscript
32
-
33
- def addlength ( script ):
34
- scriptlen = format ( len ( script ) // 2 , 'x' )
35
- assert ( len ( scriptlen ) == 2 )
36
- return scriptlen + script
37
-
38
- def create_witnessprogram (version , node , utxo , pubkey , encode_p2sh , amount ):
39
- pkscript = witness_script (version , pubkey )
30
+ # 1-of-1 multisig
31
+ witness_program = CScript ([ OP_1 , hex_str_to_bytes ( pubkey ), OP_1 , OP_CHECKMULTISIG ])
32
+ scripthash = sha256 ( witness_program )
33
+ pkscript = CScript ([ OP_0 , scripthash ])
34
+ return bytes_to_hex_str ( pkscript )
35
+
36
+ # Return a transaction (in hex) that spends the given utxo to a segwit output,
37
+ # optionally wrapping the segwit output using P2SH.
38
+ def create_witnessprogram (use_p2wsh , utxo , pubkey , encode_p2sh , amount ):
39
+ pkscript = hex_str_to_bytes ( witness_script (use_p2wsh , pubkey ) )
40
40
if (encode_p2sh ):
41
- p2sh_hash = bytes_to_hex_str ( ripemd160 ( sha256 ( hex_str_to_bytes ( pkscript ))) )
42
- pkscript = "a914" + p2sh_hash + "87"
43
- inputs = []
44
- outputs = {}
45
- inputs . append ({ "txid" : utxo [ "txid" ], "vout" : utxo [ "vout" ]} )
46
- DUMMY_P2SH = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP"
47
- outputs [ DUMMY_P2SH ] = amount
48
- tx_to_witness = node . createrawtransaction ( inputs , outputs )
49
- #replace dummy output with our own
50
- tx_to_witness = tx_to_witness [ 0 : 110 ] + addlength ( pkscript ) + tx_to_witness [ - 8 :]
51
- return tx_to_witness
52
-
53
- def send_to_witness (version , node , utxo , pubkey , encode_p2sh , amount , sign = True , insert_redeem_script = "" ):
54
- tx_to_witness = create_witnessprogram (version , node , utxo , pubkey , encode_p2sh , amount )
41
+ p2sh_hash = hash160 ( pkscript )
42
+ pkscript = CScript ([ OP_HASH160 , p2sh_hash , OP_EQUAL ])
43
+ tx = CTransaction ()
44
+ tx . vin . append ( CTxIn ( COutPoint ( int ( utxo [ "txid" ], 16 ), utxo [ "vout" ]), b"" ))
45
+ tx . vout . append (CTxOut ( int ( amount * COIN ), pkscript ) )
46
+ return ToHex ( tx )
47
+
48
+ # Create a transaction spending a given utxo to a segwit output corresponding
49
+ # to the given pubkey: use_p2wsh determines whether to use P2WPKH or P2WSH;
50
+ # encode_p2sh determines whether to wrap in P2SH.
51
+ # sign=True will have the given node sign the transaction.
52
+ # insert_redeem_script will be added to the scriptSig, if given.
53
+ def send_to_witness (use_p2wsh , node , utxo , pubkey , encode_p2sh , amount , sign = True , insert_redeem_script = "" ):
54
+ tx_to_witness = create_witnessprogram (use_p2wsh , utxo , pubkey , encode_p2sh , amount )
55
55
if (sign ):
56
56
signed = node .signrawtransaction (tx_to_witness )
57
57
assert ("errors" not in signed or len (["errors" ]) == 0 )
58
58
return node .sendrawtransaction (signed ["hex" ])
59
59
else :
60
60
if (insert_redeem_script ):
61
- tx_to_witness = tx_to_witness [0 :82 ] + addlength (insert_redeem_script ) + tx_to_witness [84 :]
61
+ tx = FromHex (CTransaction (), tx_to_witness )
62
+ tx .vin [0 ].scriptSig += CScript ([hex_str_to_bytes (insert_redeem_script )])
63
+ tx_to_witness = ToHex (tx )
62
64
63
65
return node .sendrawtransaction (tx_to_witness )
64
66
@@ -180,8 +182,8 @@ def run_test(self):
180
182
self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V0 ][0 ], False )
181
183
self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V1 ][0 ], False )
182
184
# unsigned with redeem script
183
- self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V0 ][0 ], False , addlength ( witness_script (0 , self .pubkey [0 ]) ))
184
- self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V1 ][0 ], False , addlength ( witness_script (1 , self .pubkey [0 ]) ))
185
+ self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V0 ][0 ], False , witness_script (False , self .pubkey [0 ]))
186
+ self .fail_accept (self .nodes [0 ], p2sh_ids [NODE_0 ][WIT_V1 ][0 ], False , witness_script (True , self .pubkey [0 ]))
185
187
# signed
186
188
self .fail_accept (self .nodes [0 ], wit_ids [NODE_0 ][WIT_V0 ][0 ], True )
187
189
self .fail_accept (self .nodes [0 ], wit_ids [NODE_0 ][WIT_V1 ][0 ], True )
@@ -205,8 +207,8 @@ def run_test(self):
205
207
self .fail_accept (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V1 ][1 ], False )
206
208
207
209
self .log .info ("Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork" )
208
- self .success_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V0 ][1 ], False , addlength ( witness_script (0 , self .pubkey [2 ]) )) #block 430
209
- self .success_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V1 ][1 ], False , addlength ( witness_script (1 , self .pubkey [2 ]) )) #block 431
210
+ self .success_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V0 ][1 ], False , witness_script (False , self .pubkey [2 ])) #block 430
211
+ self .success_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V1 ][1 ], False , witness_script (True , self .pubkey [2 ])) #block 431
210
212
211
213
self .log .info ("Verify previous witness txs skipped for mining can now be mined" )
212
214
assert_equal (len (self .nodes [2 ].getrawmempool ()), 4 )
@@ -230,8 +232,8 @@ def run_test(self):
230
232
self .log .info ("Verify witness txs without witness data are invalid after the fork" )
231
233
self .fail_mine (self .nodes [2 ], wit_ids [NODE_2 ][WIT_V0 ][2 ], False )
232
234
self .fail_mine (self .nodes [2 ], wit_ids [NODE_2 ][WIT_V1 ][2 ], False )
233
- self .fail_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V0 ][2 ], False , addlength ( witness_script (0 , self .pubkey [2 ]) ))
234
- self .fail_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V1 ][2 ], False , addlength ( witness_script (1 , self .pubkey [2 ]) ))
235
+ self .fail_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V0 ][2 ], False , witness_script (False , self .pubkey [2 ]))
236
+ self .fail_mine (self .nodes [2 ], p2sh_ids [NODE_2 ][WIT_V1 ][2 ], False , witness_script (True , self .pubkey [2 ]))
235
237
236
238
self .log .info ("Verify default node can now use witness txs" )
237
239
self .success_mine (self .nodes [0 ], wit_ids [NODE_0 ][WIT_V0 ][0 ], True ) #block 432
0 commit comments