Skip to main content

Zano Hard Fork 6 (v2.1 -> v2.2) services migration guide

This document is intended for services / exchanges and describes how to prepare for the upcoming HF6. The current API will keep working without any changes for another 2 months, est. until August 26 2026. You have approximately 2 months to implement the required changes.

TL;DR

If you use any of these deprecated API methods, switch to the replacement before HF6 — the old ones will start failing on transactions that carry an intrinsic (per-output) payment ID:

Table 1. TL;DR summary
If you use……switch toWhy
get_recent_txs_and_infoget_recent_txs_and_info3new method returns subtransfers_by_pid and handles intrinsic PIDs
get_recent_txs_and_info2get_recent_txs_and_info3same
search_for_transactionssearch_for_transactions2same

Also: read the per-transaction payment data from the new subtransfers_by_pid field, and expect a single tx to carry multiple payments (different PIDs and assets). See API changes for details.

Key features in HF6

Hard Fork 6 will bring to life two major features among others:

1) gateway addresses;

2) intrinsic payment IDs. (per-output payment id)

Gateway addresses are described in a separate guide. Here we focus on payment IDs.

What is Intrinsic Payment ID and what happens to existing Payment ID?

Payment ID (a.k.a. PID) is arbitrary data that can be attached to a transaction and it is mainly intended to help the receiver distinguish between different payments (e.g. an exchange receiving deposits on the same hot wallet address from different users). This data is encrypted in such a way that only the sender and the receiver can decode it. Before HF6, the PID is stored in the transaction's extra/attachment section and thus it's tx-wide by nature — you can put only one PID into a transaction regardless of the number of outputs. A PID can be packed together with a normal Zano address into an integrated address. When someone sends funds to an integrated address, the sender's wallet extracts PID from the address and then makes a standard transaction to the stripped address with PID included into tx's extra.

Since HF6 we introduce so-called intrinsic payment ID — 8 bytes of arbitrary data that is put into each transaction's output. This data is encrypted similarly to outputs' amounts, and it is always present even if no payment ID is actually used for a particular output, making a transaction more uniform. Old tx-wide payment IDs will still be usable even after HF6, although with some limitations.

Table 2. Difference between tx-wide payment IDs and intrinsic payment IDs
AspectLegacy tx-wide Payment IDIntrinsic Payment ID
Maximum length128 bytes8 bytes
Count per tx0 or 1Equal to the number of outputs
EncryptionOnly one (primary) receiver can decrypt the payment IDEach receiver decrypts their own payment ID alongside the output data
Conceptual modelOne tx corresponds to zero or one payment, identified by a single payment IDOne tx can correspond to zero, one, or multiple payments, each with its own payment ID
Supported before HF6?YesNo
Supported after HF6?Yes (with limitations)Yes
Can be used in a tx with gateway outputs?NoYes

The most important change to note: a single transaction may contain multiple payments with different payment ID and different asset. From user's perspective it looks like sending a tx to multiple integrated addresses — which is not allowed before HF6 (multiple destinations are allowed, but an integrated address must be the first and only one) — but becomes possible after HF6 activation.

Legacy tx-wide PIDs and intrinsic per-output PIDs shouldn't be used together: such a transaction cannot be created by the wallet, and if one is encountered anyway, the wallet prioritizes the legacy tx-wide PID and ignores any intrinsic PIDs.

API changes (important!)

Data structure

Newer API methods (get_recent_txs_and_info3 and search_for_transactions2) return a subtransfers_by_pid list, which has the same structure across different methods and looks as follows:

"subtransfers_by_pid": [{
"payment_id": "",
"subtransfers": [{
"amount": 6,
"asset_id": "45eab91922c86ae056a849b39a439112cc2d4819262c24acd4bb4bb0b6c56696",
"is_income": true
}]
},{
"payment_id": "ec2d180100000000",
"subtransfers": [{
"amount": 600000000000,
"asset_id": "45eab91922c86ae056a849b39a439112cc2d4819262c24acd4bb4bb0b6c56696",
"is_income": true
},
{
"amount": 137,
"asset_id": "cc608f59f8080e2fbfe3c8c80eb6e6a953d47cf2d6aebd345bada3a1cab99852",
"is_income": true
}]
}]

Note that subtransfers_by_pid may contain multiple elements with different payment_id values, each containing multiple subtransfers (e.g. native coins and an asset).

Deprecated methods (get_recent_txs_and_info, get_recent_txs_and_info2, search_for_transactions) return different fields that resemble a single element of the subtransfers_by_pid list above. You shouldn't use them anymore.

When a PID is not specified, an empty string is used as the value of payment_id (see the first element in the example above).

API methods

Table 3. API methods change summary
API methodBefore HF6After HF6data fields
get_recent_txs_and_info (deprecated)worksfails on txs with intrinsic PIDsubtransfers, payment_id
get_recent_txs_and_info2 (deprecated)worksfails on txs with intrinsic PIDsubtransfers, payment_id
get_recent_txs_and_info3worksworkssubtransfers_by_pid
search_for_transactions (deprecated)worksfails on txs with intrinsic PIDsubtransfers, payment_id
search_for_transactions2worksworkssubtransfers_by_pid
make_integrated_addressup to 8-byte PID by defaultup to 8-byte PID by defaultlegacy sizes (up to 128 bytes) require --allow-legacy-payment-id-size

HF6-ready checklist

1) Zano daemon and wallet binaries (zanod and simplewallet) are updated to v2.2.1.501 or more recent;

2) API: get_recent_txs_and_info3 and search_for_transactions2 are used instead of deprecated get_recent_txs_and_info, get_recent_txs_and_info2, search_for_transactions;

3) 8-byte-long PIDs are used when generating a deposit integrated address for a user;

4) it is expected that a single incoming tx may correspond to multiple payments/deposits with different PIDs and different assets.