我正在学习使用openzeppelin库为ERC721和ERC1155合同开发可升级的智能合同。然而,我不明白无链函数是什么意思。更具体地说,init和init_unchained函数之间的区别是什么。下面两个函数显示它们是在Openzeppelin提供的ERC1155可升级合同中调用的
function __ERC1155_init(string memory uri_) internal onlyInitializing {
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {
_setURI(uri_);
}
发布于 2022-03-04 09:00:32
在OpenZeppelin博士中,有以下部分:
初始化函数不会像构造函数一样被编译器线性化。因此,每个__{ContractName}_init函数都嵌入对所有父初始化器的线性化调用。因此,调用其中两个init函数可能会初始化相同的合同两次。在每个约定中找到的函数__{ContractName}_init_unchained是初始化器函数,减去对父初始化器的调用,可用于避免双重初始化问题,但不建议手动执行。我们希望能够在升级插件的未来版本中实现这方面的安全检查。
这基本上意味着多重继承对初始化器没有好处。
通常,_<CONTRACT_NAME>_init_unchained
方法定义派生合同的初始化,而不包括初始化它派生的父级(您必须显式地初始化契约中的那些父级),而_<CONTRACT_NAME>_init
方法定义派生契约的初始化以及派生的所有父级。在您的示例中,unchained方法碰巧不需要父初始化。
在某些具有多重继承的情况下,您定义的派生契约可能会发生冲突,其中两个父契约共享它们各自派生的父契约。在这种情况下,在冲突的合同的两个初始化器中存在的对共享父协议的_<CONTRACT_NAME>_init
调用将导致尝试两次初始化共享父协议,这将导致错误。OpenZeppelin的可升级合同在过去几年里有了很大的改进,以尽量减少这种碰撞的可能性。考虑使用合同奇才并勾选“可升级性”复选框,以展示如何编写具有多重继承的智能合同,而不会遇到此类问题。
https://ethereum.stackexchange.com/questions/122462
复制相似问题