Libraries calling methods in libraries

Hi guys,

Today I had a problem when I migrated a project to make it upgradable with ZOS. Then I created a project from the ground up and had the same problem.

Let’s imagine the following code

pragma solidity ^0.5.0;

import "zos-lib/contracts/Initializable.sol";
import "openzeppelin-eth/contracts/token/ERC721/ERC721Full.sol";
import "openzeppelin-eth/contracts/token/ERC721/ERC721Mintable.sol";
import "./MyLib.sol";

contract MyNFT is Initializable, ERC721Full, ERC721Mintable {
    function initialize() public initializer {
        ERC721.initialize();
        ERC721Enumerable.initialize();
        ERC721Metadata.initialize("MyNFT", "MNFT");
        ERC721Mintable.initialize(msg.sender);
    }

    function calculationSum() public pure returns(uint256) {
        return MyLib.mySum(1, 2);
    }
}

And

pragma solidity ^0.5.0;

import "./sec/MySec.sol";

library MyLib {
    function mySum(uint256 a, uint256 b) public pure returns(uint256) {
        return MySec.verifyOverflow(a, b);
    }
}

And

pragma solidity ^0.5.0;

library MySec {
    function verifyOverflow(uint256 a, uint256 b) public pure returns(uint256) {
        uint256 c = a + b;
        require(c - a == b, "overflow!");
        return c;
    }
}

First I tried without MySec and it worked well, then I added and it says MyLib bytecode contains unlinked libraries.. I understand what it says, but now I have a question. Is it possible to fix? If so, how? Is it a limitation of ZOS? Is it bad practice to call a library from a library?

Thanks.
Cheers.

Hey @obernardovieira, welcome to the forum! This is indeed a limitation of zOS at the moment I’m afraid. Note that it only affects external Solidity libraries though: if you change the methods in MySec to be internal instead of public, you should not have any issues.

1 Like

Hello, thank you so much. I’ve been reading the forum but it was the first post.
Ok, I just tried and yeap, it worked. Thanks.

1 Like

Hi again,
I’m now facing problems with gas limits

ContractName deployment failed with error: The contract code couldn't be stored, please check your gas limit.

Is the gas limit something that I can set with ZOS or is it the fact that the contract is too big?

Hey @obernardovieira! Thanks for using the forum :slight_smile:

Mind opening a new topic for this new issue? That way we can build a complete and easy to search knowledge base to help others with similar issues.

Edit: "The contract code couldn't be stored, please check your gas limit."

Thanks!

Sorry to get back to this one, but, is there any reason that makes the asserts stop to work? We (at our project) make the methods private, and then, the asserts stop working.

Thanks.

@obernardovieira sorry, I’m not sure I follow. Which asserts stop working when you make which methods private?

1 Like

Well, we have, let’s say a SomeLibrary.sol, then we import “./SomeLibrary.sol” and then we use SomeLibray.method();

we turned all methods to internal and the asserts in the methods stopped working.

I’d need to see the code, but my gut feeling is that the assertions you have depend on msg.sender, which is not changed in an internal call, but is set to your contract’s address in an external one. Could that be the case?

I would love to, but I can’t share the code yet.
Although, it does not have msg.sender, it only does calculations.
We decided to change the approach. The code will be released soon, I can get back to it then.

Had a similar issue, my recommendation is to just create it as a contract instead of a library. Then set the address in the main contract in a setter function or in the initialization of the contract, and cast the address to the Contract type and you are done
https://zupzup.org/smart-contract-interaction/

1 Like

Hi @pmprete,

Welcome to the community :wave:.

Thanks for sharing.

Thank you @abcoathup, i’ve being using open zeppelin sdk for a couple of months and except some minor issues the overall experience has been great.

1 Like