Skip to content

starter template leveraging chain fusion technology to build EVM coprocessors on the Internet Computer Protocol

License

Notifications You must be signed in to change notification settings

adrian-d-hidalgo/azle-chain-fusion-starter

Repository files navigation

Azle Chain Fusion Starter

hero3

Table of contents

Architecture

This starter project involves multiple canisters working together to process events emitted by EVM smart contracts. The main canisters are:

  • EVM Smart Contract: Emits events such as NewJob when specific functions are called. It also handles callbacks from the chain_fusion canister with the results of the processed jobs.
  • Chain Fusion Canister (chain_fusion): Listens to events emitted by the EVM smart contract, processes them, and sends the results back to the EVM smart contract.
  • EVM RPC Canister: Facilitates communication between the Internet Computer and EVM-based blockchains by making RPC calls to interact with the EVM smart contract.

The full flow of how these canisters interact can be found in the following sequence diagram:

EVM Smart Contract

The contracts/Coprocessor.sol contract emits a NewJob event when the newJob function is called, transferring ETH to the chain_fusion canister to pay it for job processing and transaction fees (this step is optional and can be customized to fit your use case).

// Function to create a new job
function newJob() public payable {
    // Require at least 0.01 ETH to be sent with the call
    require(msg.value >= 0.01 ether, "Minimum 0.01 ETH not met");

    // Forward the ETH received to the coprocessor address
    // to pay for the submission of the job result back to the EVM
    // contract.
    coprocessor.transfer(msg.value);

    // Emit the new job event
    emit NewJob(job_id);

    // Increment job counter
    job_id++;
}

The callback function writes processed results back to the contract:

function callback(string calldata _result, uint256 _job_id) public {
    require(
        msg.sender == coprocessor,
        "Only the coprocessor can call this function"
    );
    jobs[_job_id] = _result;
}

For local deployment, see the scripts/deploy.sh script and scripts/Coprocessor.s.sol.

Chain Fusion Canister

The chain_fusion canister listens to NewJob events by periodically calling the eth_getLogs RPC method via the EVM RPC canister. Upon receiving an event, it processes the job and sends the results back to the EVM smart contract via the EVM RPC canister, signing the transaction with threshold ECDSA.

The Job processing logic is in canisters/chain_fusion/services/job.service.ts:

private async process(event: Event, jobId: bigint): Promise<string> {
  // this calculation would likely exceed an ethereum blocks gas limit
  // but can easily be calculated on the IC
  const result = this.fibonacci(20);
  const service = new EtherRpcService(event.service);
  const coprocessor = new CoprocessorService(service, event.addresses);
  return coprocessor.callback(result.toString(), jobId);
}

Setup

In the cloud

TODO:

Locally

Ensure Docker and VS Code are installed and running, then click the button below:

TODO:

Manual setup

Ensure the following are installed on your system:

Run these commands in a new, empty project directory:

git clone https://github.com/adrian-d-hidalgo/azle-chain-fusion-starter.git
cd azle-chain-fusion-starter
npm install

Getting started

No matter what setup you pick from below, run npm run ic:start from the project root to deploy the project. To understand the steps involved in deploying the chain_fusion locally, examine the comments in scripts/ic/start.sh. This script will:

  • start icp local replica
  • deploy the evm_rpc
  • deploy the chain_fusion

Working with Foundry

For a local development you can use Foundry, run npm run foundry:start from the project root to start the needed services. To understand the steps involved in starting foundry services, examine the comments in scripts/foundry/start.sh. This script will:

  • start anvil
  • start caddy

Then to deploy the smartcontract run npm run foundry:deploy, examine the comments in scripts/foundry/deploy.sh to understand the steps involved. This script will:

  • deploy the EVM contract
  • generate a number of jobs

Now you can register an event listener:

// POST /events
{
  "network": {
    "name": "custom",
    "chainId": 31337,
    "services": [
      {
        "url": "https://localhost:8546"
      }
    ]
  },
  "events": {
    "topics": [["0x031ada964b8e520743eb9508d0ace62654b126430b7e5a92b42e78eebb61602e"]],
    "addresses": ["YOUR_CONTRACT_ADDRESS"]
  }
}

You can register one event lister per smart contract deployed.

If you want to check that the chain_fusion canister really processed the events, you can either look at the logs output by running npm run ic:start – keep an eye open for the Successfully ran job message – or you can call the EVM contract to get the results of the jobs. To do this, run:

npm run foundry:job:result --job-id=<job_id> --contract-address=<contract_address>

where <job_id> is the ID of the job you want to get the result for and <contract_address> is the Address given when the contract was deployed. This should always return "6765" for processed jobs, which is the 20th Fibonacci number, and "" for unprocessed jobs.

If you want to create more jobs, simply run:

npm run foundry:job:create --contract-address=<contract_address>

Development

All coprocessing logic lives in canisters/chain_fusion/services/job.service.ts. Developers can focus on writing jobs to process EVM smart contract events without altering the code for fetching events or sending transactions.

Note that the Chain Fusion Canister only scrapes logs every 3 minutes, so you may need to wait a few minutes before seeing the new job processed.

About

starter template leveraging chain fusion technology to build EVM coprocessors on the Internet Computer Protocol

Resources

License

Stars

Watchers

Forks

Packages

No packages published