Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
CIP: 15
Title: Segwit Support
Authors: Devon Weller
Status: Active
Type: Standards Track
Created: 2017-09-12


This is a proposal to support spending and creating segwit outputs for Counterparty transactions

  • Modify counterparty-lib to generate P2WPKH or P2WSH outputs
  • Modify counterparty-lib to parse P2WPKH or P2WSH outputs
  • Modify counterparty-lib to interpret Bech32 (BIP 173) addresses in API methods
  • Modify counterwallet to display Bech32 (BIP 173) P2WPKH addresses in addition to the standard base58 P2PKH addresses


Neither counterparty-lib nor counterwallet are segwit aware. Transactions are constructed using standard P2PKH and P2SH scripts.

By utilizing P2WPKH and P2WSH scripts to send assets, users can spend less on transaction fees sent from counterparty-lib and counterwallet.

Adding segwit compatibility to counterparty-lib also enables potential future enhancements.


Addresses for P2PKH and P2WPKH outputs

Bitcoin uses 20-byte pubkey hashes for standard addresses. These addresses can be represented in base58 format or in Bech32 format as defined in BIP 173.

The same public key hash can be represented in two different address formats. Below is a table for 3 different representations of the public key hash 0x751e76e8199196d454941c45d1b3a323f1433bd6.

Type Representation Preferred Output Type
Public key hash 0x751e76e8199196d454941c45d1b3a323f1433bd6 n/a
base58 address 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH P2PKH
Bech32 address bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 P2WPKH

In this CIP, we will refer to the base58 address as a P2PKH address. Likewise, we will refer to the Bech32 address as a "P2WPKH address" or "segwit address".

P2WPKH addresses

Counterparty will track all P2PKH/P2WPKH account balances by their appropiate segwit aware addresses. Any asset transfers involving the P2PKH or P2WPKH address for a given pubkey hash will be tracked internally by the appropiate redeem script (P2PKH or Witness program).

Users can give out their P2WPKH addresses to other users who use a wallet that supports sending to segwit addresses. Likewise they can provide their P2PKH address to legacy applications and wallets that don't support sending to segwit addresses yet, however, this is generally discouraged.

Note that a traditional BTC wallet would separate P2PKH and P2WPKH addresses by generating new segwit addresses separately from old P2PKH addresses. Counterparty re-uses addresses and therefore must take a different approach to transition users to segwit.

P2WSH addresses

Segwit compatible pay-to-script-hash addresses use 32-byte script hashes instead of the old 20-byte script hashes, this makes them incompatible with applying any backwards compatability tricks.

Compatibility with these addresses will need to either create a new enhanced send format, or reducing the amount of memo space allowed for these kind of addresses. As these kind of addresses impose a completely different set of restrictions on the tricks used to embed data into transactions, the implementation is left for a later CIP.

Segwit embedded inside P2SH

It is possible to embed a P2WPKH or P2WSH inside a P2SH script (NP2WPKH), resulting in a 3xxxx style address and enabling segwit while keeping backwards compatible addresses. The complexity involved in doing this within counterparty-lib and counterwallet is high and the gain is much smaller than using native segwit scripts.

While Counterwallet does not support the use of P2SH addresses, Counterparty remains compatible with P2SH at the protocol level. Other counterparty wallets may implement segwit embedded in P2SH scripts if desired, however, it is recommended to avoid them as user confusion would probably deter usage.


API Changes

Counterparty APIs will accept P2WPKH addresses as input arguments and will continue to support P2PKH and P2SH addresses.

Counterparty APIs will return P2PKH/P2WPKH addresses for all API calls as appropiate, as the encoding of SegWit addresses clearly states the capabilities of the software. P2WSH addresses will be returned in 62 character Bech32 format.


For this CIP, counterwallet will be modified to show the P2WPKH address in smaller text next to the standard P2PKH address.

The P2PKH address will become less prominent and be hidden by default in the future. But that is outside the scope of this CIP implementation.

Sending BTC

When generating a transaction that sends BTC to the recipient, counterparty-lib will generate the transaction outputs based on the format of the destination address.

  • If the recipient address is a Base58 encoded P2PKH (1xxxx) address, then a standard P2PKH output will be generated.
  • If the recipient address is a Base58 encoded P2SH (3xxxx) address, then a standard P2SH output will be generated.
  • If the recipient address is a Bech32 encoded P2WPKH (bc1xxxx) address, then a segwit P2WPKH output will be generated.
  • If the recipient address is a Bech32 encoded P2WSH (bc1xxxxxxx) address, then an error will be generated. A later CIP should change this behaviour.

Change outputs

All change outputs sent back to a counterparty source address will be encoded as a segwit (P2WPKH) output if the source address is a segwit one (P2WPKH).

Bitcoin Core v0.16.3+

We will use the new indexd backend with Bitcoin Core 0.16.3 or better version of bitcoind at this time. The addrindex patch will be deprecated starting from this version and its use will be discouraged.

Transaction Parsing by counterparty-lib

Counterparty server will parse P2WPKH outputs in addition to P2PKH outputs.

Backwards Compatibility

Segwit support won't be a consensus change, however, parsing of SegWit addresses needs to be coordinated between all nodes, so it will have an activation block so all transactions start being parsed at the same time. All parsing servers will need to upgrade before this block to maintain consensus.


Too complex to specify here. See the code

This CIP has been modified because implementation details were missing and some facts didn't account for certain particularities that the SegWit implementation entails over Counterparty-lib code. It has been updated and milestones extended to allow a more progressive approach.


Fundraising goal = 850 XCP

Milestone #1 (~20.58% - 175 XCP)

counterparty-lib and indexd support for segwit on develop

Milestone #2 (~20.58% - 175 XCP)

counterwallet support for segwit on develop

Milestone #3 (~41.17% - 350 XCP)

counterparty-lib and counterwallet code merged into the master branch

Milestone #4 (~17.64% - 150 XCP)

Code Released and supported on Mainnet for 1 month after activation

Bounty Address (escrow by J-Dog)



This document is placed in the public domain.