Skip to content

Address Types

Addresses are commonly used identifiers that act as a shorthand for who can spend a given output. Since Nexa transactions do not inherently have a concept of accounts with balances, it is not always easy (or even possible) to determine which unspent outputs are spendable by a given person. However, the standard scripts were designed to provide a straightforward structure that can be used to identify transactions that spendable in similar ways. In most cases, the address contains all of the information necessary to create a transaction output that is spendable by the owner of the address. Due to this and their compactness, addresses are the most common way to specify to others how ("where") they can receive funds.

Raw addresses are rarely used outside of scripts, though, as they lack context and redundancy. Instead, addresses are typically encoded using the CashAddr format to ensure they are received and interpreted correctly.

Base58 encoding of addresses is not recommended. It is not necessary to for services to accept Base58 encoded addresses. However, if used, the prefix should be the 1 byte value "8".

The contents of all addresses regardless of encoding should be as specified below.

Address Contents

The contents of an address is a serialized output script. To be precise, first create a byte array of the full script. Then serialize that byte array in the standard bitcoin serialization manner (effectively prepending the script with its length as a compact int). All such scripts are assumed to be script templates. If the script defines a group (tokens) but not a token quantity, use OP_0 as the quantity. This will render the output script illegal until the sender modifies the script with their desired token quantity. Addresses MAY also specify a desired quantity by including the field... which, of course, may be overridden by the sender or not as the sender chooses.

The following sections apply the above description to clarify the address contents for common use cases (but do not add any additional info).

Note that since script template formatted output scripts are easily distinguishable from most other output scripts, this restriction may be selectively eased for other script types.

See dstencode_tests.cpp for test vectors.

Pay to Public Key Hash (P2PKH) Addresses

P2PKH addresses encode the hash of the public key that is locking the output (i.e. RIPEMD-160(SHA-256(publicKey))). Mainnet P2PKH addresses always start with q in CashAddr encoding:

CashAddr:     nexa:qrzutqxrmk0t72yacjuka372svkdpqkmly0wwnym8x

The following diagram show the full creation process for a P2PKH address:

graph LR
PrivK["Private Key"] ==> PubK[Public key]
PubK == SHA256 and RIPEMD160 ==> PubKH[Public Key Hash]
PubKH ==> Address
Address ==> PubKH
style PubK fill:#F06,stroke:#333,stroke-width:2px;
style PrivK fill:#B06,stroke:#333,stroke-width:8px;
style PubKH fill:#0F6,stroke:#333,stroke-width:2px;
style Address fill:#0F6,stroke:#333,stroke-width:2px;

Pay to Script Template (P2ST) Addresses

The most common and recommended address format to use is Pay to Script Template. Pay to Script Template addresses have multiple advantages over the other address forms and are needed to interact with Nexa's native token system. For more information please read about Pay to Script Template addresses here.

Multisig Addresses

Multisig addresses are supported in the Pay to Multisig Template (P2MT) form which is a subset of Pay To Script Template. These have not yet been implemented in any wallets.

Pay to Script Hash (P2SH) Addresses

Nexa does not support P2SH