У меня есть несколько документов о библиотеках, но я пока не могу сделать вывод о том, какие шаги необходимы для компиляции и развертывания библиотеки, а затем контракта, который ее использует. Поведение библиотеки внутри 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;
}
}
Спасибо за вашу помощь!
Во-первых, давайте сохраним оба этих файла в одном каталоге и запустим 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.
___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», иначе связанный код будет недействительным.
никсмак