Basics of addresses and types of addresses

Ref: CIP19

In Cardano, an address is a sequence of bytes that conforms to a particular format, which is describe below.

However, users will typically come into contact with addresses only after these addresses have been encoded into sequences of human-readable characters. The basic need for a binary-to-text encoding comes from a need to communicate arbitrary binary data over preexisting communications protocols that were designed to carry only English language human-readable text. In Cardano, the Bech32 and Base58 encodings are used to encode addresses, as opposed to standard hexadecimal notation (Base16, example 0x8A7B). These encoded sequence of characters have to be distinguished from the byte sequences that they encode, but lay users will (and should) perceive the encoded form as "the" address.

Why base-58 instead of standard base-64 encoding?
// - Don't want 0OIl characters that look the same in some fonts and

In Cardano there are two "era" of addresses. The Byron address (which did not have staking) with Base58 encoding. The Shelly address (which has staking) with Bech32 encoding with the exception that Cardano does not impose a length limit on the sequence of characters. The human-readable prefixes are defined in CIP-0005; the most common prefix is addr, representing an address on mainnet.

So why Bech32?

  • Base58 needs a lot of space in QR codes, as it cannot use the alphanumeric mode.

  • The mixed case in base58 makes it inconvenient to reliably write down, type on mobile keyboards, or read out loud.

  • The double SHA256 checksum is slow and has no error-detection guarantees.

  • Most of the research on error-detecting codes only applies to character-set sizes that are a prime power, which 58 is not.

  • Base58 decoding is complicated and relatively slow.

In principle, it is possible for a Shelley address to be encoded in Base58 and a Byron address to be encoded in Bech32 (without length limit). However, implementations are encouraged to reject addresses that were encoded against convention, as this helps with the goal that lay users only encounter a single, canonical version of every address.

Examples of different addresses encoded in different eras:

Address Type
Encoding
Example

Byron

Base58

37btjrVyb4KDXBNC4haBVPCrro8AQPHwvCMp3RFhhSVWwfFmZ6wwzSK6JK1hY6wHNmtrpTf1kdbva8TCneM2YsiXT7mrzT21EacHnPpz5YyUdj64na

Shelley

bech32

addr1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5eg0yu80w

stake

bech32

stake1vpu5vlrf4xkxv2qpwngf6cjhtw542ayty80v8dyr49rf5egfu2p0u

In Cardano, the sequence of bytes (after decoding with Bech32 or Base58) that represents an address comprises two parts, a one-byte header and a payload of several bytes. Depending on the header, the interpretation and length of the payload varies.

In the header-byte, bits [7;4] indicate the type of addresses being used; we'll call these four bits the header type. The remaining four bits [3;0] are either unused or refer to what we'll call the network tag. There are currently 11 types of addresses in Cardano which we'll divide into three categories: Shelley addresses, stake addresses, and Byron addresses.

  1 byte     variable length   
     <------> <-------------------> 
    ┌────────┬─────────────────────┐
    │ header │        payload      │
    └────────┴─────────────────────┘
        🔎                          
        ╎          7 6 5 4 3 2 1 0  
        ╎         ┌─┬─┬─┬─┬─┬─┬─┬─┐ 
        ╰╌╌╌╌╌╌╌╌ │t│t│t│t│n│n│n│n│ 
                  └─┴─┴─┴─┴─┴─┴─┴─┘ 
    

Network Tag

Except for Byron addresses (type 8 = 1000), the second half of the header (bits [3;0]) refers to the network tag which can have the following values and semantics. Other values of the network tag are currently reserved for future network types. In the case of Byron addresses, bits [3;0] have a completely separate definition detailed in the section below.

Network Tag (. . . . n n n n)

Semantic

....0000

Testnet(s)

....0001

Mainnet

Shelley Addresses

There are currently 8 types of Shelley addresses summarized in the table below:

Header type (t t t t . . . .)

Payment Part

Delegation Part

(0) 0000....

PaymentKeyHash

StakeKeyHash

(1) 0001....

ScriptHash

StakeKeyHash

(2) 0010....

PaymentKeyHash

ScriptHash

(3) 0011....

ScriptHash

ScriptHash

(4) 0100....

PaymentKeyHash

Pointer

(5) 0101....

ScriptHash

Pointer

(6) 0110....

PaymentKeyHash

ø

(7) 0111....

ScriptHash

ø

The following figure shows how addresses are formed in Shelly address

Payment part

Fundamentally, the first part of a Shelley address indicates the ownership of the funds associated with the address. We call it the payment part. Whoever owns the payment parts owns any funds at the address. As a matter of fact, in order to spend from an address, one must provide a witness attesting that the address can be spent. In the case of a PubKeyHash, it means providing a signature of the transaction body made with the signing key corresponding to the hashed public key (as well as the public key itself for verification). For monetary scripts, it means being able to provide the source script and meet the necessary conditions to validate the script.

Delegation part

The second part of a Shelley address indicates the owner of the stake rights associated with the address. We call it the delegation part. Whoever owns the delegation parts owns the stake rights of any funds associated with the address. In most scenarios, the payment part and the delegation part are owned by the same party. Yet it is possible to construct addresses where both parts are owned and managed by separate entities. We call such addresses mangled addresses or hybrid addresses.

Some addresses (types 6 and 7) carry no delegation part whatsoever. Their associated stake can't be delegated. They can be used by parties who want to prove that they are not delegating funds which is typically the case for custodial businesses managing funds on the behalf of other stakeholders. Delegation parts can also be defined in terms of on-chain pointers.

Pointers

In an address, a chain pointer refers to a point of the chain containing a stake key registration certificate. A point is identified by 3 coordinates:

  • An absolute slot number

  • A transaction index (within that slot)

  • A (delegation) certificate index (within that transaction)

These coordinates form a concise way of referring to a stake key (typically half the size of a stake key hash). They are serialized as three variable-length positive numbers following the ABNF grammar here below:

POINTER = VARIABLE-LENGTH-UINT ; slot number
            | VARIABLE-LENGTH-UINT ; transaction index
            | VARIABLE-LENGTH-UINT ; certificate index
    
    VARIABLE-LENGTH-UINT = (%b1 | UINT7 | VARIABLE-LENGTH-UINT) 
                         / (%b0 | UINT7)
    
    UINT7 = 7BIT 
    

Stake Addresses

Like Shelley addresses, stake addresses (also known as reward addresses) start with a single header byte identifying their type and the network, followed by 28 bytes of payload identifying either a stake key hash or a script hash.

Header type (t t t t . . . .)

Stake Reference

(14) 1110....

StakeKeyHash

(15) 1111....

ScriptHash

  • StakeKeyHash refers to blake2b-224 hash digests of Ed25519 verification keys. How keys are obtained is out of the scope of this specification. Interested readers may look at CIP-1852 for more details.

  • ScriptHash refers to blake2b-224 hash digests of serialized monetary scripts. How scripts are constructed and serialized is out of the scope of this specification.

Mangled Address

While developing applications, we should be careful of mangled address. In a mangled address the payment part and the stake part are not owned by the same entity. This can be beneficial and also most times painful. The benefit is that two or more entities can use same delegation keys to delegate to a stake pool. However many Dapps relay on stake address to identify an entity. If users mangle the address then we just cannot rely on the stake address. Wallets usually provide users with information of "controlled stake". In this case the controlled stake is the stake that is controlled by current payment addresses (with same payment key).

Some popular Plutus scripts only checked the payment part of addresses. This resulted in situations such as: a malicious user purchases an NFT listed by Alice on a smart contract market but sends the payment to a mangled address for which Alice controls the payment part, but which specifies the buyer’s staking key in the delegation part, which allows the malicious buyer to keep staking control of the funds used in the payment. The smart contract authorises the purchase because it only checks the payment part of the address receiving the payment matches that of the seller.

More details here https://adamantsecurity.medium.com/multi-sig-concerns-mangled-addresses-and-the-dangers-of-using-stake-keys-in-your-cardano-project-94894319b1d8

Last updated