Работает на: Virtual Environments и публичных сетях (mainnet и testnet). Один и тот же плагин работает и там, и там; укажите нужную сеть в
hardhat.config.ts.@tenderly/hardhat-tenderly.
Требования
Автоматическая верификация прокси работает «из коробки» в@tenderly/hardhat-tenderly:
>= 1.10.0(линия Ethers 5)>= 2.1.0(линия Ethers 6)
@openzeppelin/hardhat-upgrades. Hardhat Ignition не поддерживается для верификации прокси пока что.
Если вы используете более раннюю версию плагина и не можете обновиться, воспользуйтесь обходным решением ниже.
Автоматическая верификация
Плагин верифицирует три паттерна прокси:TransparentUpgradeableProxy, UUPSUpgradeableProxy и BeaconProxy.
Под капотом плагин управляет
@nomicfoundation/hardhat-verify с расширением @openzeppelin/hardhat-upgrades. Установка TENDERLY_AUTOMATIC_POPULATE_HARDHAT_VERIFY_CONFIG=true позволяет плагину автоматически заполнить URL верификации @nomicfoundation/hardhat-verify.Для более наглядного примера можете заглянуть в этот GitHub-репозиторий и перейти в
scripts/proxy/, чтобы увидеть полный пример. Автоматически
Разверните прокси как обычно, используя
deployProxy из расширения @openzeppelin/hardhat-upgrades.Под капотом автоматическая верификация реализована как обёртка вокруг deployProxy и ожидание завершения деплоя. Вручную
Верификация прокси вручную выполняется после того, как прокси-контракт развёрнут, — путём вызова функции
tenderly.verify().Обходное решение для более ранних версий
При использовании@tenderly/hardhat-tenderly версий < 1.10.0 и < 2.1.0 это обходное решение включает автоматическую верификацию.
Необходимо верифицировать следующее:
- Прокси-контракт (например, прокси от OpenZeppelin)
- Реализацию за прокси
- Любые зависимости реализации
- Новые экземпляры реализации, развёрнутые при апгрейдах
Обзор
В этом руководстве мы будем использовать пример Hardhat-проекта и плагин@tenderly/hardhat-tenderly для демонстрации верификации альтернатив OpenZeppelin: UUPSUpgradeable, TransparentUpgradeableProxy и BeaconProxy.
Для получения адреса развёрнутой реализации используйте пакет @openzeppelin/upgrades-core и функцию getImplementationAddress.
Верифицировать реализацию прокси обычно несложно; верифицируйте её так же, как любой другой контракт.
example.ts
- Загрузить точный смарт-контракт прокси в зависимости от типа используемого прокси, чтобы он был скомпилирован. Вам нужно будет импортировать прокси-контракты через компилятор, создав фиктивный .sol-файл.
- Изменить
hardhat.config.ts, чтобы указать настройки, с которыми компилировались контракты OpenZepplin.
example.ts
Для вариантов установки не через Homebrew см. репозиторий Tenderly CLI.
В
hardhat.config.ts задайте tenderly.username и tenderly.project в соответствии с вашими slug’ами проекта и пользователя.Самый быстрый способ развернуть и верифицировать контракты — использовать Virtual Environment.
В Tenderly Dashboard откройте Virtual Environments и создайте новую среду. Выберите базовую сеть, от которой сделать форк, и Chain ID, затем скопируйте Admin RPC URL со страницы деталей Virtual Environment.
networks: {
virtualMainnet: {
url: process.env.TENDERLY_VIRTUAL_TESTNET_RPC!,
chainId: 73571, // the Chain ID you set when creating the Virtual Environment
},
},
Полное пошаговое руководство см. в быстром старте Virtual Environment.
При повторном деплое контрактов сначала удалите папку
.openzeppelin. Она кеширует информацию о прокси и их реализациях.Чтобы верифицировать прокси-контракт, создайте файл
DummyProxy.sol и импортируйте прокси-контракты OpenZepplin, с которыми работаете. Тем самым эти контракты будут загружены и пройдут через компилятор, что даст возможность сослаться на точный исходный код прокси при верификации.// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
abstract contract ERC1967ProxyAccess is ERC1967Proxy {}
abstract contract UpgradableBeaconAccess is UpgradeableBeacon {}
abstract contract BeaconProxyAccess is BeaconProxy {}
abstract contract TransparentUpgradeableProxyAccess is TransparentUpgradeableProxy {}
Приведённая ниже карта переопределений выведена для
@openzeppelin/contracts-upgradeable версии 4.9.1.
Для других версий пакета она может отличаться.Плагин
hardhat-tenderly использует для верификации как исходный код смарт-контрактов, так и настройки компилятора. Если что-то из этого указано неверно, верификация не пройдёт.const config: HardhatUserConfig = {
solidity: {
compilers: [{ version: '0.8.18' } /* OTHER COMPILER VERSIONS*/],
overrides: {
'@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol': {
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
'@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol': {
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
'@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol': {
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
'@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol': {
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
'contracts/proxy.sol': {
version: '0.8.9',
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
},
},
/* OTHER CONFIG */
};
Верификация по типу прокси
Эти примеры кода показывают, как верифицировать реализацию и прокси для трёх паттернов прокси OpenZeppelin. Примеры используют проксированный контрактVault, ссылающийся на ERC-20 токен (TToken).
UUPS-прокси
Чтобы верифицировать UUPS-прокси и связанную информацию, вызовите плагинhardhat-tenderly дважды:
- Для верификации реализации необходимо указать:
nameвашего проксированного контракта (в нашем случаеVault)- Адрес, по которому был развёрнут контракт, полученный методом
getImplementationAddressиз@openzeppelin/upgrades-core.
- Для верификации прокси укажите:
ERC1967Proxyв качествеnameпрокси-контракта- Адрес прокси
proxy.address
example.ts
Полный пример кода
Ниже приведён полный тест Hardhat, который делает следующее:- Разворачивает
TToken(нужен для vault) - Разворачивает
Vaultкак прокси, инициализированный контрактомTToken - Верифицирует экземпляр прокси (
ERC1967Proxy), развёрнутый по адресуawait proxy.getAddress() - Верифицирует экземпляр реализации
Vault, развёрнутый по адресуgetImplementationAddress(ethers.provider, await proxy.getAddress()) - Апгрейдит прокси до
VaultV2
example.ts
Transparent-прокси
Чтобы верифицировать UUPS-прокси и связанную информацию, вызовитеhardhat-tenderly, передав два контракта: Vault для реализации и TransparentUpgradeableProxy для самого прокси.
example.ts
- Для верификации реализации укажите:
nameвашего проксированного контракта (в нашем случаеVault)- Адрес, по которому был развёрнут контракт, полученный методом
getImplementationAddressиз@openzeppelin/upgrades-core.
- Для верификации прокси укажите:
TransparentUpgradeableProxyв качествеnameпрокси-контракта- Адрес прокси
await proxy.getAddress()
Полный пример кода
example.ts
Beacon-прокси
Чтобы верифицировать Beacon-прокси и связанную информацию, необходимо верифицировать два контракта:Vault (реализация) и UpgradableBeacon от OpenZepplin:
example.ts
Полный пример кода
example.ts