Skip to content

Derive and match P2SH-P2WPKH addresses #82

@oritwoen

Description

@oritwoen

DerivedKey currently produces four address formats: P2PKH compressed, P2PKH uncompressed, P2WPKH (bech32), and P2TR (taproot). The matcher checks all four. Missing from both: P2SH-P2WPKH.

P2SH-P2WPKH addresses (the ones starting with 3 on mainnet) were the dominant address format from roughly 2017 through 2021, before native segwit and taproot took over. A lot of funds moved through these addresses. If a vulnerable key had coins sent to its P2SH-P2WPKH address, the current scanner wouldn't find them because DerivedKey never computes that address and Matcher never checks it.

The derivation is straightforward - wrap the P2WPKH witness program in a P2SH script:

  1. Take the compressed public key
  2. Compute OP_0 <20-byte-pubkey-hash> (the witness program)
  3. Hash that script with HASH160
  4. Encode as a P2SH address (base58check with version byte 0x05)

The bitcoin crate already supports this via Address::p2shwpkh().

Changes needed:

  • Add p2sh_p2wpkh: String field to DerivedKey
  • Compute it in KeyDeriver::derive()
  • Add P2shP2wpkh variant to AddressType enum
  • Include it in DerivedKey::addresses() (becomes 5 elements)
  • Update output formats (console CSV columns, storage schema) to include the new field

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions