36

I have several pieces of documentation about libraries, but I am not yet able to infer what steps are needed to compile and deploy a library and then a contract that uses it. The behavior of the library within solidity is quite clear, but compiling and linking is not obvious to me.

Resources I have consulted:

Here is an example contract and library that I would like to get working:

MetaCoin.sol:

import "TestLib.sol";

contract MetaCoin {
  TestLib.Data data;
  address public owner;

  function MetaCoin() {
    owner = msg.sender;
    TestLib.Set(data, 2);
  }

  function GetData() constant returns(uint) {
    return TestLib.Get(data);
  }
}

TestLib.sol:

library TestLib {
  struct Data {
    uint n;
  }

  function Set(Data storage self, uint a) {
    self.n = a;
  }

  function Get(Data storage self) returns(uint) {
    return self.n;
  }
}

Thanks for your help!

28

First, let's save both of those files in the same directory and run solc --optimize --bin MetaCoin.sol. The output is:

======= MetaCoin =======
Binary: 
606060405260018054600160a060020a031916331790557f9447fa1700000000000000000000000000000000000000000000000000000000606090815260006064819052600260845273__TestLib_______________________________91639447fa179160a4916044818660325a03f41560025750505060c0806100846000396000f3606060405260e060020a600035046376b8e528811460245780638da5cb5b14608f575b005b60ad7ffc22471a000000000000000000000000000000000000000000000000000000006060908152600060648190529073__TestLib_______________________________9063fc22471a906084906020906024818660325a03f41560025750506040515191505090565b60b660015473ffffffffffffffffffffffffffffffffffffffff1681565b50604051602090f35b6060908152602090f3

======= TestLib =======
Binary: 
606060405260458060106000396000f3650302e3c5418550606060405260e060020a60003504639447fa178114602e578063fc22471a146037575b6007565b60243560043555005b600435546060908152602090f3

If you look closely (scroll right) at the MetaCoin bytecode (aka binary), you'll find a couple instances of __TestLib_______________________________. These are placeholders for where the eventual address of TestLib will be linked. This means that in order to deploy MetaCoin, we'll first need to deploy TestLib, and then use solc to link TestLib's address into the MetaCoin bytecode.

We can deploy TestLib like we would deploy any other contract. See How to deploy contract into local running node using solidity browser? for an example. Once it's deployed, you'll need to copy the address of the deployed TestLib library, which is required to link TestLib to the MetaCoin binary. To do the linking, use the deployed TestLib <address> and run:

solc --optimize --bin MetaCoin.sol | solc --link --libraries TestLib:<address>

The output will look almost the same as before, but now the __TestLib_______________________________ placeholders will have been replaced with the <address> value. This bytecode can now be used to deploy MetaCoin to the same Ethereum network that you deployed TestLib to.

  • I use 3 different libraries in my contract, but I never get the ___libraryName____________ output, no matter if I use --optimize or not. My solc version is: 0.4.24+commit.e67f0147.Linux.g++ – saitam Jul 7 '18 at 17:14
14

To add, it's possible to manually link contracts (if you wish to deploy both library and contract together.) The simplest way is just to replace all occurrences of the placeholders with the address.

An example, taken from my own (modified) code:

var linkedMetaCoinCode = metaCoinBytecode.replace(
  /_+TestLib_+/g,
  testLib.address.replace("0x", "")
);

testLib would be a normal web3 contract, deployed previously, while metaCoinBytecode would be MetaCoin's bytecode produced by solc. (In my own code, I use solc's --combined-json to get it in a nice form for JS). Note that you'll have to strip the '0x' prefix, or the linked code won't be valid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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