Каковы шаги по компиляции и развертыванию библиотеки в Solidity?

У меня есть несколько документов о библиотеках, но я пока не могу сделать вывод о том, какие шаги необходимы для компиляции и развертывания библиотеки, а затем контракта, который ее использует. Поведение библиотеки внутри solidity вполне понятно, а вот компиляция и линковка для меня не очевидны.

Ресурсы, с которыми я консультировался:

Вот пример контракта и библиотеки, которые я хотел бы заставить работать:

МетаКоин.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;
  }
}

Спасибо за вашу помощь!

Ответы (2)

Во-первых, давайте сохраним оба этих файла в одном каталоге и запустим solc --optimize --bin MetaCoin.sol. Результат:

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

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

Если вы внимательно посмотрите (прокрутите вправо) байт-код MetaCoin (он же двоичный), вы найдете пару экземпляров __TestLib_______________________________. Это заполнители для того, где будет связан возможный адрес TestLib. Это означает, что для развертывания MetaCoin нам сначала нужно развернуть TestLib, а затем использовать solc для привязки адреса TestLib к байт-коду MetaCoin.

Мы можем развернуть TestLib так же, как любой другой контракт. См. Как развернуть контракт на локальном работающем узле с помощью браузера Solidity? для примера. После развертывания вам нужно будет скопировать адрес развернутой библиотеки TestLib, которая требуется для привязки TestLib к бинарному файлу MetaCoin. Чтобы выполнить связывание, используйте развернутую TestLib <address>и запустите:

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

Вывод будет выглядеть почти так же, как и раньше, но теперь __TestLib_______________________________заполнители будут заменены <address>значением. Этот байт-код теперь можно использовать для развертывания MetaCoin в той же сети Ethereum, в которой вы развернули TestLib.

Я использую 3 разные библиотеки в своем контракте, но я никогда не получаю ___libraryName____________результат, независимо от того, использую я --optimizeили нет. Моя версия solc: 0.4.24+commit.e67f0147.Linux.g++

Чтобы добавить, можно вручную связать контракты (если вы хотите развернуть и библиотеку, и контракт вместе). Самый простой способ — просто заменить все вхождения заполнителей адресом.

Пример, взятый из моего собственного (модифицированного) кода:

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

testLib будет обычным контрактом web3, развернутым ранее, а metaCoinBytecode будет байт-кодом MetaCoin, созданным solc. (В моем собственном коде я использую solc --combined-json, чтобы получить его в удобной форме для JS). Обратите внимание, что вам придется удалить префикс «0x», иначе связанный код будет недействительным.

интересный способ, выглядит красиво