I am learning to develop upgradeable smart contracts using openzeppelin library for ERC721 and ERC1155 contracts. However, I don't understand what does the unchained function mean. More specifically what's the difference between init and init_unchained functions. Below 2 functions show them being called in an ERC1155 upgradeable contract provided by Openzeppelin
function __ERC1155_init(string memory uri_) internal onlyInitializing {
__ERC1155_init_unchained(uri_);
}
function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing {
_setURI(uri_);
}
Best Answer
From OpenZeppelin's docs, there is the following section:
This basically means that multiple inheritance doesn't play nice with initializers.
Generally, a
_<CONTRACT_NAME>_init_unchained
method defines the initialization of the derived contract while excluding initializing the parents that it derives from (you'd have to explicitly initialize those parents in your contract), while a_<CONTRACT_NAME>_init
method defines the initialization of the derived contract along with all the parents that it derives from. In your case, the unchained method happens to require no parent initialization .In some cases with multiple inheritance, the derived contract that you define could have an collision where two its parent contracts share a parent contract that they both derive from. In such a case, the
_<CONTRACT_NAME>_init
call on the shared parent that exists in both initializers of the collided contracts would result in attempting to initialize the shared parent contract twice, which causes an error. OpenZeppelin's upgradable contracts have been improving a lot in the past few years in order to minimize the possibility of such collisions. Consider using the Contracts Wizards and ticking the "upgradeability" check box to showcase writing smart contracts with multiple inheritance without being faced with such issues.