# `BSV.Transaction.P2MPKH`
[🔗](https://github.com/Bittoku/bsv_sdk_elixir/blob/main/lib/bsv/transaction/p2mpkh.ex#L1)

Pay-to-Multiple-Public-Key-Hash (P2MPKH) signing template.

Extends P2PKH to support m-of-n multisig ownership. The locking script
stores only the HASH160 of a raw multisig script (the "MPKH") — the full
multisig script remains hidden until spending.

## MultisigScript

A multisig script is represented as a map:

    %{threshold: 2, public_keys: [pk1, pk2, pk3]}

where each public key is a 33-byte compressed SEC1 binary.

## Standalone locking script (bare multisig)

    OP_m <pk1> <pk2> … <pkN> OP_n OP_CHECKMULTISIG

## Standalone unlocking script

    OP_0 <sig1> <sig2> … <sigM>

## STAS unlocking script (P2MPKH mode)

    <sig1> <sig2> … <sigM> <serialized_multisig_script>

STAS handles HASH160 verification and OP_CHECKMULTISIG internally.

# `multisig_script`

```elixir
@type multisig_script() :: %{threshold: pos_integer(), public_keys: [binary()]}
```

# `t`

```elixir
@type t() :: %BSV.Transaction.P2MPKH{
  multisig: multisig_script(),
  private_keys: [BSV.PrivateKey.t()],
  sighash_flag: non_neg_integer()
}
```

# `estimate_length`

Estimated unlocking script length: 1 (OP_0) + m * 73.

# `from_script_bytes`

```elixir
@spec from_script_bytes(binary()) :: {:ok, multisig_script()} | {:error, term()}
```

Parse a multisig script from raw bytes.

Expects: `OP_m <pk1_33bytes> … <pkN_33bytes> OP_n OP_CHECKMULTISIG`

# `lock`

```elixir
@spec lock(multisig_script()) :: {:ok, BSV.Script.t()} | {:error, term()}
```

Create a bare multisig locking script.

Produces: `OP_m <pk1> … <pkN> OP_n OP_CHECKMULTISIG`

# `mpkh`

```elixir
@spec mpkh(multisig_script()) :: &lt;&lt;_::160&gt;&gt;
```

Compute the MPKH — 20-byte HASH160 of the serialized multisig script.

# `new_multisig`

```elixir
@spec new_multisig(pos_integer(), [binary()]) ::
  {:ok, multisig_script()} | {:error, term()}
```

Create a new multisig script map.

## Arguments
- `threshold` — minimum signatures required (m)
- `public_keys` — list of 33-byte compressed public keys

## Returns
`{:ok, multisig_script()}` or `{:error, reason}`

# `sign`

Sign a transaction input producing a bare multisig unlocking script.

Produces: `OP_0 <sig1> <sig2> … <sigM>`

# `to_script_bytes`

```elixir
@spec to_script_bytes(multisig_script()) :: binary()
```

Serialize a multisig script to raw bytes.

Produces: `OP_m <pk1> <pk2> … <pkN> OP_n OP_CHECKMULTISIG`

# `unlock`

```elixir
@spec unlock([BSV.PrivateKey.t()], multisig_script(), keyword()) ::
  {:ok, t()} | {:error, term()}
```

Create a P2MPKH unlocker for bare multisig.

## Arguments
- `private_keys` — the m private keys satisfying the threshold
- `multisig` — the full multisig script
- `opts` — `:sighash_flag` (default `0x41`)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
