Что такое библиотеки на платформе Ethereum, а точнее на языке solidity, читайте тут: Ethereum Libraries. В данной публикации я рассмотрю исключительно вопрос, как их создать и использовать на примере создания ядра децентрализованной автономии.
Подготовительные работы
Контракты, используемые в публикации находятся тут: https://github.com/airalab/core
Требуется скачать контракт Core.sol и все его родительские контракты :
В данной примере контракты AddressList.sol и AddressMap.sol как раз являются библиотеками, требуемыми контракту Core.sol для работы, а так как данные контракты хранят крайне унифицированную логику (что можно понять из названий), то мы их превратили именно в библиотеки.
Пытаемся создать контракт, использующий библиотеки с помощью Ethereum Wallet.
После того, как данные контракты будут скачены, давайте их сольём в единый файл для того, чтобы попробовать сначала развернуть Core.sol в сети Ethereum, используя официальное приложение с GUI — Ethereum Wallet.
Итак, открываем Ethereum Wallet, переходим в раздел «Контракты» и нажимаем «Deploy new contract»:
В открывшемся окне вносим исходный код Core.sol и всех зависимых контрактов, после чего компилятор задумается на некоторое время, и если вы всё сделали правильно, покажет справа список контрактов на выбор. Выбираем Core.
Далее Ethereum Wallet предложит указать данные для инициализации в соответствии с контрактом Core.sol, а именно название DAO и описание. Вводим любые данные:
И нажимаем кнопку «Deploy». После чего появится всплывающее окно с byte кодом (то, что нам и нужно было увидеть) и запросом на разблокировку аккаунта отправителя.
И теперь плохая новость друзья! В byte code вы увидите примерно следующие фрагменты кода:
48600d54600160a060020a03165b90565b6040805160206004803580820135601f81018490048402850184019095528484526100e594919360249390929184019190819084018382808284375094965050505050505060005433600160a060020a03908116911614156108a057600460005073__AddressMap____________________________633b5908099091836040518360e060020a02815260040180838152602001806020018281038252838181
10002575050604051519150610ccb9050565b610c486004356040805160e060020a63a616695702815260066004820152600160a060020a0383166024820152905160009173__AddressList___________________________9163a61669579160448181019260209290919082900301818660325a03f415610002575050604051519150610ccb9050565b6040518080602001
Библиотеки требуют своего предварительного создания в сети и внесения в ручном режиме адреса библиотеки в Byte code зависимого контракта. Соответственно, не вздумайте отправлять транзакцию на данном примере, так как контракт будет создан, но не функционален.
Создаем библиотеки в сети Ethereum
Итак, чтобы все-таки создать ядро нашей децентрализованной автономии, требуется сначала создать библиотеки AddressList.sol и AddressMap.sol, после чего внести их адреса в Byte code контракта Core.sol. Давайте попробуем это сделать.
Создаем библиотеку в сети Ethereum AddressList.sol
Дожидаемся, пока контракт будет создан в Blockchain.
Получаем адрес библиотеки в тестовой сети Ethereum: 0xE164DfA637aC82C38F5BcF88f999f4f832Bce443
Создаем библиотеку в сети Ethereum AddressMap.sol
Создание библиотеки AddressMap.sol отличается от AddressList.sol тем, что в AddressMap.sol мы используем библиотеку AddressList.sol. Соответвенно, уже на данном этапе можно увидеть, как вставить адрес библиотеки в Byte код контракта.
Вставляем код библиотеки AddressMap.sol и AddressList.sol и переходим в режим просмотра байт кода.
Копируем байт код в текстовый файл, и далее необходимо найти все участки байт кода формата: «____AddressList_______________» и заменяем его на получившийся адрес без «0х» в начале, т.е. «E164DfA637aC82C38F5BcF88f999f4f832Bce443».
Получившийся байт код копируем обратно в Ethereum Wallet и отправляем транзакцию на создание библиотеки AddressMap.sol.
Если вы все верно сделали, то транзакция будет создана и контракт будет создан без ошибок.
Создаём ядро децентрализованой автономной организации с использованием библиотек Aira AddressMap.sol и AddressList.sol
Итак, теперь у нас есть 2 библиотеки:
Address List = 0xE164DfA637aC82C38F5BcF88f999f4f832Bce443
Address Map = 0xd769eA0bE0c253B2335D4928c93b73e38D3415Ee
Теперь необходимо отправить в компилятор контракта снова полный код Core.sol со всеми зависимостями, выбрать в правом меню Core и указать вводные данные. После чего необходимо перейти во вкладку байт кода и скопировать в текстовый файл получившийся байт код.
В байт коде находим места формата «____AddressList_______________» и «____AddressMap_______________», заменяя их на соответствующие адреса библиотек в сети.
Вот байт код получившийся у меня после замены:
60606040526105ec806100126000396000f3650301c67926cf50606060405260e060020a60003504632f07200981146100475780633b590809146100cc578063815e82be14610121578063904450d2146101d4575b610007565b61038660043560243560408051602081810183526000808352600160a060020a038516815260018681018352845191859020805460029281161561010002600019011691909104601f810184900484028301840190955284825292939092918301828280156105e05780601f106105b5576101008083540402835291602001916105e0565b60408051602060046024803582810135601f81018590048502860185019096528585526103f49583359593946044949392909201918190840183828082843750949650505050505050600061044e838361016b565b60408051602060046024803582810135601f81018590048502860185019096528585526103f695833595939460449493929092019181908401838280828437509496505050505050505b600082600001600050600083604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060009054906101000a9004600160a060020a031690505b92915050565b60408051602060046024803582810135601f81018590048502860185019096528585526103f495833595939460449493929092019181908401838280828437509496505093359350505050604080517ff10e3711000000000000000000000000000000000000000000000000000000008152600285016004820152600160a060020a0383166024820152905173E164DfA637aC82C38F5BcF88f999f4f832Bce4439163f10e371191604482810192600092919082900301818660325a03f415610007575050508083600001600050600084604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a815481600160a060020a03021916908302179055508183600101600050600083600160a060020a031681526020019081526020016000206000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041357805160ff19168380011785555b506104439291505b8082111561044a5760008155600101610372565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103e65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b8280016001018555821561036a579182015b8281111561036a578251826000505591602001919060010190610425565b5050505050565b5090565b604080517f1c0cf852000000000000000000000000000000000000000000000000000000008152600286016004820152600160a060020a0383166024820152905191925073E164DfA637aC82C38F5BcF88f999f4f832Bce44391631c0cf8529160448181019260009290919082900301818660325a03f41561000757505050600083600001600050600084604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a815481600160a060020a0302191690830217905550602060405190810160405280600081526020015083600101600050600083600160a060020a031681526020019081526020016000206000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061041357805160ff191683800117855561036a565b820191906000526020600020905b8154815290600101906020018083116105c357829003601f168201915b505050505090506101ce56
Теперь остается его отправить в режиме байт кода в Ethereum Wallet и создать транзакцию.
Почему-то у меня начал виснуть Ethereum wallet, поэтому результат в виде созданного ядра автономии я покажу через консольный клиент geth.
Для самостоятельный тестов данные созданного контракта в тестовой сети Ethereum:
Адрес контракта Core = 0x69f2C9aCc87EC8217ec7925739018a7ba0870208
Интерфейс = [{«constant»:true,»inputs»:[],»name»:»name»,»outputs»:[{«name»:»»,»type»:»string»}],»type»:»function»},{«constant»:true,»inputs»:[{«name»:»_name»,»type»:»string»}],»name»:»getModule»,»outputs»:[{«name»:»»,»type»:»address»}],»type»:»function»},{«constant»:true,»inputs»:[{«name»:»_module»,»type»:»address»}],»name»:»getModuleName»,»outputs»:[{«name»:»»,»type»:»string»}],»type»:»function»},{«constant»:false,»inputs»:[],»name»:»kill»,»outputs»:[],»type»:»function»},{«constant»:true,»inputs»:[{«name»:»»,»type»:»address»}],»name»:»interfaceOf»,»outputs»:[{«name»:»»,»type»:»string»}],»type»:»function»},{«constant»:true,»inputs»:[],»name»:»founder»,»outputs»:[{«name»:»»,»type»:»address»}],»type»:»function»},{«constant»:false,»inputs»:[{«name»:»_name»,»type»:»string»}],»name»:»removeModule»,»outputs»:[],»type»:»function»},{«constant»:false,»inputs»:[{«name»:»_owner»,»type»:»address»}],»name»:»delegate»,»outputs»:[],»type»:»function»},{«constant»:true,»inputs»:[],»name»:»firstModule»,»outputs»:[{«name»:»»,»type»:»address»}],»type»:»function»},{«constant»:true,»inputs»:[],»name»:»description»,»outputs»:[{«name»:»»,»type»:»string»}],»type»:»function»},{«constant»:true,»inputs»:[{«name»:»_name»,»type»:»string»}],»name»:»isConstant»,»outputs»:[{«name»:»»,»type»:»bool»}],»type»:»function»},{«constant»:true,»inputs»:[],»name»:»owner»,»outputs»:[{«name»:»»,»type»:»address»}],»type»:»function»},{«constant»:false,»inputs»:[{«name»:»_name»,»type»:»string»},{«name»:»_module»,»type»:»address»},{«name»:»_interface»,»type»:»string»},{«name»:»_constant»,»type»:»bool»}],»name»:»setModule»,»outputs»:[],»type»:»function»},{«constant»:true,»inputs»:[{«name»:»_current»,»type»:»address»}],»name»:»nextModule»,»outputs»:[{«name»:»»,»type»:»address»}],»type»:»function»},{«inputs»:[{«name»:»_name»,»type»:»string»},{«name»:»_description»,»type»:»string»}],»type»:»constructor»}]’
Результат: