Blockchain Smart Contracts with Solidity · 课时

透明代理模式与存储布局

学习透明代理模式、delegatecall 如何将逻辑与存储分离,以及安全升级合约时必须遵循的存储布局规则。

第 4 / 4 课13 个步骤

透明代理模式与存储布局 是 CoddyKit 上的免费 Blockchain Smart Contracts with Solidity 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Blockchain Smart Contracts with Solidity 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Blockchain Smart Contracts with Solidity 课程共包含 4 节课。

本课时的部分内容尚未翻译,以英文显示。

Recap: Why Proxies

You have seen UUPS and the Diamond standard. Both rely on a foundational idea: a proxy holds the storage and forwards calls to a separate logic (implementation) contract. Upgrading means pointing the proxy at new logic.

How delegatecall Works

The magic behind proxies is delegatecall. It runs the logic contract's code but in the proxy's storage context, using the proxy's msg.sender and balance.

So storage lives in the proxy; behavior lives in the implementation.

A Minimal Proxy Fallback

A proxy forwards every unknown call to the implementation using assembly delegatecall in its fallback.

fallback() external payable {
    address impl = _implementation();
    assembly {
        calldatacopy(0, 0, calldatasize())
        let ok := delegatecall(gas(), impl, 0, calldatasize(), 0, 0)
        returndatacopy(0, 0, returndatasize())
        switch ok
        case 0 { revert(0, returndatasize()) }
        default { return(0, returndatasize()) }
    }
}

The Function Clash Problem

If the proxy itself has an upgradeTo function and the logic also has a function with the same selector, calls become ambiguous. The Transparent Proxy pattern solves this by routing based on the caller.

Admin vs User Routing

In a Transparent Proxy, the admin address can call admin functions (like upgrade) but cannot reach the implementation. Everyone else is always forwarded to the implementation. This removes clashes.

modifier ifAdmin() {
    if (msg.sender == _admin()) {
        _;
    } else {
        _fallback();
    }
}

Storage Slot Collisions

Both proxy and logic write to the same storage. If they used slot 0 for different variables, they would corrupt each other. Proxies store admin and implementation at fixed pseudo-random slots (EIP-1967) to avoid collisions.

// EIP-1967 implementation slot
bytes32 internal constant _IMPL_SLOT =
    0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

Reading the Implementation Slot

The proxy reads and writes that fixed slot directly with assembly so it never collides with logic variables.

function _implementation() internal view returns (address impl) {
    bytes32 slot = _IMPL_SLOT;
    assembly { impl := sload(slot) }
}

Storage Layout Rules

When upgrading the logic you must preserve the order and types of existing storage variables. New variables go at the end.

  • Never reorder existing variables
  • Never change a variable's type
  • Never insert a new variable before old ones

Storage Gaps

Inheritable base contracts reserve space for future variables with a __gap array so child contracts do not collide after an upgrade adds fields to the base.

contract Base {
    uint256 public value;
    // reserve 50 slots for future use
    uint256[50] private __gap;
}

Initializers Not Constructors

Constructors run only on the logic contract's own deployment, not through the proxy. Upgradeable contracts use an initialize function guarded so it runs exactly once.

bool private _initialized;

function initialize(uint256 v) external {
    require(!_initialized, 'already init');
    _initialized = true;
    value = v;
}

Transparent vs UUPS

Transparent proxies put the upgrade logic in the proxy (more deployment gas, simpler logic). UUPS puts it in the implementation (cheaper proxy, but you must include upgrade code in every version). Choose based on cost and team discipline.

Quick Check

Test your understanding of proxy storage.

Recap

You learned the Transparent Proxy pattern:

  • delegatecall runs logic in the proxy's storage
  • Admin-vs-user routing avoids function clashes
  • EIP-1967 fixed slots and __gap arrays prevent collisions
  • Use initialize, preserve storage layout, append new variables

Follow these rules and upgrades stay safe.

免费开始

用 AI 导师学习 Blockchain Smart Contracts with Solidity — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
12
课程
48

常见问题解答

「透明代理模式与存储布局」课时是免费的吗?

是的 — 「透明代理模式与存储布局」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Blockchain Smart Contracts with Solidity 课程的其余内容,请升级到 CoddyKit PRO。 Blockchain Smart Contracts with Solidity 课程共包含 4 节课。

「透明代理模式与存储布局」这节课中我会学到什么?

学习透明代理模式、delegatecall 如何将逻辑与存储分离,以及安全升级合约时必须遵循的存储布局规则。 你通过在浏览器中直接运行的动手代码来练习 Blockchain Smart Contracts with Solidity,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Blockchain Smart Contracts with Solidity 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Blockchain Smart Contracts with Solidity 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「透明代理模式与存储布局」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Blockchain Smart Contracts with Solidity 课中编写并运行代码吗?

能。每节 Blockchain Smart Contracts with Solidity 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 为什么需要可升级合约
  2. UUPS 代理模式实现
  3. Diamond 标准(多 facet 代理)
  4. 透明代理模式与存储布局
← 返回 Blockchain Smart Contracts with Solidity