# Bringing Attestations On Chain

The Blocky Attestation Service `attest-fn-call` command allows you to submit a
function call to a TEE for execution. You can bring these attestations on chain
to user their attested data in your smart contracts. Below we walk you through
an example of bringing a Blocky AS function call attestation on chain. If you
haven't already, you may want to go through the
[Attesting Function Calls](/attestation-service/v0.1.0-beta.8/attest-fn-call)
example to learn how to create a function call attestation.

## Setup

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

```bash
git clone git@github.com:blocky/attestation-service-examples.git
cd attestation-service-examples/hello_world_on_chain
```
- Set up the project dependencies:

```bash
npm install --dd
```


## Quick Start

To run this example, call:


```bash
make test-local
```

which will test verifying an attested function call in
[User.sol](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
within a local test environment:


```
  Local Test
Verified attest-fn-call claims:
        Function: helloWorld
        Hash of code: a8c69ed89187a4a6b46f0e7e3e30e144784fe4f60640a0839f1e7e81af31a4cf0ec82954172094167281a3b8ed3ddb2964fc53cc3c4d03d0ba8cd680db5a9ff6
        Hash of input: a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
        Hash of secrets: 9375447cd5307bf7473b8200f039b60a3be491282f852df9f42ce31a8a43f6f8e916c4f8264e7d233add48746a40166eec588be8b7b9b16a5eb698d4c3b06e00
        Output: Hello, World!
    ✔ Set signing key and verify TA (675ms)
```

## Walkthrough

### Step 1: Attest a function call

In the [Attesting a Function Calls](/attestation-service/v0.1.0-beta.8/attest-fn-call)
example we walked through a process of attesting a WASM function call. The
result of that process was a `tmp/out.json` file containing the enclave attested
application public key and a transitive attestation of the function call. The
contents of `tmp/out.json` have been verified by the Blocky AS CLI.
To learn more about that process, revisit the
[Attesting a Function Calls](/attestation-service/v0.1.0-beta.8/attest-fn-call)
example, or read about
[Attestations in the Blocky Attestation Service](/attestation-service/v0.1.0-beta.8/concepts#attestations-in-the-blocky-attestation-service)
in our documentation.

For this example, we have copied
`tmp/out.json`
from the previous example into
[inputs/out.json](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/inputs/out.json).
To verify the output of the WASM function call in a smart contract, we will
extract from `out.json` the transitive attestation of function call, as well as
the enclave attested application public key of the Blocky AS server. As you'll
see later, this example is driven by tests in
[tests/user.ts](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/test/user.ts).
In that file, we use the `loadEVMLinkData`
function to extract the transitive attestation and enclave attested application
public key from
[inputs/out.json](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/inputs/out.json).
If you like, you can see these values now by running:


```bash
jq -r '.function_calls[0].transitive_attestation' inputs/out.json
```

and


```bash
jq -r '.enclave_attested_application_public_key.claims.public_key.data' inputs/out.json
```

### Step 2: Write a smart contract to verify a function call attestation

For this example, we have created user contract in
[contracts/User.sol](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol).
Its goal is to verify that a transitive attestation has
been signed by the enclave attested application public key of the Blocky AS
server and parse out the attested function output.

For this example, we have created `User` contract in
[`contracts/User.sol`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol).


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

  function processTransitivelyAttestedHelloWorldOutput(
    bytes calldata applicationPublicKey,
    string calldata transitiveAttestation
  )
  public
  {
    TAParserLib.FnCallClaims memory claims;

    address applicationPublicKeyAsAddress = TAParserLib.publicKeyToAddress(
      applicationPublicKey
    );

    claims = TAParserLib.verifyTransitivelyAttestedFnCall(
      applicationPublicKeyAsAddress,
      transitiveAttestation
    );

    console.log("Verified attest-fn-call claims:");
    console.log("\tFunction: %s", claims.Function);
    console.log("\tHash of code: %s", claims.HashOfCode);
    console.log("\tHash of input: %s", claims.HashOfInput);
    console.log("\tHash of secrets: %s", claims.HashOfSecrets);
    console.log("\tOutput: %s", claims.Output);

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

The goal of the
[`User`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract is to verify that a
transitive attestation of the `helloWorld` function (defined in
[`hello_world_attest_fn_call/main.go`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_attest_fn_call/main.go))
has been signed by the enclave attested application public key of the Blocky AS
server and parse out the attested function output.
The contract uses the Blocky-provided
[`lib/TAParserLib.sol`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/lib/TAParserLib.sol)
library, which offers several utility functions.

The `processTransitivelyAttestedHelloWorldOutput` function takes two arguments
`applicationPublicKey` and `transitiveAttestation`. The first is an enclave
attested application public key of a Blocky AS server. The second is the
transitive attestation created on the same server. The
`processTransitivelyAttestedHelloWorldOutput` function has four steps. First it
calls `TAParserLib.publicKeyToAddress`, to convert a public key to an Ethereum
address. Second, the function calls
`TAParserLib.verifyTransitivelyAttestedFnCall` to verify that the attestation
was signed by the expected server and parse the claims of the attestation.
Third, the function prints the `claims` to the console. Fourth, the function
emits an `AttestedFunctionCallOutput` event with the `Output` field of the
`claims`.

In practice, you may want to extend the
[`User`](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract `processTransitivelyAttestedHelloWorldOutput` function to do more than
just print the transitive attestation `claims` to the console. You may want to
add additional logic to verify the various `claims` fields to make sure that the
transitive attestation is over the function and inputs expected by your smart
contract. You may also take actions based on the output of the function to
trigger further smart contract logic.

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

To test the smart contract locally, we use the
[Hardhat](https://hardhat.org/) framework.
We define the `"Local Test"` in
[test/user.ts](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/test/user.ts)
that loads
[inputs/out.json](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/inputs/out.json),
calls the `setTASigningKeyAddress`
and `verifyAttestedFnCallClaims` functions on the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract, and checks that the contract emits the `AttestedFunctionCallOutput`
event with `"Hello, World!"` as input. You will see the output:


```
  Local Test
Verified attest-fn-call claims:
        Function: helloWorld
        Hash of code: 98a384a2ca617e966d214794da3dbf75845d760056e50220d17589f31723ce496d6206d6e63a52ea14a1bbc21e67b2cb7de9d9036138fbaefebb250e39203fa6
        Hash of input: a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
        Hash of secrets: 9375447cd5307bf7473b8200f039b60a3be491282f852df9f42ce31a8a43f6f8e916c4f8264e7d233add48746a40166eec588be8b7b9b16a5eb698d4c3b06e00
        Output: Hello, World!
    ✔ Verify TA (760ms)
```

### Step 4: Deploy the Smart Contract to Base Sepolia

You can also deploy the [User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract to Base Sepolia testnet. To do so, we need to do a bit more setup:

- Create a wallet and fund it with Base Sepolia ETH.
  - If you'd like to user Metamask as your wallet, you can follow this
[guide](https://getblock.io/blog/add-base-sepolia-testnet-metamask/)
to configure it with Base Sepolia.
  - To fund your wallet, you can tap on of the Base Sepolia faucets listed in
[Base Sepolia documentation](https://docs.base.org/chain/network-faucets).
- Set your wallet's private key in the
[.env](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/.env)
file under `WALLET_KEY`.
- Get a
[Basescan API key](https://docs.basescan.org/getting-started/viewing-api-usage-statistics#creating-an-api-key)
- Set your Basescan API key in the
[.env](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/.env)
file under `BASESCAN_KEY`.


> Now you are ready to deploy and test the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract on Base Sepolia. However, you can skip this step and go directly to
[Step 5](#step-5-test-the-user-contract-on-base-sepolia) to test the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract on Base Sepolia using deployed contract address in the
[deployments/user_deployed_address](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/deployments/user_deployed_address)
file.


To deploy the smart contract, call:


```bash
make deploy-base-sepolia
```

Notice the output of the command similar to:


```
Successfully verified contract User on the block explorer.
https://sepolia.basescan.org/address/0x2b86E71C075A8D9e06C9feD887C865a7e91ad7cd#code
```

which includes a link to the
[deployed `User` contract on Basescan](https://sepolia.basescan.org/address/0x2b86E71C075A8D9e06C9feD887C865a7e91ad7cd).

### Step 5: Test the `User` contract on Base Sepolia

To test the [User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract on Base Sepolia, call:


```bash
make test-base-sepolia
```

which will invoke the `"Base Sepolia Tests"` in
[test/user.ts](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/test/user.ts).
You will see the test output similar to:


```
  Base Sepolia Tests
    ✔ Set signing key (5510ms)
    ✔ Verify TA (2174ms)
```

which show that the
[User](https://github.com/blocky/attestation-service-examples/tree/release/v0.1.0-beta.8/hello_world_on_chain/contracts/User.sol)
contract was able to verify the TA in just over 2 seconds. If you go to Basescan
to see
[contract transaction logs](https://sepolia.basescan.org/tx/0xc772e294541b5a572e06b9a7ce96073f734cc1424e56ba69620124d4dc669d44#eventlog)
you can see that the `verifyAttestedFnCallClaims` emitted the
`AttestedFunctionCallOutput` event containing the expected `"Hello, World!"`
WASM function output.

![Transaction Logs](/assets/transaction_logs.15de770950c197413168ec2fe737fb96e827a11b185d9b21d6322b1f248133b1.39e48bf5.png)