-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add examples/contract-verification/ethers-5 examples to the repo (#184)
This PR adds usage of `@tenderly/hardhat-tenderly` with the `ethers-5` structure project to `examples/contract-verification/ethers-5`.
- Loading branch information
Showing
55 changed files
with
7,153 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@tenderly/hardhat-tenderly": patch | ||
"tenderly": patch | ||
--- | ||
|
||
Added hardhat example project for ethers-5 and changed AUTOMATIC_POPULATE_HARDHAT_VERIFY_CONFIG to TENDERLY_AUTOMATIC_POPULATE_HARDHAT_VERIFY_CONFIG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
extends: [`${__dirname}/../../../config/eslint/eslintrc.js`], | ||
parserOptions: { | ||
project: `${__dirname}/tsconfig.json`, | ||
sourceType: "module" | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
# Hardhat + Tenderly Contract Verification | ||
|
||
This repo demonstrates deployment and verification of Smart Contracts in Tenderly platform, using: | ||
|
||
- **Tenderly Hardhat plugin** to perform verification using Ethers in several ways (automatic and manual). There are 18 different possibilities you can play around with. | ||
|
||
To learn more explore [Tenderly documentation](https://docs.tenderly.co/monitoring/smart-contract-verification). | ||
|
||
# The examples | ||
|
||
There are two example contracts (`Greeter` and `Calculator`). Their build scripts are located in: | ||
|
||
- `scripts/greeter/`, deploying the classical Greeter contract. | ||
- `scripts/calculator`, deploying `Calculator` and `Maths` - a library used by the contract. | ||
|
||
From these examples, you can learn: | ||
|
||
- How to verify a Smart Contract referencing a non-deployed library: Greeter uses **non-deployed** `hardhat/console.log`. | ||
- How to verify a Smart Contract referencing an library deployed on-chain: Calculator uses **deployed** `Maths.sol` library. | ||
|
||
# Environment setup | ||
|
||
This example requires some environment variables: | ||
|
||
- The **provider access** and **tenderly access** parameters should be placed in an .env file. | ||
- Run configuration should be set on per-run basis. This allows us to run the same deployment script in public and private mode or on a fork, without changing any code. These values are used only in `hardhat.config.ts`. See [Building and verifying](#building-and-verifying-greeter-and-environment-variables) section for more information. | ||
|
||
Run the following script to to get an `.env` file initialized with placeholders, necessary for running the examples: | ||
|
||
```bash | ||
cat tpl.env | ||
cp tpl.env .env | ||
``` | ||
|
||
To get going, run | ||
|
||
``` | ||
yarn install | ||
``` | ||
|
||
Try running automatic verification: | ||
|
||
```bash | ||
TENDERLY_AUTOMATIC_VERIFICATION=true \ | ||
hardhat run scripts/greeter/automatic.ts --network sepolia | ||
``` | ||
|
||
## Building and Verifying Greeter and environment variables | ||
|
||
The `/scripts/greeter` contains 4 deployment scripts that illustrate the 3 approaches of verification (automatic, manual simple, manual advanced) and verification of a contract deployed on a Tenderly Fork. The `scripts/calculator` example has the same structure. | ||
|
||
| Verification method | Script | | ||
| ---------------------- |--------------------------------------| | ||
| Automatic verification | `scripts/greeter/automatic.ts` | | ||
| Manual simple | `scripts/greeter/manual-simple.ts` | | ||
| Manual advanced | `scripts/greeter/manual-advanced.ts` | | ||
| Fork | `scripts/greeter/fork.ts` | | ||
|
||
For example, to run the automatic verification example, you have to run it with [`TENDERLY_AUTOMATIC_VERIFICATION`](#modes-of-verification-public-private-and-fork) variable: | ||
|
||
```bash | ||
TENDERLY_AUTOMATIC_VERIFICATION=true \ | ||
hardhat run scripts/greeter/automatic.ts --network sepolia | ||
``` | ||
|
||
And to run the manual simple with private verification, you would paste this: | ||
|
||
``` | ||
TENDERLY_PRIVATE_VERIFICATION=true \ | ||
TENDERLY_AUTOMATIC_VERIFICATION=false \ | ||
hardhat run scripts/greeter/manual-simple.ts --network sepolia | ||
``` | ||
|
||
Don't worry, we generated [Run scripts](#run-scripts) to speed things up. | ||
|
||
### Modes of verification: `public`, `private`, and `fork` | ||
|
||
- To easily switch between private and public verification use `TENDERLY_PRIVATE_VERIFICATION`. | ||
- Default: `false`, contracts are verified publicly. | ||
- To run a private verification set `TENDERLY_PRIVATE_VERIFICATION=true`. Any other value is considered not true. | ||
|
||
### Tenderly Plugin verification approaches: automatic and manual | ||
|
||
- Tenderly Hardhat plugin runs with automatic verifications **enabled by default** unless explicitly configured otherwise. | ||
- To control if you're automatic or manual verification, use `TENDERLY_AUTOMATIC_VERIFICATION`. | ||
- By default, the `TENDERLY_AUTOMATIC_VERIFICATION` will not be set, so the automatic verification won't be turned on. | ||
- To run an automatic verification set `TENDERLY_AUTOMATIC_VERIFICATION=true` | ||
|
||
## Run scripts | ||
|
||
The pre-populated (generated) scripts in package.json are there to help you quickly run a particular build (out of 18 possibilities), so you don't need to specify environment variables and the target deployment script every time you're trying stuff out. | ||
|
||
You can choose | ||
|
||
| category | Meaning | options | | ||
| --------- | -------------------------------------- | ----------------------------------------------- | | ||
| `example` | Smart contract to verify | `greeter`, `calculator` | | ||
| `mode` | In one of 3 modes of verification | `public`, `private`, `fork` | | ||
| `method` | Using one of 3 methods of verification | `automatic`, `manual-simple`, `manual-advanced` | | ||
|
||
To run `private` verification of the `Greeter` using `manual-simple` method, you need to run the following: | ||
|
||
``` | ||
yarn run private:greeter:manual-simple --network sepolia | ||
yarn run fork:calculator:manual-advanced --network tenderly | ||
``` |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
39 changes: 39 additions & 0 deletions
39
examples/contract-verification/ethers-v5/hardhat.config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import * as dotenv from "dotenv"; | ||
import { HardhatUserConfig } from "hardhat/types/config"; | ||
|
||
import "@nomicfoundation/hardhat-toolbox"; | ||
import * as tdly from "@tenderly/hardhat-tenderly"; | ||
|
||
dotenv.config(); | ||
|
||
const { TENDERLY_PRIVATE_VERIFICATION, TENDERLY_AUTOMATIC_VERIFICATION } = | ||
process.env; | ||
|
||
const privateVerification = TENDERLY_PRIVATE_VERIFICATION === "true"; | ||
const automaticVerifications = TENDERLY_AUTOMATIC_VERIFICATION === "true"; | ||
|
||
tdly.setup({ automaticVerifications }); | ||
|
||
console.log("Using private verification?", privateVerification); | ||
console.log("Using automatic verification?", automaticVerifications); | ||
|
||
const config: HardhatUserConfig = { | ||
solidity: "0.8.23", | ||
networks: { | ||
tenderly: { | ||
url: `${process.env.TENDERLY_FORK_RPC_URL ?? ""}`, | ||
}, | ||
sepolia: { | ||
url: `${process.env.SEPOLIA_URL ?? ""}`, | ||
accounts: [process.env.SEPOLIA_PRIVATE_KEY ?? ""], | ||
}, | ||
}, | ||
tenderly: { | ||
project: process.env.TENDERLY_PROJECT ?? "", | ||
username: process.env.TENDERLY_USERNAME ?? "", | ||
privateVerification, | ||
}, | ||
}; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
{ | ||
"name": "hardhat-project", | ||
"license": "SEE LICENSE IN LICENSE", | ||
"files": [ | ||
"LICENSE" | ||
], | ||
"scripts": { | ||
"lint:fix": "yarn run prettier --write && yarn run eslint --fix", | ||
"eslint": "eslint 'scripts/**/*.ts'", | ||
"prettier": "prettier \"**/*.{js,md,json}\"", | ||
"build": "tsc -b", | ||
"public:greeter:automatic": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/greeter/automatic.ts", | ||
"public:greeter:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-simple.ts", | ||
"public:greeter:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-advanced.ts", | ||
"public:calculator:automatic": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/calculator/automatic.ts", | ||
"public:calculator:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-simple.ts", | ||
"public:calculator:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-advanced.ts", | ||
"private:greeter:automatic": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/greeter/automatic.ts", | ||
"private:greeter:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-simple.ts", | ||
"private:greeter:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-advanced.ts", | ||
"private:calculator:automatic": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/calculator/automatic.ts", | ||
"private:calculator:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-simple.ts", | ||
"private:calculator:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=true TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-advanced.ts", | ||
"fork:greeter:automatic": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/greeter/automatic.ts", | ||
"fork:greeter:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-simple.ts", | ||
"fork:greeter:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/greeter/manual-advanced-fork.ts", | ||
"fork:calculator:automatic": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=true npx hardhat run scripts/calculator/automatic.ts", | ||
"fork:calculator:manual-simple": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-simple.ts", | ||
"fork:calculator:manual-advanced": "TENDERLY_PRIVATE_VERIFICATION=false TENDERLY_AUTOMATIC_VERIFICATION=false npx hardhat run scripts/calculator/manual-advanced-fork.ts" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.5.7", | ||
"@typescript-eslint/eslint-plugin": "^5.36.1", | ||
"@typescript-eslint/parser": "^5.36.1", | ||
"eslint": "^8.23.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-import": "^2.26.0", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"prettier": "^2.7.1", | ||
"ts-node": "^10.9.1" | ||
}, | ||
"dependencies": { | ||
"@ethersproject/abi": "5.7.0", | ||
"@ethersproject/providers": "^5.7.2", | ||
"@nomicfoundation/hardhat-chai-matchers": "^1.0.0", | ||
"@nomicfoundation/hardhat-network-helpers": "^1.0.0", | ||
"@nomicfoundation/hardhat-toolbox": "^2.0.0", | ||
"@nomiclabs/hardhat-ethers": "^2.0.0", | ||
"@nomiclabs/hardhat-etherscan": "^3.1.8", | ||
"@tenderly/hardhat-tenderly": "^1.8.0", | ||
"@typechain/ethers-v5": "^10.2.1", | ||
"@typechain/hardhat": "^6.1.6", | ||
"@types/chai": "^4.2.0", | ||
"@types/mocha": ">=9.1.0", | ||
"chai": "^4.2.0", | ||
"dotenv": "^16.0.1", | ||
"ethers": "^5.7.2", | ||
"global": "^4.4.0", | ||
"global-tunnel-ng": "^2.7.1", | ||
"hardhat": "^2.19.0", | ||
"hardhat-gas-reporter": "^1.0.8", | ||
"solidity-coverage": "^0.8.1", | ||
"typechain": "^8.3.0" | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
32 changes: 32 additions & 0 deletions
32
examples/contract-verification/ethers-v5/scripts/calculator/maths-deployment-ethers.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// File: scripts/maths/maths-deployment-ethers.ts | ||
import { ethers } from "hardhat"; | ||
|
||
export async function deployMaths() { | ||
console.log("📐[ethers] Deploying Maths library"); | ||
|
||
const Maths = await ethers.getContractFactory("Maths"); | ||
let maths = await Maths.deploy(); | ||
maths = await maths.deployed(); | ||
|
||
console.log("📐[ethers] {Maths} deployed to", await maths.address); | ||
|
||
return maths.address; | ||
} | ||
|
||
export async function deployCalculator(mathsAddress: string) { | ||
console.log("🧮[ethers] Deploying Calculator smart contract"); | ||
const Calculator = await ethers.getContractFactory("Calculator", { | ||
libraries: { | ||
Maths: mathsAddress, | ||
}, | ||
}); | ||
|
||
let calculator = await Calculator.deploy(); | ||
calculator = await calculator.deployed(); | ||
|
||
console.log( | ||
"🧮[ethers] {Calculator} deployed to", | ||
await calculator.address, | ||
); | ||
return calculator.address; | ||
} |
19 changes: 19 additions & 0 deletions
19
examples/contract-verification/ethers-v5/scripts/greeter/automatic.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// File: scripts/greeter/automatic.ts | ||
import { ethers } from "hardhat"; | ||
|
||
export async function main() { | ||
console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly"); | ||
|
||
const Greeter = await ethers.getContractFactory("Greeter"); | ||
let greeter = await Greeter.deploy("Hello, Hardhat!"); | ||
|
||
greeter = await greeter.deployed(); | ||
|
||
const greeterAddress = await greeter.address; | ||
console.log("{Greeter} deployed to", greeterAddress); | ||
} | ||
|
||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
64 changes: 64 additions & 0 deletions
64
examples/contract-verification/ethers-v5/scripts/greeter/manual-advanced-fork.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { readFileSync } from "fs"; | ||
import { network, ethers, tenderly } from "hardhat"; | ||
import { HttpNetworkConfig } from "hardhat/types"; | ||
|
||
export async function main() { | ||
const forkID = | ||
`${(network.config as HttpNetworkConfig).url}`.split("/").pop() ?? ""; | ||
|
||
console.log("🖖🏽[ethers] Deploying and Verifying Greeter in Tenderly"); | ||
|
||
const Greeter = await ethers.getContractFactory("Greeter"); | ||
let greeter = await Greeter.deploy("Hello, Manual Hardhat on Fork !"); | ||
greeter = await greeter.deployed(); | ||
|
||
const greeterAddress = await greeter.address; | ||
console.log("Manual Advanced (fork): {Greeter} deployed to", greeterAddress); | ||
|
||
await tenderly.verifyForkMultiCompilerAPI( | ||
{ | ||
contracts: [ | ||
{ | ||
contractToVerify: "Greeter", | ||
sources: { | ||
"contracts/Greeter.sol": { | ||
name: "Greeter", | ||
code: readFileSync("contracts/Greeter.sol", "utf-8").toString(), | ||
}, | ||
"hardhat/console.sol": { | ||
name: "console", | ||
code: readFileSync( | ||
"node_modules/hardhat/console.sol", | ||
"utf-8", | ||
).toString(), | ||
}, | ||
}, | ||
// solidity format compiler with a little modification at libraries param | ||
compiler: { | ||
version: "0.8.23", | ||
settings: { | ||
optimizer: { | ||
enabled: false, | ||
runs: 200, | ||
}, | ||
evmVersion: "paris", | ||
}, | ||
}, | ||
networks: { | ||
[forkID]: { | ||
address: greeterAddress, | ||
}, | ||
}, | ||
}, | ||
], | ||
}, | ||
process.env.TENDERLY_PROJECT ?? "", | ||
process.env.TENDERLY_USERNAME ?? "", | ||
forkID, | ||
); | ||
} | ||
|
||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |
Oops, something went wrong.