Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/evm_block_explorer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: evm_block_explorer

on:
push:
branches: [master]
pull_request:
paths:
- rust/evm_block_explorer/**
- .github/workflows/evm_block_explorer.yml

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
rust-evm_block_explorer:
runs-on: ubuntu-24.04
container: ghcr.io/dfinity/icp-dev-env-rust:1.0.1
env:
ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: Deploy and test
working-directory: rust/evm_block_explorer
run: |
icp network start -d
icp deploy
bash test.sh
20 changes: 0 additions & 20 deletions rust/evm_block_explorer/.devcontainer/devcontainer.json

This file was deleted.

26 changes: 0 additions & 26 deletions rust/evm_block_explorer/BUILD.md

This file was deleted.

42 changes: 26 additions & 16 deletions rust/evm_block_explorer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@

## Overview

The EVM Block Explorer example demonstrates how an ICP smart contract can obtain information directly from other blockchain networks. Using HTTPS outcalls, smart contracts on ICP can interact with other networks without needing to go through a third-party service such as a bridge or an oracle. Supported interactions with other chains include querying network data, signing transactions, and submitting transactions directly to other networks.
In this example, you'll also see how to sign transactions with canister ECDSA or Schnorr signatures.
The EVM Block Explorer example demonstrates how an ICP canister can fetch block data directly from Ethereum and other EVM-compatible chains. Using HTTPS outcalls via the [EVM RPC canister](https://github.com/dfinity/evm-rpc-canister), canisters on ICP can read on-chain data without a bridge or oracle. The same pattern applies to any EVM-compatible chain supported by the EVM RPC canister.

<!--
## Deploying from ICP Ninja

This example can be deployed directly from [ICP Ninja](https://icp.ninja), a browser-based IDE for ICP. To continue developing locally after deploying from ICP Ninja, see [BUILD.md](BUILD.md).
This example can be deployed directly from [ICP Ninja](https://icp.ninja), a browser-based IDE for ICP.

[![Open in ICP Ninja](https://icp.ninja/assets/open.svg)](https://icp.ninja/i?g=https://github.com/dfinity/examples/rust/evm_block_explorer)

> **Note:** ICP Ninja currently uses `dfx` under the hood, which is why this example includes a `dfx.json` configuration file. `dfx` is the legacy CLI, being superseded by [icp-cli](https://cli.icp.build), which is what developers should use for local development.
-->

## Build and deploy from the command line

### Prerequisites

- [x] Install [Node.js](https://nodejs.org/en/download/)
- [x] Install [icp-cli](https://cli.icp.build): `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm`
- [Node.js](https://nodejs.org/) v18+
- [icp-cli](https://cli.internetcomputer.org/): `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm`
- [Rust](https://www.rust-lang.org/tools/install) with `wasm32-unknown-unknown` target: `rustup target add wasm32-unknown-unknown`

### Install

Expand All @@ -31,24 +31,29 @@ git clone https://github.com/dfinity/examples
cd examples/rust/evm_block_explorer
```

### Deployment
### Deploy and test

Start the local network:
Start the local network, deploy all canisters (including the local EVM RPC canister), and run the tests:

```bash
icp network start -d
icp deploy
bash test.sh
icp network stop
```

Deploy the canisters:
To start a frontend dev server with hot reload during frontend development:

```bash
icp deploy
npm run dev --prefix frontend
```

Stop the local network when done:
### Deploying on ICP mainnet

On mainnet, the `evm_rpc` canister is already deployed at `7hfb6-caaaa-aaaar-qadga-cai`. Deploy only the backend and frontend — icp-cli injects the correct canister ID via the `ic` environment configuration in `icp.yaml`:

```bash
icp network stop
icp deploy -e ic
```

## Updating the Candid interface
Expand All @@ -58,10 +63,15 @@ The `backend/backend.did` file defines the backend canister's public interface.
If you modify the backend's public API, rebuild the canister and regenerate the `.did` file:

```bash
icp build backend
candid-extractor target/wasm32-unknown-unknown/release/backend.wasm > backend/backend.did
icp build backend && candid-extractor target/wasm32-unknown-unknown/release/backend.wasm > backend/backend.did
```

## RPC providers and API keys

The example uses [PublicNode](https://ethereum-rpc.publicnode.com) by default — a free, no-registration provider that works out of the box locally and on mainnet. This is sufficient for getting started and automated testing.

For production deployments requiring premium providers (Alchemy, Ankr, BlockPi), refer to the [EVM RPC canister documentation](https://github.com/dfinity/evm-rpc-canister) for how to configure API keys. Once configured, change `RpcServices::EthMainnet(Some(vec![EthMainnetService::PublicNode]))` in `backend/src/lib.rs` to `RpcServices::EthMainnet(None)` to use all configured providers for better consensus.

## Security considerations and best practices

If you base your application on this example, it is recommended that you familiarize yourself with and adhere to the [security best practices](https://docs.internetcomputer.org/building-apps/security/overview) for developing on ICP. This example may not implement all the best practices.
If you base your application on this example, it is recommended that you familiarize yourself with and adhere to the [security best practices](https://docs.internetcomputer.org/guides/security/overview) for developing on ICP. This example may not implement all the best practices.
14 changes: 5 additions & 9 deletions rust/evm_block_explorer/backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
[package]
name = "backend"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
edition = "2024"

[lib]
crate-type = ["cdylib"]
path = "lib.rs"

[dependencies]
candid = "0.10.23"
evm-rpc-canister-types = "5.0.1"
hex = "0.4.3"
ic-cdk = "0.17.2"
ic0 = "1.0.1"
sha2 = "0.10.8"
evm_rpc_client = "0.4.0"
evm_rpc_types = "3.1.1"
ic-cdk = "0.20"
ic-canister-runtime = "0.2.0"
7 changes: 2 additions & 5 deletions rust/evm_block_explorer/backend/backend.did
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ type Block = record {
gasUsed : nat;
mixHash : text;
};
type Result = variant { Ok : Block; Err : text };
service : {
get_ecdsa_public_key : () -> (text);
get_evm_block : (nat) -> (Block);
get_schnorr_public_key : () -> (text);
sign_message_with_ecdsa : (text) -> (text);
sign_message_with_schnorr : (text) -> (text);
get_evm_block : (nat) -> (Result);
}
150 changes: 0 additions & 150 deletions rust/evm_block_explorer/backend/lib.rs

This file was deleted.

Loading
Loading