Skip to content

Commit

Permalink
Merge pull request #315 from neonlabsorg/main
Browse files Browse the repository at this point in the history
Added Subsquid SDK integration example
Added smart contract code compatibility checklist document
Added --skip-simulation parameter information to the Foundry pages
Added verification of contract pages with Hardhat, Foundry and Manually
  • Loading branch information
vodolaz authored Apr 16, 2024
2 parents a52d783 + 72b8119 commit 3994348
Show file tree
Hide file tree
Showing 25 changed files with 738 additions and 15 deletions.
30 changes: 23 additions & 7 deletions docs/developing/deploy_facilities/configure_foundry.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Configure Foundry"
title: 'Configure Foundry'
proofedDate: 20231116
iterationBy: na
includedInSite: true
Expand All @@ -14,11 +14,27 @@ Foundry is a blazing fast, portable,modular toolkit for Ethereum application dev
This page details several parameters required to configure Foundry. The Foundry framework isn't described here; find that in the [Foundry documentation](https://book.getfoundry.sh).

## Prerequisites

- cURL

## Foundry configuration

Unlike other toolkits, Foundry doesn't have a config file to hold the chain parameters, instead, parameters are passed into commands. For example, this command deploys a smart contract:
Unlike other toolkits, Foundry doesn't have a config file to hold the chain parameters, instead, parameters are passed into commands.

1. The following command deploys a contract using a script:

```
forge script script/TestERC20/DeployTestERC20.s.sol:DeployTestERC20Script --broadcast --rpc-url $RPC_URL_DEVNET --legacy --skip-simulation
```

The parameters for `forge script` command include:

- `--rpc-url`: RPC URL
- `--skip-simulation`: This parameter skips the on-chain simulation which doesn't work on Neon EVM.
- `--broadcast`: This parameter broadcasts the transaction.
- `--legacy`: This parameter is being passed to use legacy transactions _(Neon EVM currently [doesn't support EIP-1559 transactions](/docs/evm_compatibility/overview#shared-standards-and-features))_

2. The following command deploys a contract directly without a script:

```
forge create --rpc-url $RPC_URL_DEVNET \
Expand All @@ -28,10 +44,10 @@ src/TestERC20/TestERC20.sol:TestERC20
```

The parameters for `forge create` command include:
* `--rpc-url`: RPC URL
* `--private-key`: The private key of the transaction signer
* `--constructor-args`: The constructor arguments to be passed to the contract that is being deployed
* `--legacy`: This parameter is being passed to use legacy transactions _(Neon EVM currently [doesn't support EIP-1559 transactions](/docs/evm_compatibility/overview#shared-standards-and-features))_

- `--rpc-url`: RPC URL
- `--private-key`: The private key of the transaction signer
- `--constructor-args`: The constructor arguments to be passed to the contract that is being deployed
- `--legacy`: This parameter is being passed to use legacy transactions _(Neon EVM currently [doesn't support EIP-1559 transactions](/docs/evm_compatibility/overview#shared-standards-and-features))_

## What next? See the [tutorial on how to use Foundry](/docs/developing/deploy_facilities/using_foundry) to deploy to Neon EVM.
### What next? See the [tutorial on how to use Foundry](/docs/developing/deploy_facilities/using_foundry) to deploy on Neon EVM.
2 changes: 2 additions & 0 deletions docs/developing/deploy_facilities/using_foundry.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ Total Paid: 0.0034876870402 ETH (20000 gas * avg 174.38435201 gwei)
```
:::important
`--skip-simulation` parameter skips the on-chain simulation which doesn't work on Neon EVM.
The native token displayed above should be NEON instead of ETH and the unit should be Galan instead of gwei (It is not possible to customize the display).
:::
Expand Down
2 changes: 1 addition & 1 deletion docs/developing/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ neonmainnet: {
</TabItem>
</Tabs>

See the [Hardhat tutorial](https://docs.neonfoundation.io/docs/developing/deploy_facilities/configure_hardhat)
See the [Hardhat tutorial](/docs/developing/deploy_facilities/configure_hardhat)

<!-- todo find alt fix for Docusaurus issue with tabs -- links not rendering See the [Hardhat tutorial](/docs/deploy_facilities/configure_hardhat). -->

Expand Down
220 changes: 220 additions & 0 deletions docs/developing/integrate/indexer/subsquid.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
---
title: 'Subsquid SDK Integration'
proofedDate: N/A
includedInSite: false
approvedBy: na
description: Serves historical on-chain data, including event logs, transaction receipts, traces and per-transaction state diffs.
---

_This page presents an example of how SDK packages can be combined into a working indexer (called squid) on Neon EVM Devnet. This squid example tracks transfers of WNEON on Neon EVM Devnet, then save the resulting data to PostgreSQL and serve it as a GraphQL API._

# Introduction

[Subsquid Network](https://docs.subsquid.io/) is a decentralized query engine optimized for batch extraction of large volumes of data. It currently serves historical on-chain data ingested from 100+ EVM and Substrate networks, including event logs, transaction receipts, traces and per-transaction state diffs.

Here's an example of how SDK packages can be combined into a working indexer (called squid). This example uses [WNEON contract](https://devnet.neonscan.org/address/0x11adc2d986e334137b9ad0a0f290771f31e9517f).

## Prerequisites

- NodeJS 16.x or newer
- Docker

## How to run a squid on Neon EVM Devnet

### Step 1: Initialize a node project

Create an empty project directory and navigate to it and run:

```sh
npm init
```

### Step 2: Install dependencies

```sh
npm i @subsquid/evm-processor @subsquid/typeorm-store @subsquid/typeorm-migration @subsquid/graphql-server

npm i typescript @subsquid/typeorm-codegen @subsquid/evm-typegen @@subsquid/util-internal-validation --save-dev
```

### Step 3: Add `tsconfig.json` to the project's root directory

```sh
{
"compilerOptions": {
"rootDir": "src",
"outDir": "lib",
"module": "commonjs",
"target": "es2020",
"esModuleInterop": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
```

### Step 4: Define the schema for both the database and the core GraphQL API in `schema.graphql` in the project's root directory

```sh
type Transfer @entity {
id: ID!
src: String! @index
dst: String! @index
wad: BigInt!
}
```

### Step 5: Generate TypeORM classes based on the schema

```sh
npx squid-typeorm-codegen
```

The TypeORM classes will be available at `src/model/index.ts`.

### Step 6: Prepare the database

6.1 Create `.env` file in the project's root directory and paste the following lines -

```sh
DB_NAME=squid
DB_PORT=23798
RPC_NEON_HTTP=https://devnet.neonevm.org
GQL_PORT=4350
```

6.2 Create `docker-compose.yaml` file in the project's root directory and paste the following lines -

```sh
version: "3"
services:
db:
image: postgres:15
environment:
POSTGRES_DB: "${DB_NAME}"
POSTGRES_PASSWORD: postgres
ports:
- "${DB_PORT}:5432"
```

6.3 Start the database container -

```sh
docker compose up -d
```

6.4 Compile the TypeORM classes -

```sh
npx tsc
```

6.5 Generate the migration file -

```sh
npx squid-typeorm-migration generate
```

6.6 Apply the migration with -

```sh
npx squid-typeorm-migration apply
```

### Step 7: Generate utility classes for decoding WNEON contract data based on its ABI

7.1 Create a folder named `abi` under `src` (`src/abi`).

7.2 Create `wneon.json` file under `src/abi` (`src/abi/wneon.json`) and paste the contracts's ABI (https://devnet.neonscan.org/address/0x11adc2d986e334137b9ad0a0f290771f31e9517f#contract) into it.

7.3 Run -

```sh
npx squid-evm-typegen src/abi ./src/abi/wneon.json
```

The utility classes will be available at src/abi/wneon.ts.

### Step 8: Create an executable file `main.ts` under `src` folder (`src/main.ts`)

Paste the following lines of code into `main.ts` -

```sh
import { EvmBatchProcessor } from "@subsquid/evm-processor";
import { TypeormDatabase } from "@subsquid/typeorm-store";
import * as wneonAbi from "./abi/wneon";
import { Transfer } from "./model";

const processor = new EvmBatchProcessor()
.setGateway("https://v2.archive.subsquid.io/network/neon-devnet")
.setRpcEndpoint({
// set RPC endpoint in .env
url: process.env.RPC_NEON_HTTP,
//rateLimit: 10,
})
.setBlockRange({ from: 177455580 }) // Neon EVM Devnet genesis block
.setFinalityConfirmation(75) // 15 mins to finality
.addLog({
address: ["0x11adC2d986E334137b9ad0a0F290771F31e9517F"], // WNEON contract address on Neon EVM Devnet
topic0: [wneonAbi.events.Transfer.topic],
});

const db = new TypeormDatabase();

processor.run(db, async (ctx) => {
const transfers: Transfer[] = [];
for (let block of ctx.blocks) {
for (let log of block.logs) {
let { src, dst, wad } = wneonAbi.events.Transfer.decode(log);
transfers.push(
new Transfer({
id: log.id,
src,
dst,
wad,
})
);
}
}
await ctx.store.insert(transfers);
});
```
### Step 9: Compile the project and start the processor process
```sh
npx tsc
```
```sh
node -r dotenv/config lib/main.js
```
### Step 10: Start the GraphQL server
In a separate terminal, run the graphql server -
```sh
npx squid-graphql-server
```
The finished GraphQL API with GraphiQL will be available at localhost:4350/graphql.
:::info
Please follow the quick start github tutorial _[Subsquid SDK Example](https://github.com/neonlabsorg/neon-tutorials/tree/main/subsquid)_.
:::
## Changes needed to run a squid on Neon EVM Mainnet
To run a squid on Neon EVM Mainnet, there needs to be some changes to some of the above mentioned steps.
1. Replace `RPC_NEON_HTTP=https://devnet.neonevm.org` to `RPC_NEON_HTTP=https://neon-proxy-mainnet.solana.p2p.org` in the `.env` file in **Step 6.1**
2. Get the WNEON contract's ABI from the mainnet (https://neonscan.org/address/0x202c35e517fa803b537565c40f0a6965d7204609#contract) in **Step 7.2**
3. In **Step 8**, change to the following in the `src/main.ts` file:
- `setGateway("https://v2.archive.subsquid.io/network/neon-mainnet")`
- `setBlockRange({ from: 195350522 })` (Neon EVM Mainnet genesis block)
- `address: ["0x202c35e517fa803b537565c40f0a6965d7204609"]` (WNEON contract address on Neon EVM Mainnet)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions docs/developing/verify_facilities/using_foundry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: Verify smart contracts with Foundry
proofedDate: na
iterationBy: na
includedInSite: true
approvedBy: na
comment:
---

_This page outlines the steps for verifying contracts on Neon EVM using the Foundry tool._

This tutorial is based on the example located in [this repository](https://github.com/neonlabsorg/neon-tutorials/tree/main/foundry).

:::info
Foundry doesn't support custom explorers and only support Blockscout, Sourcify and Etherscan.
:::

By the end of this tutorial, you will learn to verify a contract that deploys an ERC-20 token to Neon EVM Devnet on Blockscout explorer.

## Step 1: Configure `.env`

Create a `.env` file in the project's root directory to feed in the required variables.

```sh
RPC_URL_DEVNET=https://devnet.neonevm.org
CHAIN_ID_DEVNET=245022926
RPC_URL_MAINNET=https://neon-proxy-mainnet.solana.p2p.org
CHAIN_ID_MAINNET=245022934
PRIVATE_KEY=<YOUR_PRIVATE_KEY>
VERIFIER_URL_BLOCKSCOUT=https://neon-devnet.blockscout.com/api
```

Run `source .env` to save the .env variables.

## Step 2: Deploy the contract

To deploy a contract, please follow this page describing [how to deploy contracts with Foundry](https://docs.neonevm.org/docs/developing/deploy_facilities/using_foundry).

## Step 3: Verify the deployed contract

To verify the deployed contract from the above step, let's take an example of a deployed contract with address `0x93adb347065949a90a7f2e198f94c2fadeb7dbbd` on Neon EVM Devnet.

After running the following command to verify -

```sh
forge verify-contract --chain-id $CHAIN_ID_DEVNET 0x93adb347065949a90a7f2e198f94c2fadeb7dbbd src/TestERC20/TestERC20.sol:TestERC20 --verifier-url $VERIFIER_URL_BLOCKSCOUT --verifier blockscout
```

The output should look like this -

```sh
Start verifying contract `0x93Adb347065949a90a7f2e198F94c2FADeb7dBbd` deployed on 245022926

Submitting verification for [src/TestERC20/TestERC20.sol:TestERC20] "0x93Adb347065949a90a7f2e198F94c2FADeb7dBbd".
Submitted contract for verification:
Response: `OK`
GUID: `93adb347065949a90a7f2e198f94c2fadeb7dbbd661584d8`
URL:
https://neon-devnet.blockscout.com/api?/address/0x93adb347065949a90a7f2e198f94c2fadeb7dbbd
```

The verified contract source code can be found here https://neon-devnet.blockscout.com/address/0x93Adb347065949a90a7f2e198F94c2FADeb7dBbd?tab=contract.

:::important
If the deployed contract consists of constructor arguments to be passed, then the constructor arguments are ABI-encoded. For example -

```sh
forge verify-contract --chain-id $CHAIN_ID_DEVNET 0x93adb347065949a90a7f2e198f94c2fadeb7dbbd src/TestERC20/TestERC20.sol:TestERC20 --verifier-url $VERIFIER_URL_BLOCKSCOUT --verifier blockscout --constructor-args $(cast abi-encode "constructor(string,string)" "TestToken" "TEST")
```

:::

:::info
If you want to verify on NeonScan, then please follow this page which describes the steps **[to verify smart contracts manually on NeonScan](verify_manually.md)**
:::
Loading

0 comments on commit 3994348

Please sign in to comment.