4

I'm trying to link my contract to an external library by defining

  1. an interface contract that defines the library functions and
  2. the main contract that refers to the actual library address.

My library must be deployed externally and not be fully defined in the same contract (has presented the below challenge when using use Library for unit256)

// 1. Set up an interface defining the functions that exist within the target library (but not implementing them!!) 
contract SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256);
  function div(uint256 a, uint256 b) internal pure returns (uint256);
  function sub(uint256 a, uint256 b) internal pure returns (uint256);
  function add(uint256 a, uint256 b) internal pure returns (uint256);
}

// 2. Define the main contract with reference to the interface and external deployed library address 
contract Foo {
  SafeMath ExternalSafeMath = SafeMath(0x013......);

  // THE LINE BELOW BREAKS 
  // It expects a library but instead gets contract. I must find a work around or obtain advice on how to otherwise implement this 
  using ExternalSafeMath for uint256;

  // Contract  continues ...
}

As seen above, I specify an interface contract that defines the functions that this library contains (as per suggestions in this forum's previous answers).

When attempting to issue a using ExternalSafeMath for unit256, the compiler correctly complains that it expects the ExternalSafeMath object to be a library, and NOT a contract. But as it stands, it is currently a contract for interface purposes.

THE QUESTION: How can I achieve a using Library for uint256 on an EXTERNALLY deployed library? And how will my syntax of code change in the code that follows

THE CONTEXT: My requirement is that I cannot implement the entire library in one contract deployment.

This is due to my contract implementation exceeding gas limit during deployment. Hence needing me to modularise contracts to separate addresses but still retain functionality of the current code

1
  • Have you solved this problem? Have you tried to change contract SafeMath to library SafeMath? If I am correct you can't use abstract contract as library, you will have to implement functions directly in library. Have a look at example. Commented Jan 28, 2018 at 0:31

2 Answers 2

1

There's a typo. (actually two) It is not use ExternalSafeMath for uint256:

It's using ExternalSafeMath for uint256;

  • using, not use
  • you have a colon instead of a semi-colon at the end.

Also, if you are using Open-Zeppelin's SafeMath lib, the correct usage is:

uint256 answer = a.add(b);
1
  • The context of this question is about importing libraries from an external address. What you describe with regards to the "correct usage" is if the library is in the same deployment bytecode - which my question is not referring to. Thanks for finding those syntax errors - but once again, the context of my question is less about my code example but more about how to import libraries on external addresses. Thanks for your response
    – supa_marty
    Commented Dec 14, 2017 at 0:26
0

First of SafeMath needs to be labelled as a library and not a contract. If your library only contains internal functions they will be embedded to your contract code. If the lib contains external functions you will have to provide the address when deploying your contract. Hence you can leave your code just to be:

contract Foo {

  using ExternalSafeMath for uint256;

  // Contract  continues ...
}

Dont do this SafeMath ExternalSafeMath = SafeMath(0x013......);

You will provide the address of the library to the contracts bytecode when deploying. Frameworks like foundry, hardhat or truffle make that very easy/

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.