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.
In this section you can find formats for verifier URLs on:
- Virtual TestNets
- Public networks (mainnets and testnets)
Verification on public networks
When verifying smart contracts on private or public networks, use the 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_foundryCreate 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
unknown_chain = { key = "TENDERLY_ACCESS_KEY", chain = CHAIN_ID, url = "${TENDERLY_VIRTUAL_TESTNET_RPC_URL}/verify" }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
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 \
--private-key $PRIVATE_KEY \
--verify \
--verifier custom \
--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--private-keyand pass the deployer’s private key- the
--verifyflag --verifierand set it tocustomto use Tenderly’s verification service--verifier-urlwith the verification URL ($TENDERLY_VERIFIER_URL). Learn about the Verification URL.
forge create Counter \
--rpc-url $TENDERLY_VIRTUAL_TESTNET_RPC_URL \
--private-key $PRIVATE_KEY \
--verify \
--verifier custom \
--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) --watchto make the script await the verification status--verifierand set it tocustomto use Tenderly’s verification service--verifier-urlwith the verification URL ($TENDERLY_VERIFIER_URL). Learn about the Verification URL.
COUNTER_ADDRESS=0x...
forge verify-contract $COUNTER_ADDRESS \
Counter \
--verifier custom \
--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- the
--verifyflag --verifierand set it tocustomto use Tenderly’s verification service--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 \
--broadcast \
--verify \
--verifier custom \
--verifier-url $TENDERLY_VERIFIER_URL \
--slow