Работает на: публичных сетях (mainnet и testnet). Чтобы верифицировать контракты в Virtual Environment, см. Деплой и верификация контрактов и Верификация прокси-контрактов с помощью Foundry.
forge create, forge script и forge verify-contract, посредством своего API верификации, совместимого с Etherscan. Верификация бывает либо приватной (исходный код виден только внутри вашего проекта в Tenderly), либо публичной (виден всем, у кого есть ссылка).
Прежде чем начать
Вам понадобятся slug вашего аккаунта и проекта Tenderly, ключ доступа Tenderly (Dashboard → Account Settings → Authorization) и профинансированный аккаунт в целевой сети. Верификатор Tenderly сопоставляет хеш метаданных, который компилятор Solidity добавляет к развёрнутому байткоду, с исходным кодом, который вы отправляете. Сохраняйте метаданные в результатах компиляции и фиксируйте настройки компилятора, чтобы они не изменились между моментом деплоя и моментом верификации:foundry.toml
cbor_metadata = true и bytecode_hash = "ipfs" — это значения по умолчанию в Foundry, но некоторые шаблоны их убирают; bytecode_hash = "none" ломает верификацию. Расхождение в настройках компилятора между деплоем и верификацией приводит к ошибке Bytecode does not match deployed contract.
В примерах ниже используется Base Sepolia (chain ID 84532). Настройка окружения:
.env
URL верификатора
Каждая команда верификации Foundry принимает--verifier-url, указывающий на API верификации Tenderly, и --etherscan-api-key $TENDERLY_ACCESS_KEY для аутентификации:
Приватная верификация
Приватно верифицированные контракты видны только участникам вашего проекта в разделе Contracts в Dashboard.showLineNumbers
forge verify-contract ожидает, что аргументы конструктора уже закодированы в ABI; используйте cast abi-encode, чтобы получить их. --watch опрашивает верификатор, пока верификация не завершится, и печатает результат.
При успехе Foundry печатает строку
URL: https://etherscan.io/address/.... Это особенность отображения потока, совместимого с Etherscan; контракт был верифицирован в Tenderly, а не в Etherscan. Подтвердите это в Dashboard в разделе Contracts.Публичная верификация
Замените URL верификатора на вариант с суффиксом/public; больше ничего менять не нужно. Страница с верифицированным исходным кодом станет доступна всем, у кого есть ссылка, без входа в Tenderly.
showLineNumbers
Деплой и верификация одной командой
forge create и forge script принимают те же флаги встроенно, поэтому деплой и верификацию можно запустить одной командой. В отличие от forge verify-contract, обе они принимают аргументы конструктора как сырые значения и сами кодируют их в ABI:
showLineNumbers
forge script с флагом --slow; каждый контракт, который развёртывает скрипт, верифицируется автоматически, а аргументы конструктора берутся из broadcast-лога. Без --slow пакетирование broadcast может отправить транзакцию до подтверждения предыдущей, из-за чего может произойти гонка с шагом верификации:
showLineNumbers
Верификация контракта, который вы не разворачивали
Когда контракт верифицирован в публичном обозревателе (Etherscan, Basescan), но не в вашем проекте Tenderly, клонируйте верифицированный исходный код локально с помощьюforge clone и повторно верифицируйте его через API Tenderly:
showLineNumbers
forge clone скачивает верифицированный исходный код из Etherscan-совместимого API исходной сети (используйте ключ соответствующего обозревателя для каждой сети), восстанавливает структуру проекта и фиксирует настройки компилятора, которые использовал исходный деплойер. Запустите forge build в клонированной директории, чтобы убедиться, что она собирается; ошибки разрешения импортов обычно связаны с remappings.txt.
Затем верифицируйте в Tenderly:
showLineNumbers
Bytecode does not match deployed contract, передайте исходные настройки компилятора явно. Все они перечислены на странице обозревателя, где контракт уже верифицирован, в разделе исходного кода контракта:
showLineNumbers
Контракты, живущие в директории lib
forge build компилирует только то, что достижимо из src/. Контракт, который существует только внутри зависимости в lib/ (прокси, стандартная реализация ERC), никогда не попадает в кеш сборки, и forge verify-contract падает с ошибкой:
src/Imports.sol, который импортирует контракт, а затем пересоберите:
src/Imports.sol
Imports.sol никогда не отправляется в верификатор; он лишь заставляет компилятор кешировать контракт и его зависимости. После этого верифицируйте, используя полный путь контракта в lib/, поскольку исходный код физически находится именно там.
Для TransparentUpgradeableProxy, который вы не разворачивали, конструктор имеет вид (address _logic, address initialOwner, bytes _data), и большую его часть можно восстановить из состояния сети:
showLineNumbers
foundry.toml или скриптам деплоя разворачивающего проекта.