# ZIP 48: Transparent Multisig Wallets

Status: Draft

Owners: Kris Nuttycombe, Jack Grigg, Daira-Emma Hopwood, Arya

Snapshot: a34cfc091434275120ff017c92c3b50d3cef623a

Source date: 2026-10-16T02:56:04+01:00

[Source revision](https://github.com/zcash/zips/commit/a34cfc091434275120ff017c92c3b50d3cef623a)

[Official source](https://zips.z.cash/zip-0048) · [Source file](https://github.com/zcash/zips/blob/a34cfc091434275120ff017c92c3b50d3cef623a/zips/zip-0048.md) · [Discussion](https://github.com/zcash/zips/issues/1059)

Preamble

**ZIP**: 48

**Title**: Transparent Multisig Wallets

**Owners**: 

- [Kris Nuttycombe](mailto:kris@nutty.land)
- [Jack Grigg](mailto:thestr4d@gmail.com)
- [Daira-Emma Hopwood](mailto:daira@jacaranda.org)
- [Arya](mailto:arya@zfnd.org)

**Credits**: Fontaine

**Status**: Draft

**Category**: Wallet

**Created**: 2025-08-25

**License**: MIT

**Discussions-To**: [https://github.com/zcash/zips/issues/1059](https://github.com/zcash/zips/issues/1059)

<a id="terminology"></a>

## Terminology

The key words "MUST", "REQUIRED", "MUST NOT", "SHOULD", and "MAY" in this
document are to be interpreted as described in BCP 14 <a id="user-content-fnref-bcp14"></a>
[1](#user-content-fn-bcp14) when, and
only when, they appear in all capitals.

The terms "Mainnet" and "Testnet" in this document are to be interpreted as
defined in the Zcash protocol specification <a id="user-content-fnref-protocol-networks"></a>
[2](#user-content-fn-protocol-networks).

<a id="abstract"></a>

## Abstract

This ZIP defines how wallets should implement transparent multisignature addresses in the
Zcash ecosystem. It specifies how to derive the necessary key material in a deterministic
way, and how to create transactions spending transparent multisig-controlled funds.

Any future changes, or new transparent protocols or scripts, will be made as Revisions to
this ZIP.

<a id="motivation"></a>

## Motivation

There are a variety of important use cases for funds being controlled by a quorum of
signers. In Bitcoin, these use cases were served via "P2SH multisig", or more specifically
a Pay-to-Multi-Signature (P2MS) script specified by a P2SH address.

A P2SM script can be constructed from any set of secp256k1 public keys, and anyone can use
any mechanism for obtaining or storing the corresponding signing keys by private agreement.
However, in order to ensure that funds are easily recoverable from backups, several
different BIPs emerged for P2MS scripts using BIP 32 Hierarchical Derivation <a id="user-content-fnref-bip-0032"></a>
[3](#user-content-fn-bip-0032).
Each of these has some problem when attempting to apply it as-written to Zcash:

- BIP 45 <a id="user-content-fnref-bip-0045"></a>
  [4](#user-content-fn-bip-0045) uses `m / purpose' / cosigner_index / change / address_index`.
  
  
  
  
  
  - The problem is that unlike BIP 44, this BIP does not include `coin_type' / account'`
    in its derivation path. If naively applied to Zcash, it would result in key reuse
    between Bitcoin and Zcash, which creates the potential for cross-protocol attacks
    that would be complex to rule out.
  
  - This is the BIP that essentially all hardware wallets use for Bitcoin P2SH multisig.

- BIP 48 <a id="user-content-fnref-bip-0048"></a>
  [5](#user-content-fn-bip-0048) uses `m / purpose' / coin_type' / account' / script_type' / change / address_index`
  
  
  
  
  
  - The problem is that `script_type` is specified solely for Bitcoin's Native Segwit (P2WSH)
    and Nested Segwit (P2SH-P2WSH). Several conflicting proposed `script_type` constants
    for P2SH have been considered at various points, and were rejected due to P2SH being
    considered "legacy" in the context of Bitcoin.
  
  - This is the BIP that essentially all hardware wallets use for P2WSH and P2SH-P2WSH on
    any Bitcoin-compatible chain.

- BIP 87 <a id="user-content-fnref-bip-0087"></a>
  [6](#user-content-fn-bip-0087) uses `m / purpose' / coin_type' / account' / change / address_index`
  
  
  
  
  
  - The problem is that this BIP does not consider key reuse across different scripts
    (which are to some degree different payment protocols) to be an issue, whereas we do.
  
  - This BIP is essentially unused by hardware wallets (which instead implement BIPs 45
    and 48).

While there is verifiable usage of P2SH multisig on the Zcash chain, there has been no
standard approach for public deployments (likely due to the above issues), and thus no
support for it in Zcash-compatible hardware wallets. This ZIP fills the gap.

<a id="privacy-implications"></a>

## Privacy Implications

This does not have any privacy implications beyond what users already accept by
using the transparent protocol and BIP 44 in particular for transparent address
derivation.

<a id="requirements"></a>

## Requirements

Hardware wallet providers should only need to make limited changes relative to how they
support Bitcoin P2SH multisig. As such, this specification should hew closely to the
specifications used in the Bitcoin ecosystem for P2SH support.

<a id="specification"></a>

## Specification

This ZIP applies to both Mainnet and Testnet, using the same $\mathit{coin\_type}$
constants as defined in <a id="user-content-fnref-slip-0044"></a>
[7](#user-content-fn-slip-0044) where applicable. Note that in keeping with that
document, all cryptocurrency testnets share $\mathit{coin\_type}$ index 1.

<a id="output-descriptor-and-script"></a>

### Output descriptor and script

Zcash wallets SHOULD use the BIP 383 <a id="user-content-fnref-bip-0383"></a>
[8](#user-content-fn-bip-0383) `sortedmulti()` script expression to
produce Zcash P2MS scripts, which would then be contained in the BIP 381 <a id="user-content-fnref-bip-0381"></a>
[9](#user-content-fn-bip-0381)
`sh()` script expression to produce Zcash P2SH addresses.

The following BIP 388 <a id="user-content-fnref-bip-0388"></a>
[10](#user-content-fn-bip-0388) wallet descriptor template produces a 2-of-3 P2SH
multisig wallet compatible with this ZIP:

```
sh(sortedmulti(2,@0/**,@1/**,@2/**))
```

<a id="hierarchical-derivation"></a>

### Hierarchical Derivation

Given a set of participants that each have some seed material (e.g. BIP 39 <a id="user-content-fnref-bip-0039"></a>
[11](#user-content-fn-bip-0039)
mnemonic phrases), and a BIP 380 <a id="user-content-fnref-bip-0380"></a>
[12](#user-content-fn-bip-0380) output descriptor that encodes the desired
multisig policy, wallets need to produce their individual contributions to the BIP 388
key information vector <a id="user-content-fnref-bip-0388-key-information-vector"></a>
[13](#user-content-fn-bip-0388-key-information-vector). This specification adopts
BIP 48 <a id="user-content-fnref-bip-0048-2"></a>
[5](#user-content-fn-bip-0048) for this purpose, with the following modification:

- The $\mathit{script\_type}$ values for Native Segwit and Nested Segwit MUST NOT be used
  in a Zcash context.

- The following Zcash-specific $\mathit{script\_type}$ key spaces are defined:
  
  
  
  
  
  - A path component of $133000'$ represents “Zcash P2SH”.

<a id="transaction-construction"></a>

### Transaction construction

The transaction construction workflow for a P2SH multisig wallet is as follows:

- One of the participants uses their local wallet to construct a PCZT [^zip-pczt] that
  spends transparent UTXOs controlled by the multisig wallet, with the desired outputs,
  and a change output to a P2SH address derived at the path
  `m/48'/coin_type'/account'/133000'/1/*`.

- The PCZT is conveyed to the other wallet participants out-of-band (via a private and
  authenticated channel, such as a group end-to-end-encrypted messenger).

- Each participant's wallet MUST verify that the PCZT's change outputs are to an address
  that the multisig wallet controls.

- Each participant verifies that the PCZT performs the spend action that they expect.

- Each participant modifies their copy of the PCZT to include their signature(s) using
  their wallet.

- Each participant conveys their signed PCZT to one (or more) of the other wallet
  participants (likely via the same channel that the unsigned PCZT was received on).

- One participant takes a threshold of signed PCZTs, combines them, and extracts the final
  transaction for broadcasting to the network.

Wallets SHOULD ensure they are fully synced before proposing a transaction that generates
transparent change, to minimize the likelihood of reusing a P2SH change address.

<a id="examples"></a>

## Examples

<a id="2-of-3-p2sh-multisig-on-zcash-mainnet"></a>

### 2-of-3 P2SH multisig on Zcash mainnet

Let the seeds for the three participants be (in hex):

```
[
  "0101010101010101010101010101010101010101010101010101010101010101",
  "0202020202020202020202020202020202020202020202020202020202020202",
  "0303030303030303030303030303030303030303030303030303030303030303"
]
```

TODO: Update example below with actual key fingerprints and xpub encodings.

The wallet descriptor template for this multisig is:

```
sh(sortedmulti(2,@0/**,@1/**,@2/**))
```

The three parties each derive their transparent extended public key from their respective
wallet seed, using the path `m/48'/133'/0'/133000'`. The parties then combine their
respective keys to produce a key information vector <a id="user-content-fnref-bip-0388-key-information-vector-2"></a>
[13](#user-content-fn-bip-0388-key-information-vector):

```
[
  "[MSTKFP_0/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_0",
  "[MSTKFP_1/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_1",
  "[MSTKFP_2/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_2"
]
```

The wallet policy is the composition of the wallet descriptor template and the key
information vector. The corresponding multipath descriptor <a id="user-content-fnref-bip-0389"></a>
[14](#user-content-fn-bip-0389) derived from this
policy <a id="user-content-fnref-bip-0388-descriptor-derivation"></a>
[15](#user-content-fn-bip-0388-descriptor-derivation) is (newlines and whitespace added for legibility):

```
sh(
  sortedmulti(
    2,
    [MSTKFP_0/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_0/<0;1>/*,
    [MSTKFP_1/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_1/<0;1>/*,
    [MSTKFP_2/48'/133'/0'/133000']EXTENDED_PUBLIC_KEY_2/<0;1>/*
  )
)
```

<a id="rationale"></a>

## Rationale

The choice to use BIP 48 means that participants are not restricted to constructing a
single P2SH address; once a wallet has obtained the completed wallet policy, it can
(without additional coordination) produce the same deterministic sequence of P2SH
addresses as every other participant.

We specify a likely-non-colliding $\mathit{script\_type}$ instead of using a path
component of either $0'$ (the gap left in BIP 48) or $2'$ (the next unassigned constant in
BIP 48), because both of those values have in the past been proposed and rejected as
referring to P2SH. This means that there is no compatibility benefit to trying to use one
or the other, and the likelihood of a collision with some other use case is higher.
Instead we pick a value that is prefixed (in decimal) with the SLIP 44 <a id="user-content-fnref-slip-0044-2"></a>
[7](#user-content-fn-slip-0044)
$\mathit{coin\_type}$ for Zcash mainnet, which is highly unlikely to organically occur in
another related specification.

By not using BIP 45, Zcash addresses will not be compatible with BIP 45 P2SH derivation
paths. We consider this acceptable because we explicitly do not want users that use the
same mnemonic phrase for both Bitcoin and Zcash to produce addresses that reuse the same
public keys.

By not using BIP 45 (with a $\mathit{cosigner\_index}$ path element), all cosigners produce
the same sequence of P2SH addresses. This is good for agreement on, for example, the ZIP 1016 <a id="user-content-fnref-zip-1016"></a>
[16](#user-content-fn-zip-1016)
Key-Holder Organizations’ Mainnet address, but in general usage means that two cosigners
proposing transactions can race and use the same P2SH address twice. This could result in a
situation where different members of the signing set inadvertently give the same P2SH
address to different counterparties, linking the associated payment
activity. We consider this tradeoff acceptable because it aligns with what hardware
wallets have done for years (implying that users are fine with the usability). We consider
the risk acceptable because avoiding linkage between transparent addresses is hard in any
case, and not something that Zcash actively attempts to avoid (the shielded protocols are
designed for this use case).

<a id="reference-implementation"></a>

## Reference implementation

TBD

<a id="references"></a>

## References

<a id="footnote-label"></a>

### Footnotes

1. [Information on BCP 14 — "RFC 2119: Key words for use in RFCs to Indicate Requirement Levels" and "RFC 8174: Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words"](https://www.rfc-editor.org/info/bcp14) [↩](#user-content-fnref-bcp14)

2. [Zcash Protocol Specification, Version 2024.5.1. Section 3.12: Mainnet and Testnet](protocol/protocol.pdf#networks) [↩](#user-content-fnref-protocol-networks)

3. [BIP 32: Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) [↩](#user-content-fnref-bip-0032)

4. [BIP 45: Structure for Deterministic P2SH Multisignature Wallets](https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki) [↩](#user-content-fnref-bip-0045)

5. [BIP 48: Multi-Script Hierarchy for Multi-Sig Wallets](https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki) [↩](#user-content-fnref-bip-0048) [↩2](#user-content-fnref-bip-0048-2)

6. [BIP 87: Hierarchy for Deterministic Multisig Wallets](https://github.com/bitcoin/bips/blob/master/bip-0087.mediawiki) [↩](#user-content-fnref-bip-0087)

7. [SLIP-0044: Registered coin types for BIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) [↩](#user-content-fnref-slip-0044) [↩2](#user-content-fnref-slip-0044-2)

8. [BIP 383: Multisig Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0383.mediawiki) [↩](#user-content-fnref-bip-0383)

9. [BIP 381: Non-Segwit Output Script Descriptors](https://github.com/bitcoin/bips/blob/master/bip-0381.mediawiki) [↩](#user-content-fnref-bip-0381)

10. [BIP 388: Wallet Policies for Descriptor Wallets](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki) [↩](#user-content-fnref-bip-0388)

11. [BIP 39: Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) [↩](#user-content-fnref-bip-0039)

12. [BIP 380: Output Script Descriptors General Operation](https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki) [↩](#user-content-fnref-bip-0380)

13. [BIP 388: Wallet Policies for Descriptor Wallets. Key information vector](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki#key-information-vector) [↩](#user-content-fnref-bip-0388-key-information-vector) [↩2](#user-content-fnref-bip-0388-key-information-vector-2)

14. [BIP 389: Multipath Descriptor Key Expressions](https://github.com/bitcoin/bips/blob/master/bip-0389.mediawiki) [↩](#user-content-fnref-bip-0389)

15. [BIP 388: Wallet Policies for Descriptor Wallets. Descriptor derivation](https://github.com/bitcoin/bips/blob/master/bip-0388.mediawiki#descriptor-derivation) [↩](#user-content-fnref-bip-0388-descriptor-derivation)

16. [ZIP 1016: Community and Coinholder Funding Model](/zip/1016) [↩](#user-content-fnref-zip-1016)

## Citation relationships

Cites: [ZIP 1016](https://zips.tools/zip/1016)

Cited by: [ZIP 271](https://zips.tools/zip/271), [ZIP 316](https://zips.tools/zip/316), [ZIP 374](https://zips.tools/zip/374)