# Bringing Attestations On Chain

Blocky Attestation Service (Blocky AS) allows you to run custom functions in a
Trusted Execution Environment (TEE) and receive attestations over their
execution. In the [Attesting Function Calls](/attestation-service/v0.1.0-beta.11/attest-fn-call) example, we
showed how to attest a simple "Hello, World!" function call using the Blocky AS
CLI. In this example, we show you how verify that attestation in a smart
contract allowing it to take onchain actions based on the attested function
output.

## Prerequisites

- Install `npm` by following these
[instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
- Clone the Blocky AS
[examples repository](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11)
and navigate to the `on_chain` directory by running:

```bash
git clone git@github.com:blocky/attestation-service-examples.git
cd attestation-service-examples/on_chain
```
- Install project dependencies by running:

```bash
npm install
```


## Quick Start

To verify a Blocky AS function call attestation in a smart contract, follow these steps:

1. Download a
["Hello, World!" function call attestations](/attestation-service/v0.1.0-beta.11/attest-fn-call)
by running:

```bash
curl -o out.json https://docs.blocky.rocks/v0.1.0-beta.11/out.json
```
2. Invoke the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol)
contract to verify the attested function call:

```bash
TA_FILE=$(realpath out.json) npx hardhat test --grep "User contract"
```
which will run a Hardhat test that starts a local Ethereum testnet,
deploys the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol),
contract and calls it with the attested function call as calldata.
You should see the test output:

```
  Test User contract
     processTransitiveAttestedFunctionCall emitted AttestedFunctionCallOutput(Hello, World!)
  ✔ Verify transitive attested function call (801ms)
```


## Full Walkthrough

### Step 1: Attest a function call

In the [Attesting a Function Calls](/attestation-service/v0.1.0-beta.11/attest-fn-call) example, we used
Blocky AS to attest a simple "Hello, World!" function call and saved the
attestations in [out.json](/v0.1.0-beta.11/out.json).
Download it into the `on_chain` directory by running:


```bash
curl -o out.json https://docs.blocky.rocks/v0.1.0-beta.11/out.json
```

### Step 2: Create a smart contract to verify an attested function call

For this example, we have created a simple user contract in
[contracts/User.sol](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol)
to verify a transitive attestation over a function call and emit its output.


```solidity
contract User {
    event AttestedFunctionCallOutput(string output);

    address private enclAttAppPubKeyAddress;

    function setEnclaveAttestedAppPubKey(
        bytes calldata enclAttAppPubKey
    )
    public
    {
        enclAttAppPubKeyAddress = TAParserLib.publicKeyToAddress(
            enclAttAppPubKey
        );
    }

    function processTransitiveAttestedFunctionCall(
        bytes calldata transitiveAttestation
    )
    public
    {
        TAParserLib.FnCallClaims memory claims;

        claims = TAParserLib.verifyTransitiveAttestedFnCall(
            enclAttAppPubKeyAddress,
            transitiveAttestation
        );

        emit AttestedFunctionCallOutput(string(claims.Output));
    }
}
```

The `User` contract complements process of [verifying function execution](/attestation-service/v0.1.0-beta.11/verification),
where verify the properties of a Blocky AS server and its enclave attested
application public key used to sign transitive attestations.
The `setEnclaveAttestedAppPubKey` converts an enclave attested application public key
into an address and stores it in the `enclAttAppPubKeyAddress` variable.
Once the enclave attested application public key is set, the
`processTransitiveAttestedFunctionCall` function uses the
[`TAParserLib.verifyTransitiveAttestedFnCall`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/lib/TAParserLib.sol)
function to verify that the
`transitiveAttestation` was signed by `enclAttAppPubKeyAddress` and to parse out
its `claims`.
Finally, the `processTransitiveAttestedFunctionCall` emits `claims.Output` through
the `AttestedFunctionCallOutput` event. At this point, you can extend the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol)
contract to use the value of `claims.Output` to take further onchain actions.

> Note that you can extend `setEnclaveAttestedAppPubKey` function to set other
elements of the [verification process](/attestation-service/v0.1.0-beta.11/verification#verification-process)
your smart contract will accept such as, `hash_of_code` or `function` name.
The `processTransitiveAttestedFunctionCall` can then check these against the
verified `claims` of the `transitiveAttestation` as described in
[Step 5](/attestation-service/v0.1.0-beta.11/attest-fn-call#step-5-verify-transitive-attested-function-call-output)
of the [Attesting Function Calls](/attestation-service/v0.1.0-beta.11/attest-fn-call) example.


### Step 3: Test the `User` contract locally

To verify the output of the WASM function call in a smart contract, we
extract from [out.json](/v0.1.0-beta.11/out.json) the
enclave attested application public key of the Blocky AS server and the
transitive attestation of function call and pass them to the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol)
contract functions executed in a local [Hardhat](https://hardhat.org/) testnet.

We define the `"User contract test"` in
[test/user.ts](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/test/user.ts),
which deploys the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.11/on_chain/contracts/User.sol)
contract,
calls its functions with the enclave attested application public key
and transitive attestation extracted from [out.json](/v0.1.0-beta.11/out.json),
and checks that the contract emits the `AttestedFunctionCallOutput` event
with `"Hello, World!"` as input.

You can invoke the test by running:


```bash
TA_FILE=$(realpath out.json) npx hardhat test --grep "User contract"
```

to see the output:


```
  Test User contract
     processTransitiveAttestedFunctionCall emitted AttestedFunctionCallOutput(Hello, World!)
  ✔ Verify transitive attested function call (801ms)
```