# Client contracts implementation logic

To implement a smart contract, you need to extend it from the [abstract class](/infrastructure/asterizm-connector/client-smart-contract-abstraction.md) made by the Asterizm team.

{% hint style="warning" %}
IMPORTANT! The logic of Solana network integration differs significantly from the logic of integrating other networks, so you can read more in the [Solana integration section](/guides/getting-started/1.-deploy-your-smart-contracts/solana-integration-logic.md) about this chain.
{% endhint %}

{% hint style="info" %}
Examples of client contract implementation can be found in the official repository - <https://github.com/Asterizm-Protocol/asterizm-contracts-evm/tree/master/contracts/demo>
{% endhint %}

{% hint style="info" %}
**Important!** To support different types of networks we decided to convert all address variables to the uint format. It is necessary to take this into account when integrating the protocol.&#x20;

To simplify the process, we have implemented the following libraries:

* <https://github.com/Asterizm-Protocol/asterizm-contracts-evm/tree/master/contracts/libs> - for **EVM**
* <https://github.com/Asterizm-Protocol/asterizm-contracts-tvm/tree/master/contracts/libs> - for **TVM**
* <https://github.com/Asterizm-Protocol/asterizm-contracts-ton/tree/master/contracts/libs> - for **TON**
  {% endhint %}

The developer of the client contract must follow several steps:

## Add a library

&#x20;You need to add *AsterizmProtocol* library to your *package.json:* `“asterizmprotocol”: “^1.0.1"` and update packages - <mark style="color:orange;">`npm i`</mark>

### Import abstract contract

You need to import an [Asterizm abstract client contract](/infrastructure/asterizm-connector/client-smart-contract-abstraction.md) into your contract: \
For **EVM**: <mark style="color:orange;">`import "asterizmprotocol/contracts/evm/AsterizmClient.sol"`</mark> (you can also use <mark style="color:orange;">`import "asterizmprotocol/contracts/evm/AsterizmClientUpgradeable.sol"`</mark> for upgradeable client contracts, [example](https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/contracts/demo/AsterizmDemoUpgradeableV1.sol))\
For **TVM** and **TON**: <mark style="color:orange;">`import "asterizmprotocol/contracts/tvm/AsterizmClient.tsol"`</mark>

## Call the class constructor

Call constructor of base client contract setting of necessary parameters: \
For **EVM**: <mark style="color:orange;">`AsterizmClient(IInitializerSender _initializerLib, bool _useForceOrder, bool _disableHashValidation)`</mark>\
For **TVM** and **TON**:  In this network, the constructor does not take any parameters as input, instead static parameters are used  ***initializerLib\_***, ***useForceOrder\_***, ***disableHashValidation\_***\
\
\&#xNAN;***initializerLib*** - initializer contract address (see the [list of supported networks](/what-is-asterizm/supported-chains.md)),\
\&#xNAN;***useForceOrder*** - flag of strict message order (see [Best practices](/advanced/best-practices.md)), \
\&#xNAN;***disableHashValidation*** - disable transfer hash validation flag (see [Best practices](/advanced/best-practices.md))

## Adding trusted addresses

A list of trusted addresses must be populated for the system. This list contains trusted contract addresses for each supported network. This is done by one of two methods:

<mark style="color:orange;">`addTrustedAddress(uint64 _chainId, uint _trusterAddress)`</mark>

<mark style="color:orange;">`addTrustedAddresses(uint64[] _chainId, uint[] _trusterAddress)`</mark>

## Sending messages

To initialize the transfer event you need to call the transfer initialization method:

For **EVM**: <mark style="color:orange;">`_initAsterizmTransferEvent(uint64 _dstChainId, bytes _payload)`</mark>

For **TVM** and **TON**: <mark style="color:orange;">`_initAsterizmTransferEvent(uint64 _dstChainId, TvmCell _payload)`</mark>

***\_dstChainId*** - destination network ID (see the [list of supported networks](/what-is-asterizm/supported-chains.md)),\
\&#xNAN;***\_payload*** - instructions encoded in bytes, for example with `abi.encode()` method&#x20;

**Please note:** it is not necessary to specify a contract address in the destination network - it is taken from the list of trusted addresses (read [Adding trusted addresses](#adding-trusted-addresses)).&#x20;

Examples of transfer initialization:

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/contracts/demo/AsterizmDemo.sol#L28>" %}
EVM contracts
{% endembed %}

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-tvm/blob/master/contracts/demo/AsterizmDemo.tsol#L21>" %}
TVM contracts
{% endembed %}

{% embed url="<https://github.com/Asterizm-Protocol/asterizm-contracts-ton/blob/master/contracts/demo/AsterizmDemo.tsol#L21>" %}
TON contracts
{% endembed %}

## Receive and execute messages

You need to implement <mark style="color:orange;">`_asterizmReceive()`</mark> method to receive and execute data in the destination network. \
This method accepts one `_dto` parameter type  `ClAsterizmReceiveRequestDto`, which contains all transfer data.&#x20;

To retrieve the transferred instructions, the `_dto.payload` parameter must be decoded into the originally transferred data type, for example using the <mark style="color:orange;">`abi.decode()`</mark>method.

{% hint style="warning" %}
IMPORTANT!&#x20;

For EVM networks only.&#x20;

You need to implement the <mark style="color:orange;">`_buildPackedPayload()`</mark>method. \
This method is necessary for the internal protocol logic to convert your payload from <mark style="color:orange;">`abi.encode()`</mark> format into <mark style="color:orange;">`abi.encodePacked()`</mark>. \
This conversion is necessary to implement cross-chain hashing.
{% endhint %}

## Cross-chain data hashing logic

Asterizm protocol has a universal cross-chain data hashing logic. It is required to check the validity and integrity of the data transferred within a cross-chain transaction.

The protocol currently supports the following network types: [EVM](https://help.coinbase.com/en/coinbase/getting-started/crypto-education/glossary/ethereum-virtual-machine) and [TVM](https://docs.everscale.network/arch/tvm/).\
Asterizm independently selects the hashing method depending on what types the source and destination networks are at the abstraction level of the client smart contract.

#### EVM

[Check out](https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/contracts/libs/AsterizmHashLib.sol) an example of hashing implementation for EVM networks.

As mentioned above, in EVM networks you need to implement the method <mark style="color:orange;">`_buildPackedPayload()`</mark> - [example](https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/contracts/demo/AsterizmDemo.sol#L41).

#### TVM and TON

In TVM networks there are several versions of the hashing implementation, so you have to choose the version based on your requirements:

* <mark style="color:orange;">`buildCrosschainHashV1()`</mark>- this version of hashing implementation is relatively cheap, but it has a nuance - if your payload involves sending such data types as bytes or string, you should add these data to the very end of the list when packing (<mark style="color:orange;">`abi.encode()`</mark>) otherwise hash validation errors may occur in the destination network. Use this method if you do not need to send a large number of bytes or string parameters, or to save on gas.
* <mark style="color:orange;">`buildCrosschainHashV2()`</mark>- this version of hashing has a much higher gas price but avoids the problem of the first version related to the position of bytes and string data in your payload. Use this version if you need to send bytes or string data types.

Check [this](https://github.com/Asterizm-Protocol/asterizm-contracts-tvm/blob/master/contracts/libs/AsterizmHashLib.tsol) (TVM) and [this](https://github.com/Asterizm-Protocol/asterizm-contracts-ton/blob/master/contracts/libs/AsterizmHashLib.tsol) (TON) an example of hashing implementation for TVM and TON networks.

{% hint style="warning" %}
IMPORTANT!&#x20;

In case you perform cross-chain transfer between different types of networks (EVM->TVM/TON, TVM/TON->EVM) it is strongly recommended not to use **`bool`** type in payload parameters. Otherwise, validation of transfer integrity in the destination network will fail.
{% endhint %}

{% hint style="success" %}
Congratulations! The contracts for messaging in the required networks are ready and can be deployed to the [networks supported by Asterizm](/what-is-asterizm/supported-chains.md)
{% endhint %}

## Estimating message fees

To understand the payment process and the calculation of cross-chain transaction fees, please see the [Fees management section](/guides/fee-management.md)

## Upgradeable client contracts

The protocol allows for the creation of upgradable client contracts on EVM networks, enabling the separation of system logic and data at the contract level.

To implement an upgradable client contract, you should inherit from<mark style="color:orange;">`"asterizmprotocol/contracts/evm/AsterizmClientUpgradeable.sol"`</mark> [contract abstraction](/infrastructure/asterizm-connector/client-smart-contract-abstraction.md), and instead of using a contract constructor you should utilize a special initialization function as follows: <mark style="color:orange;">`function initialize(IInitializerSender _initializerLib) initializer public { __AsterizmClientUpgradeable_init(_initializerLib, true, true); }`</mark>

Here is an example of how to implement an upgradable contract:

{% @github-files/github-code-block url="<https://github.com/Asterizm-Protocol/asterizm-contracts-evm/blob/master/contracts/demo/AsterizmDemoUpgradeableV1.sol>" %}

## You are almost there!

Get ready to make your transactions confidential using the [Client off-chain module](/infrastructure/client-off-chain-module.md) -  you will learn how to set it up in the [next section](/guides/getting-started/2.-implement-off-chain-module.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.asterizm.io/guides/getting-started/1.-deploy-your-smart-contracts/client-contracts-implementation-logic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
