🫂Connect Airstack Phat Contract to EVM Consumer Contract

In the previous section we described how the Airstack Starter Kit works. Let's revisit the diagram and description below.

The diagram above displays the user journey of (1) Alice requesting a trust score for Eve from the EVM Consumer Contract. When (2) a new action request is added to the queue, (3) the Phala Network Phat Contract will pop the action off the queue and perform the off-chain work to compute a trust score.

First (4) the Phat Contract will create a batchHttpRequest to query 3 separate subgraph endpoints to determine if Eve has transacted on-chain with Alice, has a Lens Profile, has a Farcaster account, has a primary ENS Domain, and if Alice & Eve have common POAPs. Once this data is returned then (5) the Phat Contract will compute a score based on some scoring criteria. You can view the code here. Lastly, (6) the trust score for Eve has been returned to the EVM Consumer Contract and Eve's score is set in the Consumer Contract's storage for anyone to query.

Getting Started

If you have not setup Airstack code repo locally, go back to the Quick Start section and follow the initial setup steps.

Before Deployment

Before deploying, you will need to either export your Phala Account via polkadot.js extension or store your private key in the .env (optionally you can manually enter during deployment as well).

Option 1: Export Polkadot account as json file

Go to your browser and click on the polkadot.js extension. Select your account and click "Export Account". Next, you will be prompted for your password before saving the file to your project directory. Note this is what will be set to POLKADOT_WALLET_ACCOUNT_PASSPHRASE. Make sure to save the file as polkadot-account.json in the root of your project directory.

Option 2: Set mnemonic phrase to POLKADOT_WALLET_SURI

After creating your Phala Profile, set your .env variable POLKADOT_WALLET_SURI to the mnemonic phrase from generating the new Polkadot Account.

Here is a screenshot of how to set POLKADOT_WALLET_SURI:

Deployments (Local, Testnet, Mainnet)

This guide will be separated into 3 tabs including:

  • Local: Local Testnet Deployment

  • Testnet: PoC6 Testnet & EVM Chain Testnet Deployment

  • Mainnet: Phala Mainnet & EVM Chain Mainnet Deployment

Secrets (What are Secrets?):

  • apiUrl - The endpoint base URL to the separate subgraph endpoints hosted on Airstack

  • apiKey - an API key created on Airstack

{
    "apiUrl": "https://api.airstack.xyz/gql",
    "apiKey": "3a41775a358a4cb99ca9a29c1f6fc486"
}

In the previous Quick Start section, we installed the dependencies and ran 2 separate tests locally, but these tests were not run against a live local testnet.

This section will describe the process of:

  • Start up a local hardhat node

  • Deploy the EVM Consumer Contract to the local testnet

  • Run the @phala/fn watch command to run a local instance of the Airstack Phat Contract

  • Simulate a sample request by executing npm run localhost-push-request

  • See the Airstack Phat Contract reply with a result to the EVM Consumer Contract

Testing Locally

First step is to install the package dependencies with the following command:

npm install

With all the dependencies installed, we are ready to build Airstack Phat Contract.

npx @phala/fn build

To simulate the expected result locally, run the Phat Contract script now with this command:

Use decode and encode playground at https://playground.ethers.org.

npx @phala/fn run dist/index.js -a 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000de1683287529b9b4c3132af8aad210644b259cfd '{"apiUrl": "https://gateway.thegraph.com/api/", "apiKey": "cd22a01e5b7f9828cddcb52caf03ee79"}'

Here is the expected output of this call where the encoded call will request a trust score result for the address hashwarlock.eth. The result is 16.

npx @phala/fn run dist/index.js -a 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb000000000000000000000000eaf55242a90bb3289db8184772b0b98562053559 '{"apiUrl": "https://api.airstack.xyz/gql", "apiKey": "3a41775a358a4cb99ca9a29c1f6fc486"}' 

handle req: 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb000000000000000000000000eaf55242a90bb3289db8184772b0b98562053559
[1]: 0x964256674E42D61f0fF84097E28f65311786ccB0 0xeaf55242a90bb3289dB8184772b0B98562053559
Request received for profile 0x964256674E42D61f0fF84097E28f65311786ccB0 0xeaf55242a90bb3289dB8184772b0B98562053559
Tokens Sent on ETH Check... Result [0]
Tokens Sent on ETH Check... Result [0]
Lens Profile Check... Result [7]
Farcaster Account Check... Result [14]
Primary ENS Account. Result [24]
Common POAPs Check... Result[24]
response: 0,1,0x964256674E42D61f0fF84097E28f65311786ccB0,24
{"output":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb00000000000000000000000000000000000000000000000000000000000000018"}

Deploy a Local Hardhat Node

Now that we have a simple understanding of the expected functionality of the Phat Contract, we can now take our tests to a local testnet. Here we will use Hardhat to deploy the EVM Consumer Contract then listen from new action requests and reply with built Phat Contract script.

First we will start a local hardhat node.

npm run localhost-node

With our hardhat node running locally, we can now deploy the OracleConsumerContract.sol contract to the local hardhat network.

npm run localhost-deploy
npm run localhost-deploy
> the-graph-phat-contract@1.0.0 localhost-deploy
> hardhat run --network localhost ./scripts/localhost/deploy.ts

Compiled 18 Solidity files successfully (evm target: london).
Deploying...
Deployed { consumer: '0x5FbDB2315678afecb367f032d93F642f64180aa3' }

Make sure to copy the deployed contract address when you deploy your own contract locally. Note you contract address will be different than 0x5FbDB2315678afecb367f032d93F642f64180aa3. We will now start watching the hardhat node deployed contract for any new requests from Airstack Phat Contract.

npx @phala/fn watch 0x5FbDB2315678afecb367f032d93F642f64180aa3 artifacts/contracts/OracleConsumerContract.sol/OracleConsumerContract.json dist/index.js -a '{"apiUrl": "https://api.airstack.xyz/gql", "apiKey": "3a41775a358a4cb99ca9a29c1f6fc486"}'
npx @phala/fn watch 0x5FbDB2315678afecb367f032d93F642f64180aa3 artifacts/contracts/OracleConsumerContract.sol/OracleConsumerContract.json dist/index.js -a '{"apiUrl": "https://api.airstack.xyz/gql", "apiKey": "3a41775a358a4cb99ca9a29c1f6fc486"}'
Listening for OracleConsumerContract MessageQueued events...

Let’s now make a new request and see what happens with the listener’s output. In separate tab, you will push a request with the following.

Note: The file can be edited here where you can change the target address.

LOCALHOST_CONSUMER_CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 npm run localhost-push-request
LOCALHOST_CONSUMER_CONTRACT_ADDRESS=0x5FbDB2315678afecb367f032d93F642f64180aa3 npm run localhost-push-request
> the-graph-phat-contract@1.0.0 localhost-push-request
> hardhat run --network localhost ./scripts/localhost/push-request.ts

Pushing a request...
Received event [ResponseReceived]: {
  reqId: BigNumber { value: "1" },
  target: '0x011c23b3AadAf3D4991f3aBeE262A34d18e9fdb5',
  value: BigNumber { value: "70" }
}

If you check back the tab where the Phat Contract is listening for new requests, the console log may look similar to below:

Received event [MessageQueued]: {
  tail: 0n,
  data: '0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb000000000000000000000000eaf55242a90bb3289db8184772b0b98562053559'
}
handle req: 0x0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb000000000000000000000000eaf55242a90bb3289db8184772b0b98562053559
[1]: 0x964256674E42D61f0fF84097E28f65311786ccB0 0xeaf55242a90bb3289dB8184772b0B98562053559
Request received for profile 0x964256674E42D61f0fF84097E28f65311786ccB0 0xeaf55242a90bb3289dB8184772b0B98562053559
Tokens Sent on ETH Check... Result [0]
Tokens Sent on ETH Check... Result [0]
Lens Profile Check... Result [7]
Farcaster Account Check... Result [14]
Primary ENS Account. Result [24]
Common POAPs Check... Result[24]
response: 0,1,0x964256674E42D61f0fF84097E28f65311786ccB0,24
JS Execution output: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000964256674e42d61f0ff84097e28f65311786ccb00000000000000000000000000000000000000000000000000000000000000018

🎉 Congratulations!

You've completed deploying and testing the Airstack Phat Contract successfully in a local testnet. Now let's move to deploying to an EVM Testnet and connecting a deployed Phat Contract on PoC6 Testnet to visualize how this works autonomously.

Last updated

Logo

COPYRIGHT © 2024 PHALA.LTD ALL RIGHTS RESERVED. May Phala be with you!