|
| 1 | +import pabtc |
| 2 | + |
| 3 | +# This example shows how to create a P2MR script with two unlock conditions: p2pk and p2ms. |
| 4 | + |
| 5 | + |
| 6 | +# Here created two scripts, one of which is a p2pk script, which requires that it can only be unlocked by private key 2, |
| 7 | +# and the other is an 2-of-2 multisig script. |
| 8 | +mast = pabtc.core.TapBranch( |
| 9 | + pabtc.core.TapLeaf(pabtc.core.TapScript.p2pk(pabtc.core.PriKey(2).pubkey())), |
| 10 | + pabtc.core.TapLeaf(pabtc.core.TapScript.p2ms(2, [pabtc.core.PriKey(3).pubkey(), pabtc.core.PriKey(4).pubkey()])), |
| 11 | +) |
| 12 | +root = mast.hash |
| 13 | + |
| 14 | + |
| 15 | +class Signerp2mrp2pk(pabtc.wallet.Signer): |
| 16 | + def __init__(self) -> None: |
| 17 | + self.script = pabtc.core.ScriptPubKey.p2mr(root) |
| 18 | + # In p2tr, the least significant bit is the parity bit of the output public key's y-coordinate, which can be |
| 19 | + # either 0 or 1. In p2mr, which has no internal key/key path cost, this bit is always 1. |
| 20 | + self.prefix = 0xc0 + 1 |
| 21 | + self.addr = pabtc.core.Address.p2mr(root) |
| 22 | + |
| 23 | + def sign(self, tx: pabtc.core.Transaction) -> None: |
| 24 | + assert isinstance(mast.l, pabtc.core.TapLeaf) |
| 25 | + for i, e in enumerate(tx.vin): |
| 26 | + m = tx.digest_segwit_v1(i, pabtc.core.sighash_all, mast.l.script) |
| 27 | + e.witness = [ |
| 28 | + pabtc.core.PriKey(2).sign_schnorr(m) + bytearray([pabtc.core.sighash_all]), |
| 29 | + mast.l.script, |
| 30 | + bytearray([self.prefix]) + mast.r.hash, |
| 31 | + ] |
| 32 | + |
| 33 | + |
| 34 | +class Signerp2mrp2ms(pabtc.wallet.Signer): |
| 35 | + def __init__(self) -> None: |
| 36 | + self.script = pabtc.core.ScriptPubKey.p2mr(root) |
| 37 | + # In p2tr, the least significant bit is the parity bit of the output public key's y-coordinate, which can be |
| 38 | + # either 0 or 1. In p2mr, which has no internal key/key path cost, this bit is always 1. |
| 39 | + self.prefix = 0xc0 + 1 |
| 40 | + self.addr = pabtc.core.Address.p2mr(root) |
| 41 | + |
| 42 | + def sign(self, tx: pabtc.core.Transaction) -> None: |
| 43 | + assert isinstance(mast.r, pabtc.core.TapLeaf) |
| 44 | + for i, e in enumerate(tx.vin): |
| 45 | + m = tx.digest_segwit_v1(i, pabtc.core.sighash_all, mast.r.script) |
| 46 | + e.witness = [ |
| 47 | + pabtc.core.PriKey(4).sign_schnorr(m) + bytearray([pabtc.core.sighash_all]), |
| 48 | + pabtc.core.PriKey(3).sign_schnorr(m) + bytearray([pabtc.core.sighash_all]), |
| 49 | + mast.r.script, |
| 50 | + bytearray([self.prefix]) + mast.l.hash, |
| 51 | + ] |
0 commit comments