@@ -171,6 +171,7 @@ def json(self) -> typing.Dict:
171171 'prikey' : [e .json () for e in self .prikey ],
172172 'pubkey' : [e .json () for e in self .pubkey ],
173173 'redeem' : self .redeem .hex (),
174+ 'redeem_hash' : self .redeem_hash .hex (),
174175 'script' : self .script .hex (),
175176 'addr' : self .addr ,
176177 }
@@ -240,6 +241,41 @@ def sign(self, tx: pabtc.core.Transaction) -> None:
240241 e .witness = [s , self .pubkey .sec ()]
241242
242243
244+ class Signerp2wshp2ms (Signer ):
245+ def __init__ (self , prikey : typing .List [pabtc .core .PriKey ], pubkey : typing .List [pabtc .core .PubKey ]) -> None :
246+ self .prikey = prikey
247+ self .pubkey = pubkey
248+ self .redeem = pabtc .core .ScriptPubKey .p2ms (len (prikey ), pubkey )
249+ self .redeem_hash = pabtc .core .hashwsh (self .redeem )
250+ self .script = pabtc .core .ScriptPubKey .p2wsh (self .redeem_hash )
251+ self .addr = pabtc .core .Address .p2wsh (self .redeem_hash )
252+
253+ def __repr__ (self ) -> str :
254+ return json .dumps (self .json ())
255+
256+ def json (self ) -> typing .Dict :
257+ return {
258+ 'prikey' : [e .json () for e in self .prikey ],
259+ 'pubkey' : [e .json () for e in self .pubkey ],
260+ 'redeem' : self .redeem .hex (),
261+ 'redeem_hash' : self .redeem_hash .hex (),
262+ 'script' : self .script .hex (),
263+ 'addr' : self .addr ,
264+ }
265+
266+ def sign (self , tx : pabtc .core .Transaction ) -> None :
267+ for i , e in enumerate (tx .vin ):
268+ # The op_checkmultisig opcode has a bug where it pops one extra element off the stack than it needs to.
269+ # This is why the witness includes an extra "dummy value" (00) before the signatures when using a p2ms as
270+ # the Witness Script.
271+ sig = [bytearray ()]
272+ for prikey in self .prikey :
273+ s = prikey .sign_ecdsa_der (tx .digest_segwit_v0 (i , pabtc .core .sighash_all , self .redeem ))
274+ s .append (pabtc .core .sighash_all )
275+ sig .append (s )
276+ e .witness = sig + [self .redeem ]
277+
278+
243279class Signerp2tr (Signer ):
244280 def __init__ (self , prikey : pabtc .core .PriKey , merkle : bytearray ) -> None :
245281 self .prikey = prikey
0 commit comments