Skip to main content
T TON Adoption
← Glossary
NODE/03 · Term

Smart contract on TON

An on-chain account on TON with code, persistent storage and a TON balance. Communicates via asynchronous messages; gas costs a fraction of a cent per call.

Aliases: ton smart contract, ton contract

A smart contract on TON is a special kind of account: it holds a TON balance like any wallet, but it also carries executable TVM code and a private data cell. When a message lands at its address, the TVM runs the code, optionally mutates storage, and may emit further messages.

Account state

Every contract has three persistent pieces:

  • Code — a cell with TVM bytecode (compiled from FunC, Tact or Tolk).
  • Data — a cell tree holding state variables (e.g. owner address, counter, balance).
  • Balance — a TON amount.

The triple is hashed; the hash plus the workchain ID forms the contract’s address. That means a contract’s address is deterministic from its code and its initial data — the same init produces the same address on every node.

Message-passing model

TON contracts do not call each other synchronously. Instead they pass messages:

  • Internal messages travel between contracts on TON, carry a TON amount, and are processed asynchronously in subsequent blocks.
  • External messages come in from outside the chain (e.g. a wallet app pushing a signed transaction).
  • Outgoing messages are queued at the end of a contract’s execution and sent once it commits.

There is no equivalent of Solidity’s call(...).value(x) that returns a result in the same transaction. If contract A wants a value from contract B, it sends a message and waits for a reply on a later block.

Get-methods

For read-only queries from off-chain (wallets, explorers, dApps), contracts expose get-methods. These run locally on a node, do not produce a transaction, are free, and cannot mutate state. Almost every wallet UI is built on get-method polling.

Gas and storage fees

Two cost models combine:

  • Compute and forward gas — paid per message, typically 0.005–0.02 TON per call. Way below Ethereum.
  • Storage fees — a small charge proportional to contract size and time. A contract that runs out of balance for too long enters the frozen state and stops responding until it is topped up and unfrozen.

Practical implication: idle contracts must keep a small TON reserve. Most production contracts hold enough for 5–10 years of storage at the current rate.

Init and deploy

A contract is deployed by sending a message that contains its StateInit (code + data) to its computed address. The first incoming message either includes a TON amount (the contract pays its own deploy gas) or relies on a deployer wallet to fund it. After the first transaction, the address is “active” and behaves like any other contract.

Where it lives

A contract sits in exactly one shardchain at any given moment, determined by the address hash prefix. When the shard splits, the contract migrates with its half of the address space — transparent to the user.

How it differs from Ethereum

  • Asynchronous, not synchronous — multi-contract operations span several blocks.
  • One contract per holder for tokens (jettons, NFTs), not a shared mapping.
  • No external view calls in transactions; if you need a value, the receiving contract sends it back as a message.
  • Storage cost is metered separately from gas.

Related terms