> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tac.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Basic Proxy Example

> This guide walks you through creating your first basic proxy contract, explaining each concept as we build.

<Tip>
  In the [`create-tac-app`](/quickstart/overview) quickstart project, the TAC Proxy `MessageProxy.sol` contract is created automatically.
  You can also review it
</Tip>

## Your First Proxy Contract

Let's start with the absolute minimum proxy contract that can handle TON->TAC transaction:

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import { TacProxyV1 } from "@tonappchain/evm-ccl/contracts/proxies/TacProxyV1.sol";
import { TacHeaderV1 } from "@tonappchain/evm-ccl/contracts/core/Structs.sol";

contract HelloProxy is TacProxyV1 {
    event HelloFromTON(string indexed tonUser, string message);

    constructor(address crossChainLayer) TacProxyV1(crossChainLayer) {}

    function sayHello(bytes calldata tacHeader, bytes calldata arguments)
        external
        _onlyCrossChainLayer
    {
        // 1. Decode who's calling from TON
        TacHeaderV1 memory header = _decodeTacHeader(tacHeader);

        // 2. Decode their message
        string memory message = abi.decode(arguments, (string));

        // 3. Do something with it
        emit HelloFromTON(header.tvmCaller, message);
    }
}
```

That's it! This contract can receive messages from any TON user.

## Understanding the Structure

### Required Imports

```solidity theme={null}
import { TacProxyV1 } from "@tonappchain/evm-ccl/contracts/proxies/TacProxyV1.sol";
import { TacHeaderV1 } from "@tonappchain/evm-ccl/contracts/core/Structs.sol";
```

* `TacProxyV1`: The base contract that handles all cross-chain communication
* `TacHeaderV1`: Data structure containing information about the TON user

### Inheritance

```solidity theme={null}
contract HelloProxy is TacProxyV1 {
```

Your contract **must** inherit from `TacProxyV1` to receive cross-chain calls.

### Constructor Parameter

```solidity theme={null}
constructor(address crossChainLayer) TacProxyV1(crossChainLayer) {}
```

The `crossChainLayer` address is TAC's infrastructure contract that will call your functions. You get this address from TAC documentation or contract addresses page.

### Function Signature (Critical!)

```solidity theme={null}
function sayHello(bytes calldata tacHeader, bytes calldata arguments)
    external
    _onlyCrossChainLayer
{
```

**Every cross-chain function must follow this exact pattern:**

* `bytes calldata tacHeader` - Encoded TacHeaderV1 containing TON user information
* `bytes calldata arguments` - Your custom ABI-encoded parameters
* `external` - Must be externally callable
* `_onlyCrossChainLayer` - Security modifier that ensures only CrossChainLayer can call this function
  (required only for TON->TAC and TON->TAC->TON types)

## Step-by-Step Walkthrough

### Step 1: Decode the Header

```solidity theme={null}
TacHeaderV1 memory header = _decodeTacHeader(tacHeader);
```

The header tells you:

* `header.tvmCaller` - TON user's address. **Important!** It is always base64 mainnet bounceable format and starts with "EQ" (like "EQAbc123...")
* `header.operationId` - Unique ID for this operation
* `header.timestamp` - When the TON transaction happened

### Step 2: Decode Your Parameters

```solidity theme={null}
string memory message = abi.decode(arguments, (string));
```

The `arguments` contain whatever data the TON user sent. You decide what format this should be - it could be:

* A single string: `abi.decode(arguments, (string))`
* Multiple values: `abi.decode(arguments, (uint256, address, bool))`
* A struct: `abi.decode(arguments, (MyCustomStruct))`

### Step 3: Execute Your Logic

```solidity theme={null}
emit HelloFromTON(header.tvmCaller, message);
```

This is where you do whatever your contract is supposed to do. In this example, we just emit an event, but you could:

* Store data in state variables
* Call other contracts
* Perform calculations
* Transfer tokens

## Sending Responses Back to TON

You may also want to send arbitrary tokens back to the TON user after an EVM execution (TON->TAC->TON transaction type).
Learn how in the [more advanced example](/proxies/custom-proxy/proxy-functions#complete-implementation-walkthrough).

## Deployment

Deploy your basic proxy just like any other contract. You can also use `deploy` from `@tonappchain/evm-ccl` as helper:

```javascript theme={null}
import { Signer } from "ethers";
import { HelloProxy } from "../../typechain-types";
import { deploy } from '@tonappchain/evm-ccl';
import hre from 'hardhat';

export async function deployHelloProxy(
    deployer: Signer,
    crossChainLayer: string,
): Promise<HelloProxy> {
    const helloProxy = await deploy<HelloProxy>(
        deployer,
        hre.artifacts.readArtifactSync('HelloProxy'),
        [crossChainLayer],
        undefined,
        true // verbose
    );

    await helloProxy.waitForDeployment();
    return helloProxy;
}

async function main() {
    const [deployer] = await hre.ethers.getSigners();
    const crossChainLayer = process.env.CROSS_CHAIN_LAYER_ADDRESS;
    const helloProxy = await deployHelloProxy(deployer, crossChainLayer);
    console.log("HelloProxy deployed to:", helloProxy.target);
}

main().catch(console.error);
```

## What's Next?

<Tip>
  **Start simple**: Build and test basic proxy contracts before moving to
  upgradeable patterns. Most use cases don't actually need upgradeability.
</Tip>

Feeling ready for more complex patterns?

<CardGroup cols={1}>
  <Card title="Upgradeable Proxy Example" icon="arrow-up" href="/proxies/custom-proxy/upgradeable-proxy">
    Learn when and how to build contracts that can be upgraded over time
  </Card>
</CardGroup>
