package
4.1.1
Repository: https://github.com/decred/dcrd.git
Documentation: pkg.go.dev

# README

stdaddr

Build Status ISC License Doc

Decred Address Overview

An address is a human-readable representation of a possible destination for a payment. More specifically, it encodes information needed to create a smart contract via a transaction script that imposes constraints required to redeem funds.

Under the hood, an address typically consists of 4 primary components:

  • The network for which the address is valid
  • The data necessary to create a payment script with the appropriate constraints
  • The scripting language version of the aforementioned script
  • A checksum to prevent errors due to improper entry

It is also worth keeping in mind that the scripting language version may be implicit depending on the specific concrete encoding of the address.

Supported Version 0 Addresses

The following table lists the version 0 address types this package supports along with whether the type is supported by the staking system, whether it has a raw public key that can be obtained, whether it has an associated hash160, and some additional notes and recommendations:

Version 0 Address TypeStaking?PubKey?Hash160?Notes / Recommendations
p2pk-ecdsa-secp256k1NYNPrefer p2pkh in on-chain txns [1]
p2pk-ed25519NYNNot recommended [2]
p2pk-schnorr-secp256k1NYNPrefer p2pkh, single party [1,3]
p2pkh-ecdsa-secp256k1YNYPreferred v0 address
p2pkh-ed25519NNYNot recommended [2]
p2pkh-schnorr-secp256k1NNYOnly use with single party [3]
p2shYNY-

Abbreviations:

  • p2pk = Pay-to-public-key
  • p2pkh = Pay-to-public-key-hash
  • p2sh = Pay-to-script-hash

Notes:

  • [1] Pay to public key addresses are only recommended for use in sharing public keys via off-chain protocols such as multi-party signature creation. Pay to public key hash addresses should be used for on-chain transactions to avoid revealing the public key until the funds are redeemed.
  • [2] Version 0 addresses involving Ed25519 are not recommended due to lack of support for safe hierarchical derivation and the requirement for a legacy implementation of the curve that has known issues.
  • [3] Version 0 addresses involving Schnorr signatures are only recommended for use with single parties as extra care must be taken when used with multiple parties to avoid potential theft of funds by malicious counterparties.

Note about Standardness vs Consensus

This package is named stdaddr to clearly convey that addresses are a standardized construction built on top of the underlying scripting system that is enforced by the consensus rules. The specific scripts that the addresses represent are referred to as standard scripts since they are recognized forms that most software considers standard by policy. However, the consensus rules for regular transactions must support so called non-standard scripts as well (any script that is not one of the recognized forms).

This distinction between standardness and consensus is extremely important for developers working on the consensus rules, since consensus must NOT use addresses directly and instead must work with the actual underlying scripts. An address is a human-readable representation of an underlying script along with additional metadata to help prevent misuse and typographical errors. The underlying scripts are enforced by consensus, not the other way around!

Package Usage Primer

The overall design of this package is based on a few key interfaces to provide a generalized capabilities-based approach to working with the various types of addresses along with unique types for each supported address type that implement said interfaces.

Interacting with addresses typically falls into the following categories:

  • Instantiating addresses
    • Decoding existing addresses
    • Creating addresses of the types which correspond to desired encumbrances
  • Generating the payment script and associated version for use in regular transaction outputs
  • Determining additional capabilities of an address by type asserting supported interfaces

Address Versions

All software that works with sending funds to addresses must be able to produce payment scripts that correspond to the same scripting language version the original creator of the address (aka the recipient) supports as they might otherwise not be able to actually redeem the funds.

This requirement creates a one-to-one correspondence between a given address and the underlying scripting language version. Since the original base58-based address format does not encode a scripting language version and are implicitly expected to create version 0 scripts, they are referred to as version 0 addresses.

It is expected that new version addresses will be introduced in the future that change the address format to improve some of the shortcomings of base58 addresses as well as properly encode a scripting language version.

Instantiating Addresses

In order to provide a more ergonomic API depending on the specific needs of callers, this package offers two approaches to instantiating addresses:

  1. Methods that accept and instantiate addresses for any supported version. For example, DecodeAddress and NewAddressPubKeyHashEcdsaSecp256k1.
  2. Methods that accept and instantiate addresses for a specific version. For example, DecodeAddressV0 and NewAddressPubKeyHashEcdsaSecp256k1V0.

The first approach is likely suitable for most callers as it is intended to support all historical address types as well as allow easily specifying a script version from a dynamic variable. For example, applications involving historical data analytics, such as block explorers, should prefer this approach.

However, callers might wish to only support decoding and creating specific address versions in which case the second approach is more suitable. Further, when it comes to creating addresses, since not all adddress types will necessarily be supported by all scripting language versions, the second approach makes it clear from the API exactly which types of addresses are supported for a given version at compile time whereas the first approach requires the caller to check for errors at run time.

Generating Payment Scripts and Displaying a Human-Readable Address String

In order to generalize support for the various standard address types, this package provides an Address interface which is the primary interface implemented by all supported address types.

Use the PaymentScript method to obtain the scripting language version associated with the address along with a script to pay a transaction output to the address and the String method to get the human-readable string encoding of the address.

Address Use in the Staking System

A distinguishing aspect of the staking system in Decred is that it imposes additional constraints on the types of addresses that can be used versus those for regular transactions. This is because scripts in the staking system are tightly controlled by consensus to only permit very specific scripts, unlike regular transactions which allow scripts composed of any sequence of opcodes that evaluate to true.

In order to support this difference, this package provides the StakeAddress interface which is only implemented by the address types that are supported by the staking system. This allows callers to determine if an address can be used in the staking system by type asserting the interface and then making use of the relevant methods provided by the interface to interact with the staking system. Refer to the code examples to see this in action as well as the API documentation of the interface methods for further details.

Converting Public Key to Public Key Hash Addresses

It is often necessary to share public keys in interactive and manual off-chain protocols, such as multi-party signature creation. Since raw public keys are valid for any network, it is generally less error prone and more convenient to use human-readable public key addresses in this case because they ensure the correct network is involved as well as help prevent entry errors.

However, whenever dealing with on-chain transactions, public key hash addresses should typically be used instead to avoid revealing the public key until the funds are redeemed.

With the aim of supporting easy conversion of a public key address to a public key hash address for the cases when the caller already has the former available, this package provides the AddressPubKeyHasher interface which is only implemented by the public key address types. This allows callers to determine if an address can be converted to its public key hash variant by type asserting the interface and then convert it by making use of the AddressPubKeyHash method provided by the interface.

Obtaining Serialized Public Key From Public Key Addresses

When making use of public key addresses, callers often need to obtain the serialized public key associated with the address for further processing.

This package provides the SerializedPubKeyer interface, which is only implemented by the public key address types, for this purpose. Callers may determine if a serialized public key can be obtained from an address by type asserting the interface and then extract it by making use of the SerializedPubKey method provided by the interface.

However, it is also worth noting that merely obtaining the serialized public key via the generic interface is typically not sufficient on its own for a caller to be able to work with it since parsing a public key requires knowing what type of key it is as well. In that case, the caller will likely need to fall back to type asserting the specific concrete implementation to determine which type of public key it is dealing with.

Hash160 Use in Addresses

The term Hash160 is used as shorthand to refer to a hash that is created via a combination of RIPEMD-160 and BLAKE256. Specifically, it is the result of RIPEMD-160(BLAKE256(data)).

For address types that involve Hash160 hashes, such as version 0 public key hash and script hash addresses, it can be convenient for callers to extract the associated hash.

To enable the hash extraction, this package provides the Hash160er interface which is only implemented by the address types that involve Hash160. This allows callers to determine if an address involves a Hash160 by type asserting the interface and then extract it by making use of the Hash160 method provided by the interface.

Installation and Updating

This package is part of the github.com/decred/dcrd/txscript/v4 module. Use the standard go tooling for working with modules to incorporate it.

Examples

  • DecodeAddress

    Demonstrates decoding addresses, generating their payment scripts and associated scripting language versions, determining supported capabilities by checking if interfaces are implemented, obtaining the associated underlying hash160 for addresses that support it, converting public key addresses to their public key hash variant, and generating stake-related scripts for addresses that can be used in the staking system.

License

Package stdaddr is licensed under the copyfree ISC License.

# Functions

DecodeAddress decodes the string encoding of an address and returns the relevant Address if it is a valid encoding for a known address type and is for the provided network.
DecodeAddressV0 decodes the string encoding of an address and returns the relevant Address if it is a valid encoding for a known version 0 address type and is for the network identified by the provided parameters.
Hash160 calculates the hash ripemd160(blake256(b)).
NewAddressPubKeyEcdsaSecp256k1 returns an address that represents a payment destination which imposes an encumbrance that requires a valid ECDSA signature for a specific secp256k1 public key.
NewAddressPubKeyEcdsaSecp256k1Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid ECDSA signature for a specific secp256k1 public key.
NewAddressPubKeyEcdsaSecp256k1V0 returns an address that represents a payment destination which imposes an encumbrance that requires a valid ECDSA signature for a specific secp256k1 public key using version 0 scripts.
NewAddressPubKeyEcdsaSecp256k1V0Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid ECDSA signature for a specific secp256k1 public key using version 0 scripts.
NewAddressPubKeyEd25519 returns an address that represents a payment destination which imposes an encumbrance that requires a valid Ed25519 signature for a specific Ed25519 public key.
NewAddressPubKeyEd25519Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid Ed25519 signature for a specific Ed25519 public key.
NewAddressPubKeyEd25519V0 returns an address that represents a payment destination which imposes an encumbrance that requires a valid Ed25519 signature for a specific Ed25519 public key using version 0 scripts.
NewAddressPubKeyEd25519V0Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid Ed25519 signature for a specific Ed25519 public key using version 0 scripts.
NewAddressPubKeyHashEcdsaSecp256k1 returns an address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key that hashes to the provided public key hash along with a valid ECDSA signature for that public key.
NewAddressPubKeyHashEcdsaSecp256k1V0 returns an address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key that hashes to the provided public key hash along with a valid ECDSA signature for that public key using version 0 scripts.
NewAddressPubKeyHashEd25519 returns an address that represents a payment destination which imposes an encumbrance that requires an Ed25519 public key that hashes to the provided public key hash along with a valid Ed25519 signature for that public key.
NewAddressPubKeyHashEd25519V0 returns an address that represents a payment destination which imposes an encumbrance that requires an Ed25519 public key that hashes to the provided public key hash along with a valid Ed25519 signature for that public key using version 0 scripts.
NewAddressPubKeyHashSchnorrSecp256k1 returns an address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key in the _compressed_ format that hashes to the provided public key hash along with a valid EC-Schnorr-DCR signature for that public key.
NewAddressPubKeyHashSchnorrSecp256k1V0 returns an address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key in the _compressed_ format that hashes to the provided public key hash along with a valid EC-Schnorr-DCRv0 signature for that public key using version 0 scripts.
NewAddressPubKeySchnorrSecp256k1 returns an address that represents a payment destination which imposes an encumbrance that requires a valid EC-Schnorr-DCR signature for a specific secp256k1 public key.
NewAddressPubKeySchnorrSecp256k1Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid EC-Schnorr-DCR signature for a specific secp256k1 public key.
NewAddressPubKeySchnorrSecp256k1V0 returns an address that represents a payment destination which imposes an encumbrance that requires a valid EC-Schnorr-DCRv0 signature for a specific secp256k1 public key using version 0 scripts.
NewAddressPubKeySchnorrSecp256k1V0Raw returns an address that represents a payment destination which imposes an encumbrance that requires a valid EC-Schnorr-DCRv0 signature for a specific secp256k1 public key using version 0 scripts.
NewAddressScriptHash returns an address that represents a payment destination which imposes an encumbrance that requires a script that hashes to the same value as the provided script along with all of the encumbrances that script itself imposes.
NewAddressScriptHashFromHash returns an address that represents a payment destination which imposes an encumbrance that requires a script that hashes to the provided script hash along with all of the encumbrances that script itself imposes.
NewAddressScriptHashV0 returns an address that represents a payment destination which imposes an encumbrance that requires a script that hashes to the same value as the provided script along with all of the encumbrances that script itself imposes using version 0 scripts.
NewAddressScriptHashV0FromHash returns an address that represents a payment destination which imposes an encumbrance that requires a script that hashes to the provided script hash along with all of the encumbrances that script itself imposes using version 0 scripts.

# Constants

ErrBadAddressChecksum indicates an address failed to decode due to an invalid checksum.
ErrInvalidHashLen indicates that either a public key hash or a script hash is not an allowed length.
ErrInvalidPubKey indicates that a serialized public key failed to parse.
ErrInvalidPubKeyFormat indicates that a serialized public key parsed successfully, but is not one of the allowed formats.
ErrMalformedAddress indicates an address failed to decode.
ErrMalformedAddressData indicates an address successfully decoded and is a recognized type, but the encoded data is not the expected length.
ErrUnsupportedAddress indicates that an address successfully decoded, but is not a supported/recognized type.
ErrUnsupportedScriptVersion indicates that an address type does not support a given script version.

# Structs

AddressPubKeyEcdsaSecp256k1V0 specifies an address that represents a payment destination which imposes an encumbrance that requires a valid ECDSA signature for a specific secp256k1 public key.
AddressPubKeyEd25519V0 specifies an address that represents a payment destination which imposes an encumbrance that requires a valid Ed25519 signature for a specific Ed25519 public key.
AddressPubKeyHashEcdsaSecp256k1V0 specifies an address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key that hashes to the given public key hash along with a valid ECDSA signature for that public key.
AddressPubKeyHashEd25519V0 specifies an address that represents a payment destination which imposes an encumbrance that requires an Ed25519 public key that hashes to the given public key hash along with a valid Ed25519 signature for that public key.
AddressPubKeyHashSchnorrSecp256k1V0 specifies address that represents a payment destination which imposes an encumbrance that requires a secp256k1 public key in the _compressed_ format that hashes to the given public key hash along with a valid EC-Schnorr-DCRv0 signature for that public key.
AddressPubKeySchnorrSecp256k1V0 specifies an address that represents a payment destination which imposes an encumbrance that requires a valid EC-Schnorr-DCRv0 signature for a specific secp256k1 public key.
AddressScriptHashV0 specifies an address that represents a payment destination which imposes an encumbrance that requires a script that hashes to the provided script hash along with all of the encumbrances that script itself imposes.
Error identifies an address-related error.

# Interfaces

Address represents any type of destination a transaction output may spend to.
AddressParams defines an interface that is used to provide the parameters required when encoding and decoding addresses.
AddressParamsV0 defines an interface that is used to provide the parameters required when encoding and decoding addresses for version 0 scripts.
AddressPubKeyHasher is an interface for public key addresses that can be converted to an address that imposes an encumbrance that requires the public key that hashes to a given public key hash along with a valid signature for that public key.
Ed25519PublicKey is an interface type that represents an Ed25519 public key for use in creating pay-to-pubkey addresses that involve them.
Hash160er is an interface that allows the RIPEMD-160 hash to be obtained from addresses that involve them.
Secp256k1PublicKey is an interface that represents a secp256k1 public key for use in creating pay-to-pubkey addresses that involve them.
SerializedPubKeyer is an interface for public key addresses that allows the serialized public key to be obtained from addresses that involve them.
StakeAddress is an interface for generating the specialized scripts that are used in the staking system.

# Type aliases

ErrorKind identifies a kind of error.