Cardano Improvement Proposals


CIP 21 - Transaction requirements for interoperability with hardware wallets

Contents

Abstract

This CIP describes all the restrictions applicable to Cardano transactions which need to be signed by hardware wallets.

Motivation

Due to certain limitations of hardware (abbrev. HW) wallets, especially very small memory and a limited set of data types supported by Ledger, HW wallets are not able to process all valid transactions which are supported by Cardano nodes.

The limitations also result in an inability of HW wallets to see the whole transaction at once. Transaction data are streamed into HW wallets in small chunks and they compute a rolling hash of the transaction body which is signed at the end. Consequently, a HW wallet only provides witness signatures, and the transaction body which was signed has to be reconstructed by the client. We thus need a common transaction serialization format which will allow no ambiguity. In addition, the format must define ordering of map keys in such a way that it’s possible to check for duplicate keys by HW wallets.

Several of the restrictions also stem from security or UX concerns, e.g. the forbidden combination of pool registration certificates and withdrawals in a single transaction (see reasoning below).

To ensure interoperability, SW wallets and other tools working with HW wallets should only use transactions which conform to the following rules.

Specification

Canonical CBOR serialization format

Transactions must be serialized in line with suggestions from Section 3.9 of CBOR specification RFC. In particular:

See the RFC for details.

Transaction body

Full support for some elements is not implemented yet (especially those related to scripts), but that is likely to change in the near future. The following restrictions are, however, unlikely to ever be lifted.

Unsupported entries

The transaction body entry 6 : update must not be included.

Integers

HW wallets support at most int64 for signed integers and uint64 for unsigned integers i.e. larger integers are not supported overall. Additionally, any integer value must fit in the appropriate type.

Numbers of transaction elements

The number of the following transaction elements individually must not exceed UINT16_MAX, i.e. 65535:

Optional empty lists and maps

Unless mentioned otherwise in this CIP, optional empty lists and maps must not be included as part of the transaction body or its elements.

Outputs

Outputs containing no multi-asset tokens must be serialized as a simple tuple, i.e. [address, coin] instead of [address, [coin, {}]].

Multiassets

Since multiassets (policy_id and asset_name) are represented as maps, both need to be sorted in accordance with the specified canonical CBOR format. Also, an output or the mint field must not contain duplicate policy_ids and a policy must not contain duplicate asset_names.

Certificates

Certificates of type genesis_key_delegation and move_instantaneous_rewards_cert are not supported and must not be included.

If a transaction contains a pool registration certificate, then it must not contain:

It is allowed to arbitrarily combine other supported certificate types, but all the certificates included in a transaction must have the same type of stake credential i.e. either 0 - addr_keyhash or 1 - scripthash. The stake credential type must also be consistent with the type used for withdrawals.

Withdrawals

Since withdrawals are represented as a map of reward accounts, withdrawals also need to be sorted in accordance with the specified canonical CBOR format. A transaction must not contain duplicate withdrawals. All withdrawals included in a transaction must have the same type of stake credential i.e. either 0 - addr_keyhash or 1 - scripthash. The stake credential type must also be consistent with the type used for certificates.

Auxiliary data

HW wallets do not serialize auxiliary data because of their complex structure. They only include the given auxiliary data hash in the transaction body. The only exception is Catalyst voting registration because it requires a signature computed by the HW wallet.

In this exceptional case, auxiliary data must be encoded in their "tuple" format:

[ transaction_metadata: { * transaction_metadatum_label => transaction_metadatum }, auxiliary_scripts: [ * native_script ]]
    

The auxiliary_scripts must be an array of length 0.

Reasoning

Canonical CBOR serialization format

As HW wallets don't return the whole serialized transaction, a common CBOR serialization is needed so that software wallets and other tools interacting with HW wallets are be able to deterministically reproduce the transaction body built and signed by the HW wallet.

The specified canonical CBOR format is consistent with how certain other data are serialized (e.g. Plutus script data in Alonzo) and allows the use of standard CBOR libraries out of the box.

Transaction body

Multiassets

Allowing duplicate policy_ids (or asset_names) might lead to inconsistencies between what is displayed to the user and how nodes and other tools might interpret the duplicate keys, i.e. all policies (or asset names) would be shown to the user, but nodes and other tools might eventually interpret only a single one of them.

Certificates

Combining withdrawals and pool registration certificates isn't allowed because both are signed by staking keys by pool owners. If it was allowed to have both in a transaction then the witness provided by a pool owner might inadvertently serve as a witness for a withdrawal for the owner's account.

Withdrawals

Similarly to multiassets, allowing duplicate withdrawals might lead to inconsistencies between what is displayed to the user and how nodes and other tools might interpret the duplicate keys.

Auxiliary data

The specified auxiliary data format was chosen in order to be compatible with other Cardano tools, which mostly use this serialization format.

Backwards compatibility

Most of the restrictions are already implemented in HW wallets except the canonical CBOR serialization. Tools interacting with HW wallets might need to be updated in order to continue being compatible with HW wallets when the canonical CBOR serialization format is enforced in HW wallets.

This CIP is licensed under CC-BY-4.0