# Smart Contract Integration

This overview explains how Clique can be integrated with your smart contracts.

### Example

{% code lineNumbers="true" %}

```solidity
/// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {ICliqueTaskManger} from "clique-contracts/ICliqueTaskManger.sol";

struct Response {
    bytes16 data;
}

struct EchoParams {
    bytes data;
}

contract MockClient {
    address public immutable _manager;

    event CallbackInvoked();

    constructor(address manager) {
        _manager = manager;
    }

    function callback(bytes calldata _response) external {
        Response memory response = abi.decode(_response, (Response));
        require(response.data == bytes16("hello, clique"), "Invalid response");
        emit CallbackInvoked();
    }

    function run() public {
        ICliqueTaskManager.Task memory task = ICliqueTaskManager.Task(
            0,
            "echo",
            abi.encode(EchoParams("hello, clique"))
        );
        ICliqueTaskManager(_manager).createNewTask{value: 0.05 ether}(
            abi.encode(task),
            this.callback.selector
        );
    }
}
```

{% endcode %}

Let's break down the example.

```solidity
import {ICliqueTaskManger} from "clique-contracts/ICliqueTaskManger.sol";
```

Import the Clique Contract SDK here.

`run()` is the entry point where we initialize a query struct and call the `createNewTask` function with a callback selector:

```solidity
function run() public {
    ICliqueTaskManager.Task memory task = ICliqueTaskManager.Task(
        0,
        "echo",
        abi.encode(EchoParams("hello, clique"))
    );
    ICliqueTaskManager(_manager).createNewTask{value: 0.05 ether}(
        abi.encode(task),
        this.callback.selector
    );
}
```

Once the task is fulfilled, `callback`will be invoked with response bytes. Program execution resumes afterward.

```solidity
function callback(bytes calldata _response) external {
    Response memory response = abi.decode(_response, (Response));
    require(response.data == bytes16("hello, clique"), "Invalid response");
    emit CallbackInvoked();
}
```

{% hint style="info" %}
Asynchronous programming in Solidity
{% endhint %}

### On-Chain Verification

{% hint style="info" %}
For details on the standard verification process, refer to the [Verification](https://docs.clique.tech/references/verification) section. This process mirrors the one used during setup. To minimize gas costs, subsequent verifications employ an ECDSA-based solution, as outlined in this section.
{% endhint %}

To use ECDSA-based verification, `CliqueTaskManager` maintains a trusted public key. And a **Trust Setup** process is required when a kernel initially fulfills tasks. It must submit a triple tuple consisting of a response, attestation, and signature.  If the attestation is valid, the public key recovered from this `signature, CUID` pair will be trusted. The ephemeral key must be regenerated each time the kernel restarts. Once **Trust Setup** done, the `attestation` could be empty when the kernel fulfills subsequent tasks.&#x20;

For more information, please refer to [#on-chain-verification](https://docs.clique.tech/references/verification#on-chain-verification "mention").
