Ethereum-Solidity 测验 Q14: 为什么在可升级合约中不能使用构造函数?

发布: (2026年1月6日 GMT+8 03:42)
2 min read
原文: Dev.to

Source: Dev.to

可升级合约中的构造函数行为

在 Solidity 中,放在构造函数内部或全局变量声明中的代码 不会 成为已部署合约的运行时字节码的一部分。这段代码仅在合约实例部署的那一刻执行一次。

当逻辑合约被代理(proxy)使用时,逻辑合约的构造函数根本不会在代理的存储上下文中执行。代理对构造函数所做的任何存储更改完全不知情。

解决方案:使用初始化函数

为了使合约具备可升级性,需要将构造函数逻辑移到普通的 初始化 函数中,并在代理链接到逻辑合约后调用该函数。初始化函数必须受到保护,确保只能调用一次——这与构造函数提供的一次性执行保证相同。

OpenZeppelin Upgrades 允许在部署代理时指定初始化函数的名称(以及其参数)。

使用 OpenZeppelin Initializable 的示例

// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract MyContract is Initializable {
    function initialize(
        address arg1,
        uint256 arg2,
        bytes memory arg3
    ) public payable initializer {
        // "constructor" code...
    }
}

该合约继承自 Initializable,该基类提供了 initializer 修饰符,确保 initialize 函数只能执行一次。

摘自 OpenZeppelin 文档

Back to Blog

相关文章

阅读更多 »