Explore in Telegram

apiton blog

Reading a TON address: raw vs bounceable vs non-bounceable

· 3 min read · addresses, basics

Open in @apitonBotcheck any username, number or domain live in Telegram

Copy the same wallet from three TON apps and you may get three different-looking strings. They are usually the same account. This article decodes the formats defined in TEP-2 so you can tell them apart at a glance.

One address, four spellings

Here is the TON DNS root contract (the collection that holds every .ton domain) in each form:

Form Value
raw 0:b774d95eb20543f186c06b371ab88ad704f7e256130caf96189368a7d0cb6ccf
bounceable (mainnet) EQC3dNlesgVD8YbAazcauIrXBPfiVhMMr5YYk2in0Mtsz0Bz
non-bounceable (mainnet) UQC3dNlesgVD8YbAazcauIrXBPfiVhMMr5YYk2in0Mtszx22
bounceable (testnet) kQC3dNlesgVD8YbAazcauIrXBPfiVhMMr5YYk2in0Mtsz_v5

All four identify the same account.

The raw form

An account is identified by two numbers:

  • the workchain — 0 for the basechain where almost everything lives, -1 for the masterchain;
  • the account id — a 256-bit hash of the contract's initial code and data.

The raw form writes them as workchain:hex, e.g. 0:b774…6ccf. It is exact and unambiguous, but it has no checksum, so a typo produces another valid-looking address.

The user-friendly form

The friendly form packs 36 bytes and encodes them as 48 characters of URL-safe base64:

Bytes Content
1 flags: 0x11 bounceable, 0x51 non-bounceable, +0x80 for testnet
1 workchain (0x00 for 0, 0xff for -1)
32 account id
2 CRC16-XMODEM checksum of the first 34 bytes

The first byte is why mainnet friendly addresses start with EQ (bounceable, 0x11) or UQ (non-bounceable, 0x51), and testnet ones with kQ or 0Q. The checksum catches typos: a wallet app rejects a friendly address whose CRC does not match. Some tools use the standard base64 alphabet (+ and /) instead of the URL-safe one (- and _); both decode to the same bytes.

What "bounceable" means

The flag is not a property of the account — it is a hint to the sender:

  • Bounceable (EQ…). If the message fails at the destination (for example, the contract throws, or the account is not deployed), the remaining value bounces back to the sender. Use it for smart contracts: jetton masters, NFT items, sale contracts, DNS items.
  • Non-bounceable (UQ…). The value stays at the destination even if nothing runs there. This is the right choice for wallets, including brand-new ones that have not been deployed yet — a bounceable transfer to an undeployed wallet would simply come back.

Most wallet apps now show user wallets as UQ… by default. The apiton API follows the same rule and returns addresses in non-bounceable form (UQ…) unless a field says otherwise; it accepts any of the forms as input, and a name.ton domain on methods that resolve DNS.

Practical rules

  1. Comparing addresses? Convert both to raw (or to the same friendly flag) first. EQ… and UQ… of the same account differ in the first characters and the last ones, because the checksum changes with the flag.
  2. Sending to a person? Use their UQ… wallet address.
  3. Sending to a contract? EQ… is safer: a failed call returns your funds.
  4. Seeing kQ… or 0Q…? That is a testnet address. Mainnet services (including apiton in production) do not accept it.

Checking an address

Paste any form into @apitonBot: it shows the balance, the contract type (wallet version, jetton wallet, NFT item, DNS item…), recent transactions and the NFTs it holds, and you can watch it for new transactions. On apiton.org, usernames, numbers and domains show their owner wallet — for example the +888 0000 1312 page — and the lists of usernames for sale and expired domains are a quick way to see real owner addresses.

Try it in @apitonBotfree: look up, watch and get alerts in Telegram

Explore the catalog

More from the blog

All articles · RSS

Look up another name

Open in @apitonBot