Skip to main content
TON Virtual Machine (TVM) is a stack-based virtual machine which executes smart contracts on TON blockchain. TVM is invoked when a message is sent to an account that has deployed contract code, when a get method is called on an account, and in some more rare cases. Executing code on same inputs and prior state deterministically produces same outputs, so that validators can agree on whether code was executed correctly. Every instruction consumes gas. Gas exhaustion stops execution. This limit is imposed so that expensive computations (i.e. infinite loops) cannot be used to exhaust validators’ computation resources, causing denial of service.

Data model

  • TVM has no random-access memory. Instead it uses a stack of values as a scratchpad.
  • There are no memory addresses. Most instructions either store their parameters directly in the code, or take them from the top of the stack.
  • All values are immutable. Most of the data is stored as immutable tree of cells.
  • Reading and writing of cells is done with slices and builders.
  • There are no function addresses or function pointers. Code is executed from bitcode inside continuations.

TVM state

On incoming messages or get method call, a new instance of TVM is started, with a new state. Derivation of the initial state from the message is described in its own article. The total state of TVM consists of the following components:
  • Stack. A regular stack data structure. The vast majority of instructions pop() operands from the top and push() results back.
  • Control registers. A small fixed set of special registers, denoted as c0, c1, …, c5, and c7 (c6 does not exist).
  • Gas counter. Tracks remaining computation budget. Each instruction decrements gas. When counter hits zero/negative value, an exception is raised, and the run aborts.
  • Current continuation (cc). A special register that stores a list of the next instructions to execute. Similar to the instruction pointer in traditional architectures.
  • Current codepage (cp). Determines how to decode the next instruction in cc. Different codepages may implement different instruction sets, allowing for adding new features to TVM without affecting old smart contracts. Currently, only codepage 0 (cp0) is implemented. Smart contract runs SETCP0 instruction to explicitly use codepage 0.

TVM data types

Values on the stack and inside of registers are of one of the following seven types:

Example of a smart contract: counter

Here is a sample contract, written in Fift. It implements the following logic:
  • If an event is not an internal message, stop execution.
  • Read 32-bit number (msg_counter) from internal message’s body.
  • Check that it is equal to the 32-bit number stored in c4 (persistent account storage).
  • Increment it.
  • Save it back to c4.
When an account with this code gets an internal message, TVM stack is initialized with these values:
  1. s0 (top of the stack), function selector, is 0. For other events, e.g., external messages or get method calls, selector will be non-zero.
  2. s1, message body. The example contract expects exactly 32 bits here.
  3. Three more values s2, s3, s4 are pushed by TVM onto a stack. They won’t be used in the example. After execution finishes, they’ll still be on the stack, and will be silently ignored.
In Current stack comments, we represent stack at that moment of execution, keeping its top to the right (e.g., s2 s1 s0, where s0 is the top of the stack).
Fift