
Ton
- 13 installs
- 4 repo stars
- Updated February 25, 2026
- hairyf/blockchain-master
Develop on TON blockchain - addresses, messages, the TVM, cells, Blueprint contract development, payments, and API access.
About
Covers TON (The Open Network) fundamentals - Actor model, stack-based TVM, and cell serialization - plus contract development with Blueprint, payments, and API access. A developer uses it to build and reason about TON smart contracts.
- Addresses, messages, TVM, and cell-based serialization
- Contract development with Blueprint, payments, and API access
Ton by the numbers
- 13 all-time installs (skills.sh)
- Ranked #289 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Jul 13, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hairyf/blockchain-master --skill tonAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 13 |
|---|---|
| repo stars | ★ 4 |
| Last updated | February 25, 2026 |
| Repository | hairyf/blockchain-master ↗ |
What it does
Develop on TON blockchain - addresses, messages, the TVM, cells, Blueprint contract development, payments, and API access.
Files
Skill is based on TON documentation (ton-org/docs), generated at 2026-02-09.
TON (The Open Network) is a decentralized blockchain with an Actor model (all entities are smart contracts), stack-based TVM, and cell-based serialization. This skill covers foundations, contract development with Blueprint, payments, and API access.
Core References
| Topic | Description | Reference |
|---|---|---|
| Addresses | Internal/external addresses, workchains, account ID | core-addresses |
| Messages | Message types, StateInit, deploy, transactions | core-messages |
| Cells & serialization | Cells, BOC, builders and slices | core-cells-serialization |
| TVM | Stack, data types, gas, instructions, get methods | core-tvm |
| TVM exit codes | Compute/action phase codes, testing | core-tvm-exit-codes |
| Fees & status | Storage/compute/forward fees, account status (nonexist, uninit, active, frozen) | core-fees-status |
| TVM registers | c0–c7, c4/c5 durable, c7 environment | core-tvm-registers |
Features
Development
| Topic | Description | Reference |
|---|---|---|
| Blueprint | create-ton, Sandbox, project structure | features-blueprint |
| Contract development | First contract, storage, messages, get methods, Tolk | features-contract-development |
| Tolk language | Types, message handling, lazy loading, IDE | features-tolk |
| Contract upgrades | setCodePostponed, setData, delayed and hot upgrades | features-upgrades |
| Standard wallets | V4, V5, Highload, comparison, use cases | features-wallets |
| Standard tokens | Jettons, NFTs, transfer, mint, burn, discovery | features-tokens |
| Signing | Ed25519, wallet/gasless/server patterns, TypeScript | features-signing |
Payments & API
| Topic | Description | Reference |
|---|---|---|
| Payments | Toncoin, Jettons, finality, monitoring | features-payments |
| API | Liteservers, TON Center, TonAPI, dTON | features-api |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Security | Integers, replay, accept_message, gas, random, front-running | best-practices-security |
Generation Info
- Source:
sources/ton - Git SHA:
f43a791b78dc627cee4c9537112a4f36ee6f3540 - Generated: 2026-02-09
Security Best Practices (TON Contracts)
Anti-patterns and mitigations for TON smart contracts.
Signed/unsigned integers
Validate before arithmetic to avoid overflow/underflow. Use throw_unless (or equivalent) to ensure sufficient balance or range before subtracting.
External message handling
- Guard before ACCEPT: External messages do not carry value; the contract pays gas. If you call
ACCEPT(orSETGASLIMIT) unconditionally, an attacker can drain the contract by sending many externals. Always validate sender (e.g. signature, seqno, subwallet_id) beforeaccept_message(). - Replay protection: Use a stored seqno (or similar) and require incoming external message to match it, then increment. Without this, the same signed message can be replayed.
Account destruction
Using send mode 128 + 32 destroys the account. Only do this after checks: authorized sender, no pending operations, and intentional flow. Otherwise race conditions can cause fund loss.
Exit codes 0 and 1
Do not throw 0 or 1 from contract code; they indicate successful compute/action. Use other codes (e.g. 256–65535) for errors so failures are distinguishable.
Gas
Out-of-gas (exit code 13 / -14) cannot be caught. Pre-calculate gas where possible and require minimum value in messages (e.g. require(context().value > getComputeFee(voteGasUsage, false))). Return excess gas to sender (e.g. Excesses message 0xd53276db) to avoid accumulation.
Random numbers
On-chain “random” is predictable (e.g. logical time). For critical use: avoid sole reliance on-chain; use commit–disclose off-chain, or built-in random with randomized logical time and not in external message receivers.
Front-running and signatures
Pending messages are visible. Include critical parameters (e.g. recipient to) in the signed payload so a copied signature cannot be reused for another recipient. Combine with replay protection (seqno).
Pulling data from other contracts
Contracts cannot call getters of other contracts (cross-shard). All cross-contract communication is asynchronous via messages. To get another contract’s data: send a message, receive a reply with the data.
Address formats and validation
Handle raw, bounceable, and non-bounceable formats; validate workchain when needed (e.g. force_chain(to_address)).
Type and return-value checks
Use consistent load/store types (e.g. don’t store uint and load int). Check return values (e.g. udict_delete? success) and throw on failure.
Code updates
Restrict upgrade entrypoints to an authorized admin and validate new code before calling set_code (or setCodePostponed).
<!-- Source references:
- https://github.com/ton-org/docs (contract-dev/security.mdx)
-->
TON Addresses
TON uses the Actor model: every entity (including wallets) is a smart contract with a unique address for message routing.
Internal addresses
Each deployed contract has an internal address. TL-B:
addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt;
addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9) workchain_id:int32 address:(bits addr_len) = MsgAddressInt.- addr_std: fixed 256-bit address; use whenever possible.
- workchain_id: signed 8- or 32-bit. Active workchains:
- masterchain (
-1): protocol state, validators, block hashes. - basechain (
0): default for most operations. - account_id (the
addressfield): in current workchains,hash(initial_code, initial_data)fromStateInit. Same code+data ⇒ same address; address does not change after deployment.
External addresses
Used by off-chain software; TON software ignores them. TL-B:
addr_none$00 = MsgAddressExt;
addr_extern$01 len:(## 9) external_address:(bits len) = MsgAddressExt.- addr_none: stub when no external info is needed.
- addr_extern: up to 9 bits of extra info (e.g. for external routing).
Key points
- Every actor is a smart contract with a unique internal address.
- Internal address = workchain_id + account_id (256-bit in masterchain/basechain).
- Account ID = hash of contract’s initial code and data (
StateInit). - TON supports up to 2^32 workchains; address length can vary (64–512 bits) in future.
<!-- Source references:
- https://github.com/ton-org/docs (foundations/addresses/overview.mdx)
- foundations/addresses/formats, foundations/status
-->
TON Cells and Serialization
Cells
TVM memory, storage, and code are made of cells. Each cell has:
- Up to 1023 bits of data.
- Up to 4 references to other cells (no cycles; DAG).
Two kinds: ordinary (data + refs) and exotic (pruned, library, merkle, merkle-update; type ID in first byte). Cell level (0–3) is max of children’s levels; affects hashes.
Standard cell representation
Before transfer or storage, cells are serialized to CellRepr: descriptor bytes (refs count, level, exotic flag; data length), then data bytes, then for each ref depth (2 B) + SHA-256 hash (32 B). Graphs are serialized as BOC (bag of cells); see foundations/serialization/boc.
Builders and slices
- Builder: write cursor to construct a new cell (e.g.
beginCell(),store...(),endCell()in@ton/core). - Slice: read cursor over a cell (parse/load data from cells).
TVM cell instructions work with builders and slices; libraries like @ton/core and @ton-community/assets-sdk wrap cell creation and parsing.
Key points
- All persistent and in-memory contract data is a DAG of cells (≤1023 bits + ≤4 refs per cell).
- Serialization: standard cell representation + BOC for graphs.
- Use builders to create cells, slices to read them; same idea in TVM and in TypeScript SDKs.
<!-- Source references:
- https://github.com/ton-org/docs (foundations/serialization/cells.mdx, boc.mdx)
- tvm/builders-and-slices
-->
TON Messages and Transactions
Message structure
message$_ {X:Type}
info:CommonMsgInfo
init:(Maybe (Either StateInit ^StateInit))
body:(Either X ^X)
= Message X;- info: message type and routing (internal, external-in, external-out).
- init: optional StateInit to deploy or unfreeze a contract (see foundations/messages/deploy).
- body: payload for the receiver (in-place or in ref).
Message types:
- Internal: contract → contract; always creates a transaction.
- External incoming: off-chain → contract; transaction only if contract accepts.
- External outbound: contract → off-chain (e.g. logs); no transaction.
StateInit (deploy)
Sent with a message to deploy a contract or unfreeze it. TL-B:
_ fixed_prefix_length:(Maybe (## 5)) special:(Maybe TickTock)
code:(Maybe ^Cell) data:(Maybe ^Cell) library:(Maybe ^Cell)
= StateInit;- code, data, library: initial contract code and data.
- fixed_prefix_length: allows deploying to a different shard by letting the first N bits of the destination differ from
hash(StateInit); rest must match. Max 8 (config param 43).
Address from StateInit: account_id = hash(initial_code, initial_data) (same for current TVM).
Transactions
A transaction records state changes of one account. Contract state only changes via a transaction.
- Triggered by: processing an internal or accepted external message, or by tick-tock/split-prepare/split-install/storage-tx.
- Each transaction has
lt(logical time),now(Unix time),state_update(Merkle update),in_msg,out_msgs,total_fees. - Transactions form an AccountChain; order is strict (
prev_trans_hash). Finality when referenced in a masterchain block (~5 s).
Key points
- Messages carry optional
init(StateInit) andbody; type is ininfo. - Deploy = send message with StateInit; address derived from hash of code+data; use
fixed_prefix_lengthfor shard placement. - Transactions are immutable records; one per account state change; finality after masterchain confirmation.
<!-- Source references:
- https://github.com/ton-org/docs (foundations/messages/overview.mdx, deploy.mdx)
- foundations/messages/internal, external-in, external-out, ordinary-tx
-->
TVM Registers
TVM registers hold control flow, durable state, and environment. Only c4 and c5 persist after a successful run; the rest are transient.
Summary
| Register | Purpose | Persistent |
|---|---|---|
| c0 | Return continuation (normal exit 0) | No |
| c1 | Alternative return (exit 1) | No |
| c2 | Exception handler | No |
| c3 | Function selector (current code / method dispatch) | No |
| c4 | Account storage (contract data) | Yes |
| c5 | Outbound actions (messages, set_code, reserve, library) | Yes (action phase consumes it) |
| c7 | Environment tuple (block time, balance, config, etc.) | No |
c4 — persistent storage
Root cell of account data. Read with GETDATA; write with SETDATA. When the transaction succeeds, the final c4 value becomes the new account state. High-level: Tolk/FunC storage maps to c4.
c5 — action list
Accumulator of actions for the action phase. Structure: linked list of OutAction cells. Actions include: action_send_msg, action_set_code, action_reserve_currency, action_change_library. New actions are prepended (previous = first ref of next). Empty cell starts the list.
c7 — environment
Tuple: index 0 = SmartContractInfo (tag 0x076ef1ea), indices 1–255 = globals. Environment slice gives: actions count, messages sent, NOW (unix time), BLOCKLT, LTIME, RANDSEED (sha256(block_rand_seed . account_address)), BALANCE, MYADDR, CONFIGROOT, MYCODE, INCOMINGVALUE, STORAGEFEES, DUEPAYMENT, INMSGPARAMS (bounce, src_addr, value, etc.). Use GETGLOB/SETGLOB for globals; use TVM instructions (e.g. NOW, BALANCE) for common fields.
c3 — function selector
Holds the current code (root cell). Used by CALLDICT for method-id dispatch. Hot upgrades can replace c3 in the same transaction via setTvmRegisterC3() so a migration runs with new code before setCodePostponed is applied.
Key points
- Durable effects: c4 (new state), c5 (actions). c0–c3, c7 are per-transaction.
- For debugging/emulation: inspect c4 for storage, c5 for outbound messages, c7 for balance/time/sender.
<!-- Source references:
- https://github.com/ton-org/docs (tvm/registers.mdx)
-->
TVM Overview
TVM is a stack-based VM that runs smart contracts on TON. Execution is deterministic; every instruction consumes gas; gas exhaustion aborts the run.
Data model
- No RAM; stack for scratchpad. Parameters in code or on stack.
- Values are immutable. Persistent data is an immutable tree of cells; read/write via slices and builders.
- No function pointers; code lives in continuations (executable slices).
TVM state
- Stack: operands and results.
- Control registers
c0–c5,c7(no c6). - Gas counter: decremented per instruction; zero/negative ⇒ exception.
- Current continuation (`cc`): next instructions to run.
- Codepage (`cp`): instruction set; currently only
SETCP0(codepage 0).
Data types
| Type | Description |
|---|---|
| Integer | 257-bit signed; special NaN for faults |
| Cell | ≤1023 bits + ≤4 refs |
| Slice | Read cursor over a cell |
| Builder | Write cursor to build a cell |
| Tuple | 0–255 elements, any of the seven types |
| Continuation | Executable slice (TVM bitcode) |
| Null | Empty value |
Initialization
On incoming message or get-method call, TVM is initialized from that message (stack, registers). See tvm/initialization.
Instructions
Instructions are stack-based (e.g. pop operands, push results). Full reference: tvm/instructions (opcodes, Fift aliases, categories: stack_basic, cell ops, crypto, etc.). Use get methods for read-only queries; they run TVM without changing state.
Key points
- Stack-based, deterministic, gas-limited; state = stack + registers + gas + continuation.
- Data in cells; manipulate via slices/builders; types include Cell, Slice, Builder, Integer, Tuple, Continuation, Null.
- Get methods are read-only entrypoints; all state changes go through messages and transactions.
<!-- Source references:
- https://github.com/ton-org/docs (tvm/overview.mdx, instructions.mdx, gas.mdx, registers.mdx, get-method.mdx)
- tvm/initialization, tvm/continuations, tvm/exit-codes
-->
TON API and Data Access
Access TON via public liteservers, hosted APIs, or self-hosted nodes.
Options (summary)
| Feature | Public liteservers | TON Center v2 | TON Center v3 | TonAPI | dTON |
|---|---|---|---|---|---|
| Self-hosted | ✅ | ✅ | ✅ | ❌ | ❌ |
| Indexer (DB/queries) | ❌ | ❌ | ✅ | ✅ | ✅ |
| Proofs | ✅ | ❌ | ❌ | ❌ | ❌ |
- Liteservers: raw RPC; cryptographic proofs; config: mainnet global.config.json, testnet testnet-global.config.json. Run your own node/liteserver for full control.
- TON Center v2: HTTP API (toncenter.com); no proofs; can self-host (ton-http-api).
- TON Center v3: indexer + API; archival; no proofs; open-source (ton-indexer).
- TonAPI: REST/Swagger; indexer; not self-hosted; OpenTonAPI is limited open-source.
- dTON: GraphQL (dton.io); indexer; not self-hosted.
Indexer = service keeps derived DB (traces, jettons, NFTs, etc.). Proofs = responses verifiable with network crypto (liteserver/tonlib).
When to use
- Need proofs or full control → liteserver (or run node).
- Need indexed data (history, tokens, traces) → v3, TonAPI, or dTON.
- Simple REST, quick integration → TonAPI or TON Center v2/v3.
Mainnet/testnet endpoints and deploy/source links are in ecosystem/api/overview and per-service docs.
Key points
- Liteservers = RPC + proofs; TON Center v2/v3 = HTTP API; v3/TonAPI/dTON = indexer.
- Self-host: liteserver, v2 (ton-http-api), v3 (ton-indexer). TonAPI/dTON = hosted only.
- Choose by: proofs vs indexed data vs ease of integration.
<!-- Source references:
- https://github.com/ton-org/docs (ecosystem/api/overview.mdx)
- ecosystem/api/toncenter, ecosystem/node
-->
Blueprint Development Toolkit
Blueprint is the standard environment for building, testing, and deploying TON smart contracts.
Components
- Blueprint (ton-org/blueprint): core build and tooling.
- Sandbox (ton-org/sandbox): local in-process blockchain for fast tests.
- Create TON App (ton-org/create-ton): project scaffolding.
- Test utils (ton-org/test-utils): matchers and helpers for tests.
Quick start
npm create ton@latestFollow prompts (project name, contract name, type e.g. tolk-empty). Then:
cd <project>
npm installRequirements: Node.js 22+ (node -v).
Project structure
- contracts/ — source (e.g. Tolk, Tact, FunC) and imports.
- scripts/ — deploy and interaction scripts (Mainnet/Testnet).
- tests/ — TypeScript tests using Sandbox (in-process).
- wrappers/ — TypeScript contract interfaces (except Tact): implement
Contractfrom@ton/core(message encode/decode, getters, compile). Used in tests and clients. - build/ — compile output.
Workflow
1. Build: compile contracts (output in build/). 2. Test: run test suite against Sandbox. 3. Deploy: run deploy script; publish from wallet to Mainnet/Testnet.
IDE support: see contract-dev/ide (VS Code, JetBrains).
Key points
- Use
npm create ton@latestto scaffold; Node 22+ required. - Sandbox = local chain for tests; wrappers = TypeScript API for contracts.
- Build → test (Sandbox) → deploy (scripts + wallet).
<!-- Source references:
- https://github.com/ton-org/docs (contract-dev/blueprint/overview.mdx)
- contract-dev/blueprint/cli, config, deploy, testing
-->
Contract Development on TON
Contract layout
On-chain, a contract has code (TVM instructions) and data (persistent state), stored at one address. Contracts interact only via messages.
Logical layout:
- Storage: persistent state (e.g. counter, owner).
- Messages: handlers for incoming messages (internal/external); each can change state and send out messages.
- Get methods: read-only entrypoints; return data without changing state. Not callable from other contracts; inter-contract use is messages only.
First contract (Blueprint + Tolk)
1. Scaffold: npm create ton@latest -- Example --contractName FirstContract --type tolk-empty. 2. Storage: define a struct (e.g. Storage { counter: Int }) in the contract. 3. Messages: define receivers (e.g. increase, reset) that read body, update storage, optionally send messages. 4. Get method: expose read-only value (e.g. current counter). 5. Build: compile; run tests in Sandbox; deploy via script and wallet.
Contract code lives in contracts/; wrappers in wrappers/; deploy in scripts/. Use IDE plugins for Tolk/FunC (see contract-dev/ide).
Tolk
Tolk is a high-level language for TON contracts (structures, message handlers, get methods). Blueprint supports Tolk via --type tolk-empty. Alternatives: FunC, Tact (different wrapper workflow).
Key points
- Contract = code + data at one address; entrypoints = message handlers + get methods.
- Storage = persistent state; messages = state-changing and cross-contract; get methods = read-only, off-chain or SDK.
- Blueprint + Tolk: define storage, message handlers, get method; build, test in Sandbox, deploy with scripts.
<!-- Source references:
- https://github.com/ton-org/docs (contract-dev/first-smart-contract.mdx, blueprint/overview)
- languages/tolk, contract-dev/testing, deploy
-->
Payment Processing on TON
On-chain vs off-chain
- On-chain: all logic in contracts; good for simple transfers or AMMs.
- Off-chain: your service watches the chain, keeps DB, runs business logic; needed for accounts, history, refunds, external systems. Typical for exchanges and merchants.
Finality
Finality is reached after one masterchain block that references the shard block (~5 s). No multi-block wait like Ethereum or Bitcoin. When monitoring, treat only transactions included in masterchain as final; many APIs expose this.
Assets
- Toncoin: native currency; any wallet can receive; process by watching incoming transfers to your address.
- Jettons (TEP-74): fungible tokens; master contract + per-holder wallet contracts. Process by monitoring the Jetton wallet contract for your deposit address; parse transfer notifications (sender, amount). See standard/tokens/jettons.
Implementation options
1. Self-built: your service + TON API or liteserver; poll blocks, filter by address, parse, verify finality, update DB. Full control, more work. 2. Self-hosted processor: e.g. Bicycle; you run it, configure addresses/assets, consume its API. Balance of control and effort. 3. Third-party: external API/webhooks; fast to integrate, dependency and often fees.
Monitoring flow: fetch blocks → filter transactions for your addresses → parse amount/metadata → confirm masterchain finality → update records. Often poll every few seconds; can combine with indexer webhooks and reconciliation.
Key points
- Use off-chain processing for anything beyond simple transfers (accounts, history, external systems).
- Finality: one masterchain confirmation (~5 s).
- Toncoin = native; Jettons = TEP-74, monitor Jetton wallet contract. Choose self-built, self-hosted processor, or third-party API by control vs effort.
<!-- Source references:
- https://github.com/ton-org/docs (payments/overview.mdx, toncoin.mdx, jettons.mdx)
- standard/tokens/jettons
-->
Contract Upgrades
Contract address is derived from initial code and state. Upgrading allows new code and/or data while keeping the same address (critical for NFTs, vanity addresses, DEXes).
Primitives (Tolk)
- `contract.setCodePostponed(code: cell)`: Schedules code replacement in the action phase. New code is active after the current transaction.
- `contract.setData(data: cell)`: Replaces persistent storage in the compute phase (immediate). New code from setCodePostponed runs only on the next message.
Restrict upgrade messages to an admin (e.g. check in.senderAddress == storage.adminAddress). Ensure enough Toncoin for the full transaction (compute + action); otherwise the whole transaction can revert.
Basic upgrade
Admin sends message with new code and/or data. Contract: verify admin → if code: setCodePostponed(code) → if data: setData(data). Upgrade completes in one transaction; new code applies from the next message.
Delayed upgrade (production)
Request → wait → approve (or reject). Store upgrade request with timestamp; allow ApproveUpgrade only after timestamp + timeout. Gives users time to react if admin is compromised.
Hot upgrade (frequent updates)
When storage changes often (e.g. DEX pool), prepared data in a normal upgrade can be stale when the upgrade runs. Hot upgrade: call setCodePostponed(newCode), then setTvmRegisterC3(...) to switch to new code immediately, then call a migration function (e.g. hotUpgradeData) that reads current storage with the old layout, transforms to the new layout, and calls setData(). Migration runs in the same transaction so it sees up-to-date state. Migration function must have a fixed @method_id and exist in both old and new code (old can no-op). Test migrations on testnet; failure can brick the contract.
When to use
- Basic: Rare upgrades, predictable state.
- Delayed: Production protocols; time for users to exit.
- Hot: High-frequency state updates; storage layout changes without losing in-flight updates.
<!-- Source references:
- https://github.com/ton-org/docs (contract-dev/upgrades.mdx)
-->
Standard TON Wallets
In TON, wallets are smart contracts. They handle signing, replay protection (seqno or query_id), and optionally gasless transfers. Choose by throughput and features.
Comparison
| Feature | V4 | V5 | Highload |
|---|---|---|---|
| Replay protection | Seqno | Seqno | query_id / batch_id |
| Messages per request | Up to 4 | Up to 255 | Up to 2B per timeout |
| Gasless | No | Yes | No |
| Plugins | Yes | Yes | No |
| Subwallet ID | Yes | Yes | Yes |
Multisig: multiple owners, configurable N-of-M; higher cost and coordination. Preprocessed: lowest per-message cost, no plugins.
Use cases
- Retail / dApps: V5 (recommended) or V4 — gasless, plugins, 255 messages per request.
- Payment gateways / exchanges: Highload — high throughput, query_id-based tracking.
- Shared custody: Multisig — N-of-M, audit trail, higher fees.
Key points
- Wallet = smart contract; address = contract address. User signs off-chain; wallet receives external message and sends internal messages.
- Seqno: incrementing nonce per valid submission; common replay protection. Highload uses query_id/batch_id instead.
- Prefer V5 for new apps (gasless, 255 messages). Use Highload only when you need massive throughput and can implement query_id tracking.
<!-- Source references:
- https://github.com/ton-org/docs (standard/wallets/comparison.mdx, standard/wallets/v4.mdx, standard/wallets/v5.mdx, standard/wallets/highload/overview.mdx)
-->