首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在Openzeppelin的可初始化契约中使用_initializing和isTopLevelCall变量?

为什么在Openzeppelin的可初始化契约中使用_initializing和isTopLevelCall变量?
EN

Stack Overflow用户
提问于 2021-12-01 19:09:17
回答 2查看 353关注 0票数 2

这是代理模式上下文中的抽象契约:

代码语言:javascript
复制
abstract contract Initializable {
    bool private _initialized;
    bool private _initializing;

    modifier initializer() {
        require(_initializing || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }
}

contract UpgradebleTest1 is Initializable {
    uint public x;

    function initialize(uint _x) public initializer {
        x = _x;
    }
}

我不明白_initializing和isTopLevelCall的必要性。仅仅使用_initialized进行控制还不够吗?

谢谢,

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-12-02 10:21:20

_initializingisTopLevelCall组合允许使用initializer修饰符进行链接调用:

代码语言:javascript
复制
contract UpgradebleTest1 is Initializable {
    uint public x;

    function initialize(uint _x) public initializer {
        internalInit(_x);
    }

    function internalInit(uint _x) internal initializer {
        x = _x;
    }
}

如果没有_initializingisTopLevelCall检查,initializer修饰符将传递第一个调用(initialize()),但在第二个调用(internalInit())上失败。

代码语言:javascript
复制
modifier initializer() {
    require(!_initialized, "Initializable: contract is already initialized");
    _initialized = true;
}
票数 1
EN

Stack Overflow用户

发布于 2021-12-02 11:07:40

代码语言:javascript
复制
abstract contract Initializable {
        bool private _initialized;
    
        modifier initializer() {
            require(!_initialized, "Initializable: co...");
            _;
            _initialized = true;
        }
    }
    
contract UpgradebleTestParent is Initializable {
    uint public x;

    function initialize(uint _x) internal initializer {
        x = _x;
    }
}

contract UpgradebleTestMain is UpgradebleTestParent {
    function init(uint _x) public initializer {
        initialize(_x);
    }
}

如果如上,它将执行相同的逻辑,但是_initialized = true;将不必要地执行两次,对吗?然而,它似乎比前一个更便宜的一个变量和相关的附加指令?难到不是么?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70189923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档