> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-ton-storage.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Your first smart contract

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

Welcome to your journey into TON smart contract development! In this comprehensive tutorial, you'll learn to build, deploy, and interact with a smart contract from scratch.

## What you'll learn

By the end of this tutorial, you'll have:

* ✅ **Built** a complete smart contract in Tolk
* ✅ **Deployed** it to TON testnet
* ✅ **Interacted** with it using TypeScript scripts
* ✅ **Mastered** the fundamentals of TON development

## What is a TON smart contract?

### Understanding the basics

A **smart contract** is a computer program stored on TON Blockchain — a distributed database that many computers maintain together. It runs on the [TVM](/tvm/overview) (TON Virtual Machine) — the "computer" that runs smart contract code on TON.

The contract is made of two parts:

* **Code** (compiled TVM instructions) - the "rules" or "program logic"
* **Data** (persistent state) - the "memory" that remembers things between interactions

Both are stored at a specific **address** on TON Blockchain, a unique identifier for each smart contract.

## Prerequisites

* **Basic programming** - Understanding of variables, functions, if/else statements
* **Command line basics** - Comfortable opening terminal and running commands
* **Node.js** (v22 or later) — [Download here](https://nodejs.org/)
  * Check if installed: `node -v` in terminal
* **TON wallet**

## Tutorial overview

This tutorial is organized into six clear steps that build upon each other:

| Step                                                               | What You'll Do              | Key Skills                                           |
| ------------------------------------------------------------------ | --------------------------- | ---------------------------------------------------- |
| **[Step 1](#step-1%3A-development-environment-setup)**             | Set up Blueprint toolkit    | Project structure, development environment           |
| **[Step 2](#step-2%3A-understanding-smart-contract-architecture)** | Learn contract architecture | Storage, messages, getters concept                   |
| **[Step 3](#step-3%3A-writing-the-smart-contract)**                | Write contract in Tolk      | Programming, message handling, data structures       |
| **[Step 4](#step-4%3A-compiling-your-contract)**                   | Compile to bytecode         | Build process, TVM compilation                       |
| **[Step 5](#step-5%3A-deploying-to-testnet)**                      | Deploy to blockchain        | Testnet deployment, wallet integration               |
| **[Step 6](#step-6%3A-contract-interaction)**                      | Interact with contract      | Message sending, get methods, TypeScript integration |

Let's dive into development!

## Step 1: Development environment setup

We'll use [**Blueprint**](/contract-dev/blueprint/overview) as our development toolkit for smart contracts. Start a new project with:

```bash theme={null}
npm create ton@latest -- Example --contractName FirstContract --type tolk-empty
```

This will create a project **Example** with a contract **FirstContract**.

The project structure will look like this:

```text theme={null}
Example/
├── contracts/                       # Smart contract source code
│   └── first_contract.tolk          # Main contract file
├── scripts/                         # Deployment and on-chain interaction scripts
│   └── deployFirstContract.ts       # Script to deploy the contract
├── tests/                           # Testing specifications
│   └── FirstContract.spec.ts        # Contract test file
└── wrappers/                        # TypeScript wrappers for contract interaction
    ├── FirstContract.ts             # Wrapper class for the smart contract
    └── FirstContract.compile.ts     # Configuration for compiling contract
```

<Aside>
  TON provides plugins that add syntax support for various IDEs and code editors.
  Check out the [IDE & plugins](/contract-dev/ide/overview) section for VS Code and JetBrains support.
</Aside>

Now, move into the project directory:

```bash theme={null}
cd Example
```

## Step 2: Understanding smart contract architecture

Every smart contract in TON is typically divided into three sections: **storage**, **messages**, and **getters**.

* **Storage**: Defines the contract’s persistent data. For example, our *counter* variable must keep its value across calls from different users.
* **Messages**: Define how the contract reacts to incoming messages. On TON, the primary way to interact with contracts is by sending [messages](/foundations/messages/ordinary-tx). Each processed message produces a [transaction](/foundations/messages/ordinary-tx) — a recorded change on the blockchain (like "Alice sent 5 TON to Bob").
* **Getters**: Provide read-only access to contract data without modifying state. For example, we’ll create a getter to return the current value of the counter.

<Aside type="caution">
  Due to the [TON architecture](/from-ethereum#on-chain-get-methods), getters cannot be called from other contracts.
  Inter-contract communication is possible only through **messages**.
</Aside>

## Step 3: Writing the smart contract

We’ll build a simple **counter** contract:

* The counter starts from an initial number.
* Users can send an `increase` message to increment it, or a `reset` message to drop it to zero.
* A `getter` function will let anyone query the current counter value.

We'll use [**Tolk**](/languages/tolk) to implement this. Tolk looks familiar if you know TypeScript or Rust, but it's designed specifically for smart contract development.

### 3.1 Defining contract storage

First, we need a way to store the counter value. Tolk makes this simple with <Tooltip tip="A structure is a composite data type that groups named fields (each with its own type) into one unit." cta="Learn more" href="/languages/tolk">structures</Tooltip>:

```tolk title="./contracts/first_contract.tolk" theme={null}
struct Storage {
    counter: uint64  // the current counter value
}

// load contract data from persistent storage
fun Storage.load() {
    return Storage.fromCell(contract.getData())
}

// save contract data to persistent storage
fun Storage.save(self) {
    contract.setData(self.toCell())
}
```

Behind the scenes, structures know how to serialize and deserialize themselves into [cells](/foundations/serialization/cells) — the fundamental way TON stores data. This happens through the `fromCell` and `toCell` functions - Tolk automatically converts between your nice structures and the cell format that TON understands.
You may think of cells like containers that hold data on TON:

* Each cell can store up to 1023 bits of data.
* Cells can reference other cells (like links).
* Everything on TON (contracts, messages, storage) is made of cells.

Now that we can store data, let’s handle our first messages.

### 3.2 Implementing message handlers

The main entry point for processing messages in a Tolk contract is the `onInternalMessage` function. It receives one argument — the incoming message. Among its fields, the most important one for us is `body`, which contains the payload sent by a user or another contract.

Tolk structures are also useful for defining message bodies. In our case, we’ll define two messages:

* `IncreaseCounter` — with one field `increaseBy`, used to increment the counter.
* `ResetCounter` — used to reset the counter to zero.

Each structure has a unique prefix (`0x7e8764ef` and `0x3a752f06`), widely called opcodes, that lets the contract distinguish between them.

```tolk title="./contracts/first_contract.tolk" theme={null}
struct (0x7e8764ef) IncreaseCounter {
    increaseBy: uint32
}

struct (0x3a752f06) ResetCounter {}
```

To group them together, we'll use a union. Unions allow multiple types to be bundled into a single type that can be serialized and deserialized automatically:

```tolk title="./contracts/first_contract.tolk" theme={null}
type AllowedMessage = IncreaseCounter | ResetCounter
```

Now we can write our message handler:

```tolk title="./contracts/first_contract.tolk" theme={null}
fun onInternalMessage(in: InMessage) {
    // use `lazy` to defer parsing until fields are accessed
    val msg = lazy AllowedMessage.fromSlice(in.body);

    // matching our union to determine body structure
    match (msg) {
        IncreaseCounter => {
            // load contract storage lazily (efficient for large or partial reads/updates)
            var storage = lazy Storage.load();
            storage.counter += msg.increaseBy;
            storage.save();
        }

        ResetCounter => {
            var storage = lazy Storage.load();
            storage.counter = 0;
            storage.save();
        }

        // this match branch would be executed if the message body does not match IncreaseCounter or ResetCounter structures
        else => {
            // reject user message (throw) if body is not empty
            assert(in.body.isEmpty()) throw 0xFFFF
        }
    }
}
```

<Aside title={"📚 Learn More About Tolk"}>
  * [Tolk Language Guide](/languages/tolk) - Complete language documentation
  * [View the complete contract on GitHub](https://github.com/ton-org/docs-examples/blob/main/guidebook/first-smart-contract/Example/contracts/first_contract.tolk)
</Aside>

### 3.3 Adding getter functions

Finally, let’s implement a getter so users can read the current counter value:

```tolk title="./contracts/first_contract.tolk" theme={null}
get fun currentCounter(): int {
    val storage = lazy Storage.load();
    return storage.counter;
}
```

### 3.4 Complete contract code

We now have a complete smart contract with:

* **Storage**: persistent `counter` value
* **Messages**: `IncreaseCounter` and `ResetCounter` handlers
* **Getter**: `currentCounter`

Here’s the full source code of `contracts/first_contract.tolk`:

```tolk title="./contracts/first_contract.tolk" expandable theme={null}
struct Storage {
    counter: uint64
}

fun Storage.load() {
    return Storage.fromCell(contract.getData());
}

fun Storage.save(self) {
    contract.setData(self.toCell());
}

struct (0x7e8764ef) IncreaseCounter {
    increaseBy: uint32
}

struct (0x3a752f06) ResetCounter {}

type AllowedMessage = IncreaseCounter | ResetCounter

fun onInternalMessage(in: InMessage) {
    val msg = lazy AllowedMessage.fromSlice(in.body);

    match (msg) {
        IncreaseCounter => {
            var storage = lazy Storage.load();
            storage.counter += msg.increaseBy;
            storage.save();
        }

        ResetCounter => {
            var storage = lazy Storage.load();
            storage.counter = 0;
            storage.save();
        }

        else => {
            assert(in.body.isEmpty()) throw 0xFFFF;
        }
    }
}

get fun currentCounter(): int {
    val storage = lazy Storage.load();
    return storage.counter;
}
```

🎉 Congratulations — you've built your first smart contract in **Tolk**!

<Aside title={"📁 Complete Example Code"}>
  You can find the full working code for this tutorial in our [GitHub repository](https://github.com/ton-org/docs-examples/tree/main/guidebook/first-smart-contract/Example). This includes all contract files, scripts, and wrappers ready to use.
</Aside>

## Step 4: Compiling your contract

The next step is to build our contract — compile it into bytecode that can be executed by the TVM. With **Blueprint**, this takes one command:

```bash theme={null}
npx blueprint build FirstContract
```

Expected output:

```ansi theme={null}
Build script running, compiling FirstContract
🔧 Using tolk version 1.1.0...

✅ Compiled successfully! Cell BOC result:

{
  "hash": "fbfb4be0cf4ed74123b40d07fb5b7216b0f7d3195131ab21115dda537bad2baf",
  "hashBase64": "+/tL4M9O10EjtA0H+1tyFrD30xlRMashEV3aU3utK68=",
  "hex": "b5ee9c7241010401005b000114ff00f4a413f4bcf2c80b0102016202030078d0f891f24020d72c23f43b277c8e1331ed44d001d70b1f01d70b3fa0c8cb3fc9ed54e0d72c21d3a9783431983070c8cb3fc9ed54e0840f01c700f2f40011a195a1da89a1ae167fe3084b2d"
}

✅ Wrote compilation artifact to build/FirstContract.compiled.json
```

This compilation artifact contains the **contract bytecode** and will be used in the deployment step.

In the next section, we'll learn how to **deploy this contract to the TON blockchain** and interact with it using scripts and wrappers.

## Step 5: Deploying to testnet

Ready to put your contract on-chain? 🚀

To deploy, we first need a **wrapper class**. Wrappers implement the `Contract` interface and make it easy to interact with contracts from TypeScript.

Create a file `./wrappers/FirstContract.ts` with the following code:

```typescript title="./wrappers/FirstContract.ts" theme={null}
import { Address, beginCell, Cell, Contract, contractAddress, ContractProvider, Sender, SendMode } from '@ton/core';

export class FirstContract implements Contract {
    constructor(
        readonly address: Address,
        readonly init?: { code: Cell; data: Cell },
    ) {}

    static createFromConfig(config: { counter: number }, code: Cell, workchain = 0) {
        const data = beginCell().storeUint(config.counter, 64).endCell();
        const init = { code, data };
        return new FirstContract(contractAddress(workchain, init), init);
    }

    async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) {
        await provider.internal(via, {
            value,
            sendMode: SendMode.PAY_GAS_SEPARATELY,
        });
    }
}
```

### 5.1 Understanding the wrapper class

* We depend on [`@ton/core`](https://www.npmjs.com/package/@ton/core) — a library with base TON types.
* The function `createFromConfig` constructs a wrapper using **code** (compiled bytecode) and **data** (the initial storage layout).
* The contract [address](/foundations/addresses/overview) is derived deterministically from `code + data` using `contractAddress`. If two contracts have the same code and init data, the calculation of the address will result in the same value.
* The method `sendDeploy` sends the first message with [`stateInit`](/foundations/messages/deploy), which triggers deployment. In practice, this can be an empty message with some TON coins attached.

### 5.2 Choosing your network

TON has two networks available for deployment:

* **testnet** — developer sandbox.
* **mainnet** — production blockchain.

For this tutorial, we'll use **testnet** since it's free and perfect for learning. You can always deploy to mainnet later once you're confident in your contract.

### 5.3 Creating the deployment script

Blueprint makes deployment simple. Create a new script `./scripts/deployFirstContract.ts`:

```typescript title="./scripts/deployFirstContract.ts" theme={null}
import { toNano } from '@ton/core';
import { FirstContract } from '../wrappers/FirstContract';
import { compile, NetworkProvider } from '@ton/blueprint';

export async function run(provider: NetworkProvider) {
    const firstContract = provider.open(
        FirstContract.createFromConfig(
            { counter: Math.floor(Math.random() * 10000000) },
            await compile('FirstContract')
        )
    );

    await firstContract.sendDeploy(provider.sender(), toNano('0.05'));

    await provider.waitForDeploy(firstContract.address);
}
```

The `sendDeploy` method accepts three arguments, but we only pass two because `provider.open` automatically supplies the ContractProvider as the first argument.

Run the script with ([learn more about Blueprint deployment](/contract-dev/blueprint/deploy)):

```bash theme={null}
npx blueprint run deployFirstContract --testnet --tonconnect --tonviewer
```

Choose your wallet, scan the QR code shown in the console, and approve the transaction in your wallet app.

Expected output:

```text theme={null}
Using file: deployFirstContract
? Choose your wallet Tonkeeper

<QR_CODE_HERE>

Connected to wallet at address: ...
Sending transaction. Approve in your wallet...
Sent transaction
Contract deployed at address kQBz-OQQ0Olnd4IPdLGZCqHkpuAO3zdPqAy92y6G-UUpiC_o
You can view it at https://testnet.tonviewer.com/kQBz-OQQ0Olnd4IPdLGZCqHkpuAO3zdPqAy92y6G-UUpiC_o
```

Follow the link in the console to see your contract on the **Tonviewer**. Blockchain explorers like [Tonviewer](/ecosystem/explorers/tonviewer) allow you to inspect transactions, smart contracts, and account states on the TON blockchain.

🎉 Congratulations! Your contract is live on testnet. Let's interact with it by sending messages and calling get methods.

## Step 6: Contract interaction

Technically speaking, we've already sent messages to the contract - the deploy message in previous steps. Now let's see how to send messages with a body.

First of all, we should update our wrapper class with three methods: `sendIncrease`, `sendReset`, and `getCounter`:

```typescript title="./wrappers/FirstContract.ts" theme={null}
import { Address, beginCell, Cell, Contract, contractAddress, ContractProvider, Sender, SendMode } from '@ton/core';

export class FirstContract implements Contract {
    constructor(
        readonly address: Address,
        readonly init?: { code: Cell; data: Cell },
    ) {}

    static createFromConfig(config: { counter: number }, code: Cell, workchain = 0) {
        const data = beginCell().storeUint(config.counter, 64).endCell();
        const init = { code, data };
        return new FirstContract(contractAddress(workchain, init), init);
    }

    async sendDeploy(provider: ContractProvider, via: Sender, value: bigint) {
        await provider.internal(via, {
            value,
            sendMode: SendMode.PAY_GAS_SEPARATELY,
            body: beginCell().endCell(),
        });
    }

    async sendIncrease(
        provider: ContractProvider,
        via: Sender,
        opts: {
            increaseBy: number;
            value: bigint;
        },
    ) {
        await provider.internal(via, {
            value: opts.value,
            sendMode: SendMode.PAY_GAS_SEPARATELY,
            body: beginCell().storeUint(0x7e8764ef, 32).storeUint(opts.increaseBy, 32).endCell(),
        });
    }

    async sendReset(
        provider: ContractProvider,
        via: Sender,
        opts: {
            value: bigint;
        },
    ) {
        await provider.internal(via, {
            value: opts.value,
            sendMode: SendMode.PAY_GAS_SEPARATELY,
            body: beginCell().storeUint(0x3a752f06, 32).endCell(),
        });
    }

    async getCounter(provider: ContractProvider) {
        const result = await provider.get('currentCounter', []);
        return result.stack.readNumber();
    }
}
```

The only difference from the deploy message is that we pass a **body** to it — remember the cells I talked about previously? The message body is a cell that contains our instructions.

### Building message bodies

Construction of cells starts with the `beginCell` method ([learn more about cell serialization](/foundations/serialization/cells)):

* `beginCell()` - creates a new cell builder
* `storeUint(value, bits)` - adds an unsigned integer of specified bit length
* `endCell()` - finalizes the cell

**Example**: `beginCell().storeUint(0x7e8764ef, 32).storeUint(42, 32).endCell()`

* First 32 bits: `0x7e8764ef` (opcode for "increase")
* Next 32 bits: `42` (increase by this amount)

### 6.1 Sending messages to your contract

Now that our contract is deployed and we have wrapper methods, let's interact with it by sending messages.

Let's create a script `./scripts/sendIncrease.ts` that would increase the counter:

```typescript title="./scripts/sendIncrease.ts" theme={null}
import { Address, toNano } from '@ton/core';
import { FirstContract } from '../wrappers/FirstContract';
import { NetworkProvider } from '@ton/blueprint';

const contractAddress = Address.parse('<CONTRACT_ADDRESS>');

export async function run(provider: NetworkProvider) {
    const firstContract = provider.open(new FirstContract(contractAddress));
    await firstContract.sendIncrease(provider.sender(), { value: toNano('0.05'), increaseBy: 42 });
    await provider.waitForLastTransaction();
}
```

Do not forget to replace `<CONTRACT_ADDRESS>` with your actual contract address from Step 5!

#### Understanding the script breakdown:

* **Address parsing**: `Address.parse()` converts the string address to a TON Address object
* **Contract opening**: `provider.open()` creates a connection to the deployed contract
* **Value attachment**: `toNano('0.05')` converts 0.05 TON to nanotons (the smallest TON unit)
* **Message parameters**: `increaseBy: 42` tells the contract to increase the counter by 42
* **Transaction waiting**: `waitForLastTransaction()` waits for the transaction to be processed on-chain

To run this script:

```bash theme={null}
npx blueprint run sendIncrease --testnet --tonconnect --tonviewer
```

Expected result:

```text theme={null}
Using file: sendIncrease
Connected to wallet at address: ...
Sending transaction. Approve in your wallet...
Sent transaction
Transaction 0fc1421b06b01c65963fa76f5d24473effd6d63fc4ea3b6ea7739cc533ba62ee successfully applied!
You can view it at https://testnet.tonviewer.com/transaction/fe6380dc2e4fab5c2caf41164d204e2f41bebe7a3ad2cb258803759be41b5734
```

#### What happens during execution:

1. **Wallet Connection**: Blueprint connects to your wallet using [TON Connect](/ecosystem/ton-connect/overview) protocol
2. **Transaction Building**: The script creates a transaction with the message body containing the opcode `0x7e8764ef` and the value `42`
3. **User Approval**: Your wallet app shows the transaction details for approval
4. **Blockchain Processing**: Once approved, the transaction is sent to the TON network
5. **Validator Consensus**: Validators need to produce a new block containing your transaction
6. **Contract Execution**: The contract receives the message, processes it in the `onInternalMessage` function, and updates the counter
7. **Confirmation**: The transaction hash is returned, and you can view it on the explorer

<Aside type={"tip"}>
  **Composability**: Messages can be sent to your contract by other contracts, too! This means different contracts can increment your counter, allowing the TON ecosystem to create composable apps and protocols that build on top of each other and interact in unforeseen ways.
</Aside>

Let's create a script `./scripts/sendReset.ts` that would reset the counter:

```typescript title="./scripts/sendReset.ts" theme={null}
import { Address, toNano } from '@ton/core';
import { FirstContract } from '../wrappers/FirstContract';
import { NetworkProvider } from '@ton/blueprint';

const contractAddress = Address.parse('<CONTRACT_ADDRESS>');

export async function run(provider: NetworkProvider) {
    const firstContract = provider.open(new FirstContract(contractAddress));
    await firstContract.sendReset(provider.sender(), { value: toNano('0.05') });
    await provider.waitForLastTransaction();
}
```

To run this script:

```bash theme={null}
npx blueprint run sendReset --testnet --tonconnect --tonviewer
```

Expected result:

```text theme={null}
Using file: sendReset
Connected to wallet at address: ...
Sending transaction. Approve in your wallet...
Sent transaction
Transaction 0fc1421b06b01c65963fa76f5d24473effd6d63fc4ea3b6ea7739cc533ba62ee successfully applied!
You can view it at https://testnet.tonviewer.com/transaction/fe6380dc2e4fab5c2caf41164d204e2f41bebe7a3ad2cb258803759be41b5734
```

### 6.2 Reading contract data with get methods

Get methods are special functions in TON smart contracts that allow you to read data without modifying the contract state or spending gas fees. Unlike message-based interactions, get methods:

* **Cost nothing**: No gas fees required since they don't modify blockchain state
* **Execute instantly**: No need to wait for blockchain confirmation
* **Read-only**: Cannot change contract storage or send messages

To call a get method, use `provider.get(<GET_METHOD_NAME>)`:

```typescript title="./scripts/getCounter.ts" theme={null}
import { Address } from '@ton/core';
import { FirstContract } from '../wrappers/FirstContract';
import { NetworkProvider } from '@ton/blueprint';

const contractAddress = Address.parse('<CONTRACT_ADDRESS>');

export async function run(provider: NetworkProvider) {
    const firstContract = provider.open(new FirstContract(contractAddress));
    const counter = await firstContract.getCounter();
    console.log('Counter: ', counter);
}
```

#### Understanding the get method execution:

1. **Direct contract call**: The `getCounter()` method directly calls the contract's `currentCounter` getter
2. **Instant response**: The result is returned immediately without blockchain confirmation
3. **Data parsing**: Our wrapper automatically converts the returned stack value to a JavaScript number

<Aside>
  Getters are only accessible **off-chain** (from JavaScript clients, web apps, etc.) through RPC service providers. **Contracts cannot call getters on other contracts** - inter-contract communication must use messages only.
</Aside>

To run this script:

```bash theme={null}
npx blueprint run getCounter --testnet --tonconnect
```

Expected output:

```bash theme={null}
Using file: getCounter
Counter:  42
```

## 🎉 Tutorial complete!

**Congratulations!** You've successfully built, deployed, and interacted with your first TON smart contract from scratch. This is a significant achievement in your blockchain development journey!

### Continue Your Learning Journey

Ready to build more advanced contracts? Here's your roadmap:

#### **Next Steps**

* [Tolk Language Guide](/languages/tolk) - Master advanced Tolk features and syntax
* [Blueprint Documentation](/contract-dev/blueprint/overview) - Learn advanced development patterns
* [Tutorial Example Repository](https://github.com/ton-org/docs-examples/tree/main/guidebook/first-smart-contract/Example) - Complete working code from this tutorial

#### **Advanced Topics**

* [Gas Optimization](/contract-dev/gas) - Reduce transaction costs
* [Security Best Practices](/contract-dev/security) - Protect your contracts

<Aside title={"Tutorial Credits"}>
  This tutorial was enhanced with insights from the excellent [TON Hello World series](https://helloworld.tonstudio.io/02-contract/) by Tal Kol and the TON community. For additional examples and alternative approaches, check out the original series.
</Aside>

**🎉 Happy coding on TON!** You're now equipped with the fundamentals to build amazing smart contracts. The blockchain world awaits your innovations! 🚀
