Screenshot from 2016-06-15 13:32:24

Использование библиотек при работе с автономными контрактами на платформе Ethereum

Что такое библиотеки на платформе 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»

Ethereum wallet deploy new contract
Ethereum wallet deploy new contract

 

В открывшемся окне вносим исходный код Core.sol и всех зависимых контрактов, после чего компилятор задумается на некоторое время и если вы всё сделали правильно покажет справа список контрактов на выбор. Выбираем Core.

Ethereum-wallet-chooise-contract

 

Далее Ethereum Wallet предложит указать данные для инициализации в соответствии с контрактов Core.sol,  а именно название DAO и описание. Вводим любые данные:

ethereum-wallet-deploy-core

И нажимаем кнопку «Deploy». После чего появится всплывающее окно с byte кодом (то, что нам и нужно было увидеть) и запросом на разблокировку аккаунта отправителя.

Screenshot from 2016-06-15 13:32:24

 

И, теперь плохая новость друзья! В byte code вы увидите примерно следующие фрагменты кода:

48600d54600160a060020a03165b90565b6040805160206004803580820135601f81018490048402850184019095528484526100e594919360249390929184019190819084018382808284375094965050505050505060005433600160a060020a03908116911614156108a057600460005073__AddressMap____________________________633b5908099091836040518360e060020a02815260040180838152602001806020018281038252838181
10002575050604051519150610ccb9050565b610c486004356040805160e060020a63a616695702815260066004820152600160a060020a0383166024820152905160009173__AddressList___________________________9163a61669579160448181019260209290919082900301818660325a03f415610002575050604051519150610ccb9050565b6040518080602001

Библиотеки требуют  своего предварительного создания в сети и внесения в ручном режиме адреса библиотеки в Byte code зависимого контракта. Соответственно не вздумайте отправлять транзакцию на данном примере, так как контракт будет создан, но не функционален.

Создаем библиотеки в сети Ethereum

Итак, чтобы все таки создать ядро нашей децентрализованной автономии требуется сначала создать библиотеки AddressList.sol и AddressMap.sol, после чего внести их адреса в Byte code контракта Core.sol. Давайте попробуем это сделать.

Создаем библиотеку в сети Ethereum AddressList.sol

Address List deploy

Дожидаемся, пока контракт будет создан в Blockchain

Address List deploy 2

 

Получаем адрес библиотеки в тестовой сети Ethereum: 0xE164DfA637aC82C38F5BcF88f999f4f832Bce443

Создаем библиотеку в сети Ethereum AddressMap.sol

Создание библиотеки AddressMap.sol отличается от AddressList.sol тем, что в AddressMap.sol мы используем библиотеку AddressList.sol. Соответвенно, уже на данном этапе можно увидеть как вставить адрес библиотеки в Byte код контракта.

Deploy byte code Address map
Deploy byte code Address map

Вставляем код библиотеки AddressMap.sol и AddressList.sol и переходим в режим просмотра байт кода.

Копируем байт код в текстовый файл и далее необходимо найти все участки байт кода формата: «____AddressList_______________» и заменяем его на получившийся адрес без «0х» в начале, т.е.  «E164DfA637aC82C38F5BcF88f999f4f832Bce443″. 

Replace Address list address in Address map library

Получившийся байт код копируем обратно в Ethereum Wallet и отправляем транзакцию на создание библиотеки AddressMap.sol

Если вы все верно сделали, то транзакция будет создана и контракт будет создан без ошибок.

Deploy Address map confirming

Создаём ядро децентрализованой автономной организации с использованием библиотек 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»}]’

Результат:

core geth qa 1

Screenshot from 2016-06-15 14:44:09