Transparent Upgradeable Proxy - это паттерн, полностью исключающий возможность столкновения селекторов функций.
В частности, TUP предписывает, что в прокси контракте не должно быть никаких публичных функций, кроме fallback.
Но если есть только функция fallback, как нам вызвать функцию для обновления прокси?
Ответ заключается в том, чтобы определить, является ли отправитель msg.sender администратором.
contract Proxy is ERC1967 {
address immutable admin;
constructor(address admin_) {
admin = admin_
}
fallback() external payable {
if (msg.sender == admin) {
// upgrade logic
} else {
// delegatecall to implementation
}
}
}
Из этого следует, что администратор не может напрямую использовать прокси, поскольку его вызовы всегда направляются в сторону if. Однако, используя немного другой механизм, который мы обсудим позже, администратор все же может делать вызовы прокси, а тот делегировать вызов в Логику.
Изменение неизменяемого администратора
В приведенном выше фрагменте кода администратор является неизменяемым. Это означает, что контракт технически не соответствует стандарту ERC-1967, который гласит, что администратор должен храниться в слоте хранения 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 или bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1).
Для того, чтобы стать совместимым со стандартом, TUP должен хранить адрес администратора в этом слоте памяти, но не использовать его для других целей.
Наличие адреса в этом слоте будет сигнализировать другим программам, что контракт является прокси (одна из целей ERC-1967). Однако чтение из хранилища при каждом обращении к прокси добавляет к вызову еще 2100 газа. Поэтому желательно использовать неизменяемую переменную.
«Смена» администратора
Однако все же желательно иметь возможность обновлять адрес администратора - но изначально это кажется невозможным.
TUP позволяет изменять админский контракт прокси двумя способами. Во-первых, он назначает другой контракт, известный как ProxyAdmin, администратором прокси.
Во-вторых, владелец ProxyAdmin является «истинным» администратором. ProxyAdmin просто направляет вызовы от владельца к прокси. «Истинный» администратор вызывает ProxyAdmin, а ProxyAdmin вызывает Transparent Proxy. Изменив владельца ProxyAdmin, мы можем изменить, кто имеет возможность обновлять Transparent Proxy.
Далее поговорим об этом интересном контракте.
#proxy #transparent
