5

Suppose you have a library called MyAwesomeMathLib.sol, which contains only pure internal functions, and a contract Consumer.sol that consumes the library:

pragma solidity ^0.8.0;

import "./MyAwesomeMathLib.sol";

contract Consumer {
    function doAvg(uint256 x, uint256 y) external pure returns (uint256 result) {
        result = MyAwesomeMathLib.avg(x, y);
    }
}

Further suppose that there is more than just the avg function in the MyAwesomeMathLib.sol library. When compiling Consumer.sol, will Solidity include only the bytecode relevant to the consumer, or will it include the library as a whole?

2 Answers 2

7

Only what is actually used from the library will be included in the bytecode. As discussed here, the documentation might not be super clear about it, but it states:

the code of internal library functions that are called from a contract and all functions called from therein will at compile time be included in the calling contract

Which means that functions not called from the contract will not be included at compile time.

Also answered here.

2

After reading this posts on Trying to understand libraries and Are internal functions in libraries not covered by linking?.

I think only the internal functions that are really consumed by the calling contract will be inlined. Also, for a library that is not pure internally (as long as it contains non-internal functions, I call it non-pure), even if its internal functions are called in a contract, its interal functions will not be inlined.

I checked with the following example in Remix. After compiling the following code, I searched the assembly code. I found "_num+8" (the internal function in the pure library l_Intl is called), but neither "_num+2" (the internal function in the pure library l_Intl, but no called) nor "numxxx" (which presents in the non-pure library l_Pub) presents in the assembly code.

You can also try with the follwing example.

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

library l_Intl {
    struct lstore { uint num; }
    function set (lstore storage self, uint _num) internal {
        self.num = _num+8;
    }

    function setxxx (lstore storage self, uint _num) internal {
        self.num = _num+2;
    }
}

contract c_Intl {
    l_Intl.lstore cstore;
    function setxxx (uint _num) public { l_Intl.setxxx(cstore, _num); }

}

library l_Pub {
    struct lstore { uint numxxx; }
    function set (lstore storage self, uint _num) public{
        self.numxxx = _num;
    }
    function setxxx (lstore storage self, uint _num) internal{
        self.numxxx = _num+2;
    }
}

contract c_Pub {
    l_Pub.lstore cstore;
    function set (uint _num) public { l_Pub.set(cstore, _num); }
    function setxxx (uint _num) public { l_Pub.setxxx(cstore, _num); }
}
1
  • Hi Tian, no I didn't find the answer. But tis is not an answer so unfortunately I have to flag it as such. Commented Mar 28, 2022 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.