Monitoring
Verifying Contracts Using the Tenderly Hardhat Plugin

Verifying Contracts Using the Tenderly Hardhat Plugin

The Tenderly Hardhat plugin verifies contracts publicly by default, unless you configure it to use the private mode.

When it comes to the Tenderly Hardhat plugin, there are 3 ways to verify your Smart Contracts:

  • Automatic: The verification happens seamlessly just after the contract is deployed. You don’t have to take any additional steps.
  • Simple manual: You need to call the verification explicitly (tenderly.verify()), which requires you to pass a minimal configuration object: the name and the address.
  • Advanced manual: You must call the verification explicitly (tenderly.verifyMultiCompilerAPI()). This requires you to pass a very detailed configuration object: all the contracts involved, their source, the addresses they’re deployed at, all the libraries used, and Solidity compiler configuration.
💡

Whether using automatic or manual approach, verification can happen only after the contract deployment is confirmed. Calling the blocking waitForDeployment() method on the contract:

example.ts
let ctrct = await ethers.deployContract('Ctrct');
 
ctrct = await ctrct.waitForDeployment(); // hardhat-tenderly plugin verifies the contract
// if automatic, the contract is deployed
// if manual, paste the verification code here

Before starting the process of verification using one of these methods, you need to set up your development environment.

You can find a demo project on Git, showing different configuration options and possible ways to verify Smart Contracts.

Setting up the environment

To use a specific Tenderly contract verification method, you need a Hardhat project and a Tenderly API key.

tenderly login
  • Generate an API key in the Dashboard and place it in ~/.tenderly/config.yaml under access_key.

Installing the Tenderly Hardhat plugin

Once you set up your environment, install the Tenderly plugin for Hardhat:

example
npm install --save-dev @tenderly/hardhat-tenderly

Tenderly Hardhat plugin creates a deployments directory where it stores intermediary information about deployments. It's not necessary to keep it in VCS.

example
cat >> .gitignore <<EOF
 
 
# hardhat-tenderly plugin
deployments
EOF

After installing the Tenderly package, go to hardhat.config.js (or hardhat.config.ts if you’re using TypeScript), import the Tenderly Hardhat library and initialize the plugin by calling setup.

example.tsx
import * as tdly from '@tenderly/hardhat-tenderly';
tdly.setup();

Take a look at the complete Hardhat config file.

For now, remember it’s important to call tenderly.setup() so the plugin initializes. The plugin is in the automatic verification mode by default. In the case you wish to go for manual verification, pass a configuration argument:

example.tsx
tdly.setup({ automaticVerifications: false });

Next, you need to extend hardhat configuration with information about the project and your access data:

example.ts
//File:  hardhat.config.ts
//...
 
const config: HardhatUserConfig = {
  solidity: {...},
  networks: {...},
  tenderly: {
    project: 'my-project-slug',
    username: 'my-username'
  }

Replace the my-project-slug and my-username with appropriate values you can find in the dashboard.

Important - You must use tenderly as the network name if you want ethers to recognize Tenderly as a network. Tenderly Network Configuration

Using an example contract

The following examples use a simple contract automatically generated when you start a new Hardhat project - Greeter:

example.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.9;
 
import "hardhat/console.sol";
 
contract Greeter {
   string private greeting;
 
   constructor(string memory _greeting) {
       console.log("Deploying a Greeter with greeting:", _greeting);
       greeting = _greeting;
   }
 
   function greet() public view returns (string memory) {
       return greeting;
   }
 
   function setGreeting(string memory _greeting) public {
       console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
       greeting = _greeting;
   }
}