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:
- Virtual TestNets
- Public networks (mainnets and testnets)
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_IDPublic 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/publicQuickstart
In this quickstart, we’ll deploy and verify a smart contract on a Tenderly TestNet.
Create a new Foundry project
forge init hello_foundryGet 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
7357to 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_KEYwith 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_URLwith 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 hereFund 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_URLVerifying 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-urlwith the RPC URL of the network--etherscan-api-keyand pass the value of your Tenderly API token--private-keyand pass the deployer’s private key- the
--verifyflag --verifier-urlwith 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_URLVerify 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-keyand pass the value of your Tenderly access token--watchto make the script await the verification status--verifier-urlwith 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 \
--watchVerify 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-urlwith the RPC URL of the network--etherscan-api-keyand pass the value of your Tenderly access token- the
--verifyflag --verifier-urlwith 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