Python 3 and a terminal. No wallet, no Toncoin, no internet connection.
macOS and Linux ship with Python; on Windows install it from python.org with
“Add python.exe to PATH” ticked. Check with
python3 --version. Everything below uses only modules that come with
Python.
You are going to take a TON address apart. That string beginning
EQ is not a random identifier — it is four fields with a checksum, and
once you have decoded one by hand you can tell a corrupted address from a good one, and a
mainnet address from a testnet one, without trusting any tool to do it for you.
What is TON?
TON (The Open Network) is a decentralized layer-1 blockchain designed for speed, scalability, and mass adoption. Originally conceived by Telegram founders Nikolai and Pavel Durov in 2018, TON was built to handle millions of transactions per second while remaining accessible to everyday users through Telegram's 900+ million user base.
Unlike most blockchains that process transactions on a single chain, TON uses a multi-blockchain architecture with dynamic sharding. This means the network can split into smaller chains as demand grows, then merge them back when demand drops — automatically and without downtime.
The History: From Telegram to Community
The story of TON is one of the most dramatic in crypto history:
- 2018: Telegram raises $1.7 billion in a private token sale for the "Telegram Open Network" — at the time, the largest ICO ever
- 2019: The SEC files an emergency action against Telegram, arguing the token sale was an unregistered securities offering
- 2020: Telegram settles with the SEC for $18.5 million, returns $1.2 billion to investors, and officially abandons the project
- 2020-2021: Independent developers fork the open-source codebase and continue development as "The Open Network" (TON)
- 2021: The TON Foundation forms as a non-profit to steward the ecosystem
- 2023-2024: Telegram re-embraces TON, integrating Toncoin payments, TON-based wallets, and Mini Apps directly into the messaging platform
- 2024: Pavel Durov is arrested in France; the community continues development independently, proving the network's decentralization
TON survived its founder's company abandoning it AND the arrest of its original visionary. The fact that development continued in both cases demonstrates genuine decentralization — no single entity controls the network.
Toncoin: The Native Token
Toncoin (TON) is the native cryptocurrency of The Open Network. It serves multiple purposes:
- Transaction fees: Every operation on TON requires a small amount of Toncoin as gas
- Staking: Validators stake Toncoin to secure the network and earn rewards
- Governance: Token holders can participate in network governance decisions
- Payments: Used for peer-to-peer payments within Telegram and the broader ecosystem
- Smart contract execution: Powers all dApps, DeFi protocols, and services on the network
Key Features of TON
TON by the Numbers
- Theoretical throughput: Millions of TPS (with full sharding activated)
- Block time: ~2-5 seconds
- Transaction cost: Typically $0.01-0.05 per transaction
- Validators: 300+ globally distributed validators
- Consensus: Byzantine Fault Tolerant Proof-of-Stake (BFT PoS)
Why TON Matters for Security
From a cybersecurity perspective, TON introduces both opportunities and risks:
- Telegram integration means mass exposure: Millions of non-technical users now interact with crypto through Telegram, making them targets for phishing and scams
- Mini Apps expand the attack surface: Third-party Mini Apps in Telegram can request wallet permissions, creating new phishing vectors
- Asynchronous contracts require new security thinking: TON's message-passing model means smart contract vulnerabilities differ from Ethereum's
- Speed makes fraud harder to reverse: Sub-second finality means fraudulent transactions cannot be front-run or reversed
Because TON is embedded in Telegram, many users treat it as casually as sending a message. But every TON transaction is irreversible. There is no "unsend" for cryptocurrency.
Now Take a TON Address Apart, in Five Steps
Everything above is what TON is. This is where you touch it. In the next twenty minutes you will build a TON address from scratch, read out every field hidden inside one, mistype it and watch the built-in checksum refuse it, measure how reliable that protection is, and convert between the two forms you will meet in wallets and block explorers. Every line of output below came from running these files.
Go: open a terminal in a folder you can write to, e.g.
cd ~/Desktop (Windows: cd %USERPROFILE%\Desktop).
Do: save this as tonaddr.py. It prints nothing by itself;
it is the toolbox for every step that follows. A TON address is 36 bytes — one flags
byte, one workchain byte, the 32-byte account identifier, and a two-byte checksum —
written out in base64.
import base64, hashlib
def crc16(data: bytes) -> int:
"""CRC-16/XMODEM, the checksum TON uses in a user-friendly address."""
crc = 0
for byte in data:
crc ^= byte << 8
for _ in range(8):
crc = ((crc << 1) ^ 0x1021) & 0xFFFF if crc & 0x8000 else (crc << 1) & 0xFFFF
return crc
def encode(account_hash: bytes, workchain: int = 0, bounceable: bool = True) -> str:
flags = 0x11 if bounceable else 0x51
body = bytes([flags, workchain & 0xFF]) + account_hash
return base64.urlsafe_b64encode(body + crc16(body).to_bytes(2, "big")).decode()
def decode(address: str):
raw = base64.urlsafe_b64decode(address)
body, given = raw[:34], int.from_bytes(raw[34:], "big")
return {
"flags": hex(body[0]),
"bounceable": body[0] == 0x11,
"workchain": body[1] - 256 if body[1] > 127 else body[1],
"account": body[2:].hex(),
"checksum_ok": crc16(body) == given,
}
You should see: nothing. python3 tonaddr.py should return
to the prompt in silence, which means the file parses.
If not: SyntaxError around the crc16 loop
usually means the shift operators arrived mangled — the line uses two less-than signs
and two greater-than signs, not one. IndentationError means the function bodies
lost their four-space indent.
Go: same folder.
Do: save this as make.py and run
python3 make.py.
import hashlib
from tonaddr import encode
account = hashlib.sha256(b"finkatana practice account").digest()
print("account id (32 bytes):", account.hex())
print("bounceable address :", encode(account))
print("non-bounceable :", encode(account, bounceable=False))
You should see: two addresses that differ only in their first character:
account id (32 bytes): 39f259113ae4de6b5cba43c7013e5b880bc590a97fe413a6ca7ad88de266b10a
bounceable address : EQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCkOX
non-bounceable : UQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCh5S
Here is the check that matters: every TON address you have ever seen begins
EQ or UQ, and yours do too. That is not a coincidence
arranged by this page — it falls out of the flags byte. 0x11 plus a zero
workchain byte encodes to the letters EQ in base64; 0x51 encodes to
UQ. You have just derived a piece of TON trivia from first principles rather
than being told it.
If not: if your addresses do not start EQ and
UQ, the flags values in encode are wrong — they are
0x11 and 0x51. Different account bytes than shown mean the quoted
phrase differs; it must match character for character.
Go: same folder. This is what a wallet does silently the moment you paste a destination.
Do: save this as read.py and run it.
from tonaddr import decode
addr = "EQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCkOX"
print("length:", len(addr), "characters")
for key, value in decode(addr).items():
print(f" {key:12s}: {value}")
You should see: the whole address explained:
length: 48 characters
flags : 0x11
bounceable : True
workchain : 0
account : 39f259113ae4de6b5cba43c7013e5b880bc590a97fe413a6ca7ad88de266b10a
checksum_ok : True
Three of those fields are worth knowing by name.
Bounceable decides what happens when the destination is a contract that
cannot accept the transfer: a bounceable send comes back to you, a non-bounceable one does
not — which is why wallets use the UQ form for ordinary payments to
people. Workchain 0 is the ordinary chain where wallets live, and
-1 is the masterchain. Account is the real identity; everything
else is packaging.
If not: binascii.Error: Invalid base64-encoded string means
a character was dropped — the address is exactly 48 characters.
checksum_ok: False means it was mistyped, which is precisely what the next step
is about.
Go: same folder. Sending to a wrong-but-valid address is irreversible, so this is the protection that matters most in daily use.
Do: save this as typo.py and run it.
from tonaddr import decode
good = "EQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCkOX"
typo = good[:20] + ("X" if good[20] != "X" else "Y") + good[21:]
print("as published :", good)
print("as retyped :", typo)
print()
print("published address, checksum ok:", decode(good)["checksum_ok"])
print("retyped address, checksum ok:", decode(typo)["checksum_ok"])
You should see: one character changed, and the address refused:
as published : EQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCkOX
as retyped : EQA58lkROuTea1y6Q8cBXluIC8WQqX_kE6bKetiN4maxCkOX
published address, checksum ok: True
retyped address, checksum ok: False
Your wallet runs exactly this check before it will let you send. That is why a TON wallet says “invalid address” rather than cheerfully sending your coins into a void.
If not: if both lines say True, the two strings are identical —
print good == typo to confirm the substitution happened.
Go: same folder. One example is an anecdote; ten thousand is a measurement.
Do: save this as howgood.py and run it. It changes one random
character, ten thousand times, and counts how often the corrupted address still passes.
import random
from tonaddr import decode
good = "EQA58lkROuTea1y6Q8cBPluIC8WQqX_kE6bKetiN4maxCkOX"
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
random.seed(3)
missed = 0
for _ in range(10_000):
i = random.randrange(len(good) - 1)
wrong = random.choice([c for c in alphabet if c != good[i]])
candidate = good[:i] + wrong + good[i + 1:]
try:
if decode(candidate)["checksum_ok"]:
missed += 1
except Exception:
pass # not even valid base64 -- also caught
print(f"of 10000 single-character typos, {missed} went undetected")
You should see: a clean sweep:
of 10000 single-character typos, 0 went undetected
Sixteen checksum bits catch every single-character mistake in this test, which is why pasting a TON address is a low-risk operation. Note carefully what it does not protect against: an address that was swapped for a different valid one — by clipboard-hijacking malware, or by a scammer sending you theirs — passes every check, because it is a perfectly good address. It is simply not the one you meant. The checksum defends against your fingers, never against an attacker.
If not: a number greater than zero is possible in principle and does not
mean your code is broken; the checksum is 16 bits, so a wrong address passing is rare rather
than impossible. A large count means decode is not comparing the checksum
— check that line in step 1.
Without scrolling up: you copy a TON address from a friend’s message, your wallet accepts it without complaint, and the coins never arrive. Given what step 5 measured, what is the most likely explanation, and what should you have done differently? Answer: the address was almost certainly not corrupted — a corrupted one would have been rejected. It was a different valid address, most often because clipboard-hijacking malware replaced it at the moment of copying, or because the message itself came from an impersonated account. The defence is to compare the first four and last four characters of what landed in the send box against the source, and to confirm the address through a second channel for anything large — a checksum cannot tell you whose address it is.
Now do it without the page: generate an address on workchain
-1, the masterchain, by calling encode(account, workchain=-1), then
decode it and confirm the workchain field reads -1 and not 255.
Work out from step 1 why the decoder needs that adjustment at all. You have just met the
difference between a byte and a signed number — a distinction that has caused real bugs
in real wallets.
Summary
In this tutorial, you learned:
- TON is a high-speed, multi-blockchain network originally designed by Telegram
- The project survived both Telegram's abandonment and its founder's arrest
- Toncoin powers transactions, staking, governance, and smart contracts
- TON's key innovations include infinite sharding, sub-second finality, and Telegram integration
- The Telegram integration creates unique security considerations for 900M+ users
Next, dive into TON's architecture to understand how the multi-blockchain design actually works.