ZIP: 48
Title: Transparent Multisig Wallets
Owners: Kris Nuttycombe <kris@electriccoin.co>
        Jack Grigg <jack@electriccoin.co>
        Daira-Emma Hopwood <daira-emma@electriccoin.co>
        Arya <arya@zfnd.org>
Credits: Fontaine
Status: Draft
Category: Wallet
Created: 2025-08-25
License: MIT
Discussions-To: <https://github.com/zcash/zips/issues/1059>

Terminology

The key words “MUST”, “REQUIRED”, “MUST NOT”, “SHOULD”, and “MAY” in this document are to be interpreted as described in BCP 14 1 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 2.

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.

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 3. Each of these has some problem when attempting to apply it as-written to Zcash:

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.

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.

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.

Specification

This ZIP applies to both Mainnet and Testnet, using the same \(\mathit{coin\_type}\) constants as defined in 7 where applicable. Note that in keeping with that document, all cryptocurrency testnets share \(\mathit{coin\_type}\) index 1.

Output descriptor and script

Zcash wallets SHOULD use the BIP 383 8 sortedmulti() script expression to produce Zcash P2MS scripts, which would then be contained in the BIP 381 9 sh() script expression to produce Zcash P2SH addresses.

The following BIP 388 10 wallet descriptor template produces a 2-of-3 P2SH multisig wallet compatible with this ZIP:

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

Hierarchical Derivation

Given a set of participants that each have some seed material (e.g. BIP 39 11 mnemonic phrases), and a BIP 380 12 output descriptor that encodes the desired multisig policy, wallets need to produce their individual contributions to the BIP 388 key information vector 13. This specification adopts BIP 48 5 for this purpose, with the following modification:

Transaction construction

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

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.

Examples

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 13:

[
  "[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 15 derived from this policy 16 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>/*
  )
)

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 7 \(\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 17 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).

Reference implementation

TBD

References


  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”  ↩︎

  2. Zcash Protocol Specification, Version 2024.5.1. Section 3.12: Mainnet and Testnet  ↩︎

  3. BIP 32: Hierarchical Deterministic Wallets  ↩︎

  4. BIP 45: Structure for Deterministic P2SH Multisignature Wallets  ↩︎

  5. BIP 48: Multi-Script Hierarchy for Multi-Sig Wallets  ↩︎

  6. BIP 87: Hierarchy for Deterministic Multisig Wallets  ↩︎

  7. SLIP-0044: Registered coin types for BIP-0044  ↩︎

  8. BIP 383: Multisig Output Script Descriptors  ↩︎

  9. BIP 381: Non-Segwit Output Script Descriptors  ↩︎

  10. BIP 388: Wallet Policies for Descriptor Wallets  ↩︎

  11. BIP 39: Mnemonic code for generating deterministic keys  ↩︎

  12. BIP 380: Output Script Descriptors General Operation  ↩︎

  13. BIP 388: Wallet Policies for Descriptor Wallets. Key information vector  ↩︎

  14. zip-pczt  ↩︎

  15. BIP 389: Multipath Descriptor Key Expressions  ↩︎

  16. BIP 388: Wallet Policies for Descriptor Wallets. Descriptor derivation  ↩︎

  17. ZIP 1016: Community and Coinholder Funding Model  ↩︎