← all simulations
slide 27 · contracts
Proxy contract approach
proxy
delegatecall →storage kept
logic V1
logic V2
Upgrade logic from V1 to V2 through while survives.
- 1Call V1 through the proxy
- 2Upgrade to V2
- 3Check the storage survived
live · 0 players in this room
send coins to another player
10.0000 BTC10.0000 ETH
recipient
waiting for another player to join this room… open this page in a second tab or share the link with the class.
fee 0.0005 · total 0.5005 BTC
live transfers in this room
room ledger · tap a row to replay its steps
- no transfers yet — be the first to pay a classmate.
Proxy address
0xPr0xy… (never changes)
Implementation
LogicV1
counter (proxy storage)
0
Increment step
+1
Interact
PROXY (storage)
slot 0 · implementation
slot 1 · admin
slot 2 · counter = 0
→
delegatecallcode borrowed,
storage stays home
storage stays home
LOGIC V1 (code only)
increment()
its own storage: unused, always 0
Proxy.sol
1contract Proxy {2 // slot keccak256('eip1967.proxy.implementation') - 13 address implementation; // storage lives HERE4 address admin;5 uint256 public counter; // user data lives HERE too67 function upgradeTo(address newImpl) external {8 require(msg.sender == admin, "not admin");9 implementation = newImpl;10 }1112 fallback() external payable {13 // run impl's CODE against THIS contract's storage14 (bool ok,) = implementation.delegatecall(msg.data);15 require(ok);16 }17}
LogicV1.sol
1contract LogicV1 {2 address implementation; address admin; // layout must match!3 uint256 public counter;45 function increment() external { counter += 1; }6}
Execution log
01 proxy deployed at 0xPr0xy… · implementation = LogicV1 · counter = 0
Rules of the proxy pattern
- •delegatecall executes another contract's code in your own storage and msg.sender context — that is the whole trick.
- •Never reorder or insert state variables; only append. Use EIP-1967 fixed slots for admin and implementation to avoid clashing with user data.
- •Logic contracts have no constructor — use an initialize() guarded by initializer, and initialize in the same transaction as deployment.
- •Flavours: Transparent proxy (admin routing), UUPS (upgrade logic in the implementation, cheaper), Beacon (upgrade many proxies at once), Diamond/EIP-2535 (multi-facet).
- •Upgradeability is centralisation. Whoever holds the admin key can replace the contract users trusted — put it behind a multisig plus a timelock, and say so publicly.
The trade-off in one line: is the security guarantee, and a proxy deliberately gives it up in exchange for the ability to fix bugs.