Foundry Contract Verification
Foundry is a smart contract development toolchain. Foundry’s command line tool Forge tests, builds, and deploys smart contracts.
Tenderly can verify smart contracts deployed with Foundry’s commands forge create
, forge script
or forge verify-contract
. You can even use Tenderly’s development infrastructure and tools in conjunction with Foundry tooling.
Use the --slow
flag when running Foundry scripts to prevent transaction batching. With this, a transaction is sent only after it’s preceding transaction is confirmed.
Verification URL
All Foundry commands that support verification require the --verification-url
argument. You need to give it an Etherscan-compliant URL.
In this section you can find formats for verifier URLs on:
- Forks
- DevNets
- TestNets
- Public networks (mainnets and testnets)
Verification on Tenderly development infrastructure
Tenderly development, staging, and testing infrastructure - Forks, DevNets, and TestNets, expose an RPC URL for access. You get the Etherscan-compliant verification URL by:
- adding
/verify/etherscan
to the URL, - replacing the
$TENDERLY_ACCOUNT
and$TENDERLY_PROJECT
with the settings from your account. Follow this guide, - adhering to the following formats, depending on the technology you’re using:
## For TestNets
VERIFIER_URL=$TENDERLY_VIRTUAL_TESTNET_RPC/verify/etherscan
## For DevNets
VERIFIER_URL=https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/devnet/<resourceId>
## For Forks
VERIFIER_URL=https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/fork/<resourceId>
Examples:
## TestNets
https://virtual.base.rpc.tenderly.co/872ac073-1de1-4422-b01d-8d057781d77d/verify/etherscan
## For DevNets
## https://rpc.vnet.tenderly.co/devnet/test/c6a552cd-3064-4e95-9fb3-8cee2e317296/
https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/devnet/c6a552cd-3064-4e95-9fb3-8cee2e317296/
## Forks
## Fork RPC: https://rpc.tenderly.co/fork/68cc4cd5-2a3b-441a-afbb-4dea745a22c2
https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/fork/68cc4cd5-2a3b-441a-afbb-4dea745a22c2
Verification on public networks
When verifying on private or public networks, use appropriate verifier URL. To verify publicly, your URL must end with /public
.
Private verification mode on public mainnets/testnets. The verification URL has the following structure:
https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/network/$NETWORK_ID
Public verification mode on public mainnets/testnets. The verification URL has the following structure:
https://api.tenderly.co/api/v1/account/$TENDERLY_ACCOUNT/project/$TENDERLY_PROJECT/etherscan/verify/network/$NETWORK_ID/public
Quickstart
In this quickstart, we’ll deploy and verify a smart contract on a Tenderly TestNet.
Create a new Foundry project
forge init hello_foundry
Get your access key
To authenticate with Tenderly, generate an access key in the Dashboard. Follow this guide to learn how.
If you have the Tenderly CLI set up, you can also get the key from:
cat ~/.tenderly/config.yaml | grep access_key:
Create a Virtual TestNet
Create a new Virtual TestNet:
- Choose a chain and name your testnet
- Choose a custom chain ID (e.g. prepend
7357
to original chain’s ID - Click “Create”
Extend foundry.toml
For verification to succeed, it’s necessary to configure cbor_metadata=true
in foundry.toml
.
Extend foundry.toml
file to include the unknown_chain
entry:
key
: ReplaceTENDERLY_ACCESS_KEY
with Tenderly access tokenchain
: Replace CHAIN_ID with your chain’s ID, especially if you created a Virtual TestNet with custom chain ID.url
: The verification URL. ReplaceTENDERLY_VIRTUAL_TESTNET_RPC_URL
with the TestNet RPC.
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
cbor_metadata = true
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
[etherscan]
# Paste TENDERLY_ACCESS_TOKEN Chain ID Verifier URL: RPC_URL/verify/etherscan
unknown_chain = { key = "TENDERLY_ACCESS_KEY", chain = CHAIN_ID, url = "${TENDERLY_VIRTUAL_TESTNET_RPC_URL}/verify/etherscan" }
Set up environment variables
Set up the following environment variables that hold:
- RPC URL
- Tenderly Verifier URL according to these formats
- Tenderly Access Token
TENDERLY_VIRTUAL_TESTNET_RPC_URL=... # Virtual TestNet RPC URL
TENDERLY_VERIFIER_URL=$TENDERLY_VIRTUAL_TESTNET_RPC_URL/verify/etherscan
TENDERLY_ACCESS_TOKEN= # paste your access key here
Fund your account
Use the TestNet’s unlimited faucet to set a new balance for any account on the network.
The following command funds 0xE58b9ee93700A616b50509C8292977FA7a0f8ce1
that we’ll use throughout this example.
Replace it with
curl $TENDERLY_VIRTUAL_TESTNET_RPC_URL \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tenderly_setBalance",
"params": [["0xE58b9ee93700A616b50509C8292977FA7a0f8ce1"], "0xDE0B6B3A7640000"],
"id": "1234"
}'
Deploy and verify the contract
Finally, deploy the contract using forge create
.
# Demo private key for address 0xE58b9ee93700A616b50509C8292977FA7a0f8ce1
# Make sure to use the correct private key if using a different account.
# Make sure your funded the account using tenderly_setBalance
PRIVATE_KEY=0xbd3a24f40aa009e82b67af2ce17c9e2c794f1958d802c9481bc551ef76e8f03f
forge create Counter \
--rpc-url $TENDERLY_VIRTUAL_TESTNET_RPC_URL \
--etherscan-api-key $TENDERLY_ACCESS_TOKEN \
--private-key $PRIVATE_KEY \
--verify \
--verifier-url $TENDERLY_VERIFIER_URL
Verifying with Foundry
In this section, you’ll find examples of how to run Foundry commands with Tenderly verification included.
Check if you’ve set up your foundry.toml
file for verification on Tenderly infrastructure.
Deploy and verify contracts with forge create
Verify your smart contract alongside the deployment with forge create
, and use the following options:
- the contract name (
Counter
) --rpc-url
with the RPC URL of the network--etherscan-api-key
and pass the value of your Tenderly API token--private-key
and pass the deployer’s private key- the
--verify
flag --verifier-url
with the verification URL ($TENDERLY_VERIFIER_URL
). Learn about the Verification URL.
forge create Counter \
--rpc-url $TENDERLY_VIRTUAL_TESTNET_RPC_URL\
--etherscan-api-key $TENDERLY_ACCESS_TOKEN \
--private-key $PRIVATE_KEY \
--verify \
--verifier-url $TENDERLY_VERIFIER_URL
Verify existing contracts with forge verify-contract
To verify a deployed contract, use forge verify-contract
and use the following options:
- The contract address (
$COUNTER_ADDRESS
) - The contract name (
Counter
) --etherscan-api-key
and pass the value of your Tenderly access token--watch
to make the script await the verification status--verifier-url
with the verification URL ($TENDERLY_VERIFIER_URL
). Learn about the Verification URL.
COUNTER_ADDRESS=0x...
forge verify-contract $COUNTER_ADDRESS \
Counter \
--etherscan-api-key $TENDERLY_ACCESS_TOKEN \
--verifier-url $TENDERLY_VERIFIER_URL \
--watch
Verify contracts from Foundry scripts with forge script
When your Foundry scripts include contract deployments, you can opt-in to get them verified when you run the script.
Use the following options to forge script
:
- The fully qualified path to the Solidity class containing the script (
script/Counter.s.sol:CounterScript
) --rpc-url
with the RPC URL of the network--etherscan-api-key
and pass the value of your Tenderly access token- the
--verify
flag --verifier-url
with the verification URL ($TENDERLY_VERIFIER_URL
) in one of these formats.
Use the --slow
flag when running Foundry scripts to prevent transaction batching. With this, a transaction is sent only after it’s preceding transaction is confirmed.
# Demo private key for address 0xE58b9ee93700A616b50509C8292977FA7a0f8ce1
# Make sure to use the correct private key if using a different account
# Make sure your funded the account using tenderly_setBalance
PRIVATE_KEY=0xbd3a24f40aa009e82b67af2ce17c9e2c794f1958d802c9481bc551ef76e8f03f
forge script script/Counter.s.sol:CounterScript \
--rpc-url $TENDERLY_VIRTUAL_TESTNET_RPC_URL \
--private-key $PRIVATE_KEY \
--etherscan-api-key $TENDERLY_ACCESS_TOKEN \
--broadcast \
--verify \
--verifier-url $TENDERLY_VERIFIER_URL \
--slow