Transparent proxy
A transparent proxy in Ethereum (ETH) refers to a specific type of proxy contract that acts as an intermediary between a user and the actual logic or functionality of a smart contract, while remaining “transparent” in the sense that users or other contracts are unaware that they are interacting with a proxy instead of the underlying contract directly.
Complex implementation
Ref - https://eips.ethereum.org/EIPS/eip-1967
Using the Transparent Proxy pattern
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.22;
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
contract StorageProxy is TransparentUpgradeableProxy { constructor( address _logic, address initialOwner, bytes memory _data ) payable TransparentUpgradeableProxy(_logic, initialOwner, _data) { // You can put custom constructor logic here if needed. }
// If you MUST add new functionality, do so with caution, // and ideally only internal or private functions to avoid // creating new externally-callable selectors. function _myInternalLogic() internal { // Example internal logic }
// If you need to intercept calls before they're forwarded, override `_fallback()`. // But be aware that in the transparent pattern, the admin calls are routed here // to do the upgrade. function _fallback() internal virtual override { // Custom pre-forwarding logic
// Then call the original fallback from TransparentUpgradeableProxy super._fallback(); }}
contract ImplementationV1 { uint256 public num; address public implementation;
function setNum(uint256 _num) public { num = _num; }}
- Deploy ImplementationV1
- Deploy StorageProxy and give it the address of
ImplementationV1
- Select ImplementationV1 and change the
At address
field to the address of the proxy contract - Play with
setNum
andnum
- Try updating the implementation via the
ProxyAdmin
contract
Problems
- Function collissions (across implementation contract and logic contract)
- Storage slot re-ordering
Simple Proxy vs Transparent proxy
A simple proxy (often called a basic proxy) typically uses delegatecall to forward calls to another contract (implementation). However, it doesn’t have the protections or additional features that come with the transparent proxy pattern:
- Lack of transparency: If the user interacts with a basic proxy, they may have more visibility into the proxy behavior, or the proxy could expose implementation-specific details.
- Admin visibility: In some proxies, the admin can interact with the contract through the same functions as the user, potentially making it more difficult to distinguish between admin-level functionality and regular contract behavior.