Блокчейн Ethereum интересен своими смарт-контрактами, а также возможностью создания децентрализованных приложений DApp (Decentralized Application). Однако такому приложению необходимо децентрализованное хранилище данных.

Хранение данных большого объема в блокчейне может стоить немалых денег. На помощь приходят такие децентрализованные хранилища, как Ethereum Swarm («swarm» переводится как «рой», «куча»). Если кратко, то Ethereum Swarm представляет собой программный код, работающий на пиринговой сети Ethereum. Он обеспечивает децентрализованное хранение данных на дисках узлов, владельцы которых отдают свои ресурсы в общее пользование.

В этой статье мы расскажем о том, как установить локальный узел Ethereum Swarm для приватной сети Ethereum с целью тестирования технологии и разработки децентрализованных приложений, хранящих данные в Ethereum Swarm.

Почему для DApp нужно децентрализованное хранилище данных


Блокчейн Ethereum (как и другие блокчейны) представляет собой распределенный журнал, очень хорошо защищенный от подделок и атак со стороны злоумышленников.

Защита эта достигается, с одной стороны, использованием хеширования и криптографических алгоритмов, алгоритмов добавления новых блоков в блокчейн, а с другой — огромным количеством узлов Ethereum, обеспечивающих хранение данных и обработку транзакций. Эти узлы расположены по всему миру. Ни у кого нет достаточно ресурсов, чтобы «сломать» блокчейн, и это обеспечивает доверие к записанной в нем информации.

«SkyNet всюду и нигде единого центра нет. Отключать нечего.» (Терминатор-3: Восстание машин)

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

Где же хранить данные DApp большого объема?

Например, вы собираетесь при помощи блокчейна зафиксировать авторские права на изображения, сохранить навсегда сведения о заказе, сделанном в интернет-магазине, или сохранить сканы бумажных документов. Здесь потребуется какое-то другое хранилище данных.

Конечно, для хранения данных DApp вы можете арендовать сервер, место в облачном хранилище или использовать какое-либо другое традиционное хранилище. Но серверы, облака и хранилища контролируются компаниями или отдельными людьми. Они могут быть заблокированы по какой-либо причине или атакованы злоумышленниками.

При использовании централизованного хранилища теряется основное преимущество DApp — устойчивость к атакам и действиям злоумышленников. Более того, ваше приложение перестает быть децентрализованным. А значит теряется и доверие к DApp. Ведь если заблокировать или нарушить работу централизованного хранилища, пропадет доступ к части информации, зафиксированной DApp при помощи блокчейна, и пропадет весь смысл использования DApp.

Как работает Ethereum Swarm


Представьте себе, что по всеми миру разбросаны десятки тысяч узлов сети Ethereum Swarm, которые предоставляют свои ресурсы для хранения данных, загруженных пользователями. Предполагается, что владельцы узлов будут получать вознаграждение за предоставление ресурсов, при этом стоимость размещения данных будет ниже, чем в традиционных облачных хранилищах.

Когда пользователь загружает файл в сеть Ethereum Swarm, этот файл сначала попадает на один из узлов. Далее файл реплицируется на остальные узлы сети в процессе синхронизации. При этом используется протокол bzz, работающий поверх сети Ethereum.

До тех пор пока работает хоть один узел Ethereum Swarm, загруженный файл остается доступным. Это обеспечивает надежность хранения данных, т.к. практически невозможно вывести из строя или заблокировать огромное количество узлов Ethereum Swarm.

Подробнее обо все этом вы сможете прочитать на сайте Ethereum Swarm.

В документации отмечено, что к настоящему моменту Ethereum Swarm реализован в версии 0.2 как доказательство концепции (POC, proof of concept). В этой версии сохранность загруженных данных не гарантируется. Стабильный релиз ожидается во втором квартале 2018 года, так что ждать осталось недолго. Тогда же планируется создание системы вознаграждений за предоставление ресурсов для сети Ethereum Swarm.

Однако мы не будем ничего ждать, а начнем тестировать Ethereum Swarm прямо сейчас. Мы создадим собственный узел Ethereum Swarm в своей приватной сети Ethereum.

Установка Ethereum Swarm и Geth на Debian и Ubuntu


Я расскажу об установке Ethereum Swarm на серверах Debian и Ubuntu. В целом нужно действовать по этой инструкции, но есть некоторые нюансы.

Установка Go


Очень важно перед началом работ установить Go новой версии, не ниже 1.9.2. В репозитории Debian и Ubuntu могут быть старые версии Go, поэтому устанавливаем из исходников.

Скачиваем и распаковываем исходники под непривилегированным пользователем:

$ curl -O https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.9.2.linux-amd64.tar.gz

Создаем у пользователя каталог go и устанавливаем переменные окружения:

$ mkdir -p ~/go; echo "export GOPATH=$HOME/go" >> ~/.bashrc
$ echo "export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin" >> ~/.bashrc
$ source ~/.bashrc

Проверяем, что переменные окружения установлены:

$ printenv | grep go

PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/home/frolov/go/bin:/usr/local/go/bin
GOPATH=/home/frolov/go

В операционной системе Debian вместо файла .bashrc используйте файл .profile. Можно просто скопировать:

cp .bashrc .profile

Проверяем версию go:

$ go version
go version go1.9.2 linux/amd64

Версия go должна быть не ниже 1.9.2.

Если ранее была установлена старая версия go из репозитория ОС, удаляем ее так:

$ sudo apt-get remove golang-go
$ sudo apt-get remove --auto-remove golang-go

Устанавливаем Geth и Ethereum Swarm


Загружаем исходный код из репозитория:

$ mkdir -p $GOPATH/src/github.com/ethereum
$ cd $GOPATH/src/github.com/ethereum
$ git clone https://github.com/ethereum/go-ethereum
$ cd go-ethereum
$ git checkout master
$ go get github.com/ethereum/go-ethereum

Запускаем компиляцию клиента geth и демона swarm:

$ go install -v ./cmd/geth
$ go install -v ./cmd/swarm

Проверяем версию установленного geth и swarm:

$ geth version
Geth
Version: 1.8.0-unstable
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9.2
Operating System: linux
GOPATH=/home/frolov/go
GOROOT=/usr/local/go

$ swarm version
Swarm
Version: 1.8.0-unstable
Network Id: 0
Go Version: go1.9.2
OS: linux
GOPATH=/home/frolov/go
GOROOT=/usr/local/go

Подготовка приватного блокчейна для запуска Ethereum Swarm


Прежде всего, создайте в домашнем каталоге пользователя файл genesis.json:

{
  "config": {
     "chainId": 1907,
     "homesteadBlock": 0,
     "eip155Block": 0,
     "eip158Block": 0
  },
  "difficulty": "40",
  "gasLimit": "5100000",
  "alloc": {}
}

Далее создайте в домашнем каталоге подкаталог node1:

$ mkdir node1

Инициализацию узла можно сделать при помощи пакетного файла init_node.sh:

geth --datadir node1 account new
geth --datadir node1 init genesis.json

При запуске этого файла будет создан аккаунт и запрошен пароль, который вам необходимо сохранить в безопасном месте.

Создайте файл start_node.sh для запуска узла:

geth --datadir node1 --nodiscover --mine --minerthreads 1 --maxpeers 0 --verbosity 3 --networkid 98765 --rpc --rpcapi="db,eth,net,web3,personal,web3" console

Запустите этот файл и дождитесь завершения генерации DAG.

С помощью файла attach_node.sh вы сможете открыть консоль geth и подключиться к приватному узлу:

geth --datadir node1 --networkid 98765 attach ipc://home/frolov/node1/geth.ipc

Запуск демона swarm


Здесь вам потребуется адрес аккаунта, созданного на этапе инициализации узла. Если вы его не сохранили, ничего страшного. Просто зайтите в консоль geth, открытую с помощью скрипта attach_node.sh, и выдайте там следующую команду:

> web3.eth.accounts
["0xcd9fcb450c858d1a7678a2bccf36ea5decd2b09b"]

Команда покажет адрес созданных учетных записей. Сразу после инициализации там будет только один адрес.

Для запуска демона Ethereum Swarm в режиме единственного узла (Singleton) подготовьте командный файл swarm_start.sh:

swarm --bzzaccount cd9fcb450c858d1a7678a2bccf36ea5decd2b09b --datadir "/home/ethertest/data/node1" --maxpeers 0 -nodiscover --verbosity 4 --ens-api /home/ethertest/data/node1/geth.ipc

Укажите в нем адрес аккаунта, созданного на вашем узле, без «0x».

При запуске демона вам будет нужно ввести пароль от созданного ранее аккаунта:

$ sh swarm_start.sh
Unlocking swarm account 0xCD9Fcb450C858D1A7678a2bCCf36EA5decd2B09B [1/3]
Passphrase:

Загружаем файл в Ethereum Swarm


Проще всего загрузить файл с помощью команды swarm с параметром up. Дополнительно нужно указать путь к загружаемому файлу:

$ swarm up start_node.sh
f2073b8f0cf0cfe1e165060882da71a37bb6fd97bdec6be71b4f66ebcf0aba9f

Данная команда вернет хеш загруженного файла. Хеш можно использовать для чтения файла. Вы можете это сделать с помощью команд wget или curl:

$ wget http://localhost:8500/bzz:/f2073b8f0cf0cfe1e165060882da71a37bb6fd97bdec6be71b4f66ebcf0aba9f/

$ curl http://localhost:8500/bzz:/f2073b8f0cf0cfe1e165060882da71a37bb6fd97bdec6be71b4f66ebcf0aba9f/

Команда wget позволяет сохранить содержимое файла на локальном диске. Используйте параметр -O, чтобы задать имя файла. Команда curl выведет содержимое файла на консоль, поэтому в таком виде ее не следует использовать для просмотра содержимого бинарных файлов. В конце URL необходим слеш, иначе произойдет редирект.

Когда файл загружается в Ethereum Swarm описанным выше образом, для него создается и сохраняется так называемый манифест. Это заголовок, описывающий содержимое, доступное в хранилище по заданному идентификатору.

Ниже мы загрузили файл Net-Ethereum-0.28.tar.gz с помощью простой команды swarm up:

$ swarm up Net-Ethereum-0.28.tar.gz
8da3713d49c62740f5ab594b06173975ac97cb3dd3848ae996484ec264a10e2f

Теперь, указав протокол bzz-list, мы можем просмотреть манифест:

$ curl http://localhost:8500/bzz-list:/8da3713d49c62740f5ab594b06173975ac97cb3dd3848ae996484ec264a10e2f/
{"entries":[{"hash":"543ee6e744f93de76ac132b8ab71982e32beaf90d1005e771dde003b2a4a54c3","path":"/","contentType":"application/gzip","mode":420,"size":12403,"mod_time":"2018-01-13T14:57:54+03:00"}]}

Манифест будет показан в формате JSON.

В манифесте хранится пусть к файлу (имя файла), его размер, тип (Content Type), дата и время модификации, а также хеш файла.

Чтобы извлечь содержимое файла по его идентификатору и сохранить под именем t.tar.gz, сделайте так:

$ wget -O t.tar.gz http://localhost:8500/bzz:/8da3713d49c62740f5ab594b06173975ac97cb3dd3848ae996484ec264a10e2f/ 

Загрузка каталогов с подкаталогами


Для рекурсивной загрузки каталога вместе с его содержимым в хранилище Ethereum Swarm укажите параметр --recursive:

$ swarm --recursive up Net-Ethereum/
4fb1f2270381c022461037151f70ce081082f0ae1a2a23d8c7ea602da69b4115

В манифесте будет показана информация обо всех файлах загруженного подкаталога:

Скрытый текст
$ curl http://localhost:8500/bzz-list:/4fb1f2270381c022461037151f70ce081082f0ae1a2a23d8c7ea602da69b4115/
{"common_prefixes":["blib/","lib/","t/"],"entries":[{"hash":"feea799e7d53fa8465489baf13f66becda29f94695d6ddad161af4bfc51556b4","path":"Changes","mode":420,"size":314,"mod_time":"2018-01-13T14:56:39+03:00"},{"hash":"11fe71c1ab60779eb7b055c96a6fe0fe88d498ca60ece51d79db62d6677f1bf9","path":"MANIFEST","mode":420,"size":241,"mod_time":"2018-01-09T18:38:06+03:00"},{"hash":"1fa030391282faa61b01c1ca07bc483db54c04173801e90477be0919bb9fa2b8","path":"META.json","contentType":"application/json","mode":420,"size":822,"mod_time":"2018-01-09T18:38:06+03:00"},{"hash":"261487aa0cb7218ee3953ac1a67b757cc59d19aadca0b6b4272b8751ba4dfe64","path":"META.yml","mode":420,"size":470,"mod_time":"2018-01-09T18:38:06+03:00"},{"hash":"4a4ef37333596472a6a5bcee20456621f039f2f3bb9a331f0afc289a1e122af5","path":"MYMETA.json","contentType":"application/json","mode":420,"size":862,"mod_time":"2018-01-13T14:57:41+03:00"},{"hash":"374603f37acd044b3605dc0c051b9996625c9dfcce4919e80ba84bda21b4bbcd","path":"MYMETA.yml","mode":420,"size":510,"mod_time":"2018-01-13T14:57:41+03:00"},{"hash":"18cdc7c003810e53974187bcee1b7d2c536c4b952fe0f199d264e5af21d6548c","path":"Makefile.PL","contentType":"text/x-perl; charset=utf-8","mode":420,"size":664,"mod_time":"2018-01-13T12:24:37+03:00"},{"hash":"44481e1b88e2c00cd30717108d8490d839358bb4cb9895962e4fa64c2be6ed73","path":"Makefile","mode":420,"size":27605,"mod_time":"2018-01-13T14:57:41+03:00"},{"hash":"543ee6e744f93de76ac132b8ab71982e32beaf90d1005e771dde003b2a4a54c3","path":"Net-Ethereum-0.28.tar.gz","contentType":"application/gzip","mode":420,"size":12403,"mod_time":"2018-01-13T14:57:54+03:00"},{"hash":"c6ff1f1742a156aeaf98fcfb480cfb168857029a8790ac8c3bc7a00aef415021","path":"README","mode":420,"size":1303,"mod_time":"2018-01-13T14:57:31+03:00"},{"hash":"011b4d03dd8c01f1049143cf9c4c817e4b167f1d1b83e5c6f0f10d89ba1e7bce","path":"pm_to_blib","mode":420,"mod_time":"2018-01-13T14:57:49+03:00"}]}


Другие возможности Ethereum Swarm


В этой статье я не рассказал обо всех возможностях Ethereum Swarm, ограничившись лишь самым необходимым.

Помимо загрузки отдельных файлов и содержимого каталогов вы можете добавлять данные к манифесту. При этом создается новый элемент данных с дополненным манифестом и с добавленными файлами.

Есть возможность загружать файлы без манифеста, а также считывать их в так называемом «сыром» (raw) виде.

При считывании файла можно указывать его имя (полностью или частично). При этом будет задействован сервис имен ENS (Ethereum Name Service). Такая возможность позволит вам получить только некоторые файлы из блока, объединенного общим манифестом.

Я также не описал SWarm Accounting Protocol (SWAP) и некоторые другие возможности. Проект Ethereum Swarm активно развивается, в нем обязательно появится еще что-нибудь интересное для разработчиков децентрализованных приложений.

Модуль Perl Net::Ethereum::Swarm


Для того чтобы работать с децентрализованным хранилищем данных Ethereum Swarm в системах, написанных на языке Perl, я разработал и выложил на CPAN модуль Net::Ethereum::Swarm.

С помощью этого модуля вы сможете загружать в Ethereum Swarm текстовые и бинарные файлы, получать манифест для загруженных данных, а также загружать файлы из Ethereum Swarm по их идентификатору.

Модуль Net::Ethereum::Swarm работает с узлом Ethereum Swarm с помощью HTTP-запросов GET и POST. Использование запросов описано в разделе The HTTP API документации.

Взаимодействие через HTTP-запросы можно легко реализовать практически на любом языке программирования.

Другие мои статьи о блокчейне и смарт-контрактах Ethereum


Комментарии (7)


  1. Napitok
    16.01.2018 12:15

    Спасибо большое за очень интересную статью! При чтении возникло несколько вопросов:
    1) Правильно ли я понимаю, что в случае частной сети объем данных, которые можно сохранить определяется ресурсами которые участники этой приватной сети выделят?
    2) Если общедоступные сети (или возможно планируются), которые будут работать с этой технологией и какая мотивация для обычных пользователей отдавать свои ресурсы под эту систему?


    1. AlexandreFrolov Автор
      16.01.2018 12:47

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

      Что же касается второго вопроса, то насколько я понял из документации, в следующем релизе Ethereum Swarm предполагается внедрить систему мотивации для того чтобы отдавать свои ресурсы в пользование. Возможно, эта мотивация будет работать аналогично мотивации для майнинга — предоставляющие ресурсы и участвующие в процессе будут получать вознаграждение в эфирах.


  1. Pilat
    16.01.2018 16:28

    Правильно ли я понимаю, что для того, чтобы мои документы были мне доступны всегда, они должны копироваться на компьютеры десятков или тысяч пользователей, так чтобы хотя бы один из них был всегда в сети?


    Если это справедливо для меня, и справедливо для всех остальных, то мне надо прикупить дополнительно столько же винчестеров, сколько людей должны принять мои файлы на хранение? То есть был у меня диск в домашнем компьютере, диск бэкапа. Теперь у меня десятки дисков должны непрерывно работать и синхронизироваться?


    1. AlexandreFrolov Автор
      16.01.2018 17:05

      Да, децентрализованное хранилище предполагает, что ваши файлы будут размножены по узлам сети, расположенным по всему миру. Будет храниться много копий ваших файлов.

      Это не имеет прямого отношения к бекапу, тут речь идет о размещении данных, которые невозможно удалить или изменить, и с которыми будет работать децентрализованное приложение. Для личного или корпоративного бекапа вы можете использовать обычные технологии, такие как NAS, серверы бекапов, облака или просто диски.

      Например, если вам нужно заверить авторство на изображение, то, говоря упрощенно, в децентрализованное хранилище будет записан файл изображения, а ссылка на него и фамилия автора будет находиться в блокчейне.

      Чтобы пользоваться Ethereum Swarm в том виде, в котором его планируется сделать, вам не нужно создавать собственный узел и выделять для сети дисковую память. Вы сможете просто записывать файлы в хранилище для общего доступа за определенную плату. Это доступно уже сейчас в тестовом виде в сети Rinkeby.

      Но если вы заходите зарабатывать на размещении данных сети, то вам потребуется создать собственный узел. Детали, по-видимому, будут известны с выходном новой версии Ethereum Swarm.


      1. Pilat
        17.01.2018 00:49

        Хотелось бы конкретные цифры увидеть. Понимаю, что это не к Вам вопрос, но все рассуждения о децентрализованности хранения и обработки могут натолкнуться именно на то что я описал — необходимость увеличить вычислительные мощности на порядки, или платить деньги компаниям типа Амазона — но это уже та себе децентрализация получается.


        1. AlexandreFrolov Автор
          17.01.2018 09:11

          Да, в зависимости от стоимости можно принимать решение, какую информацию имеет смысл хранить в блокчейне и Ethereum Swarm, а какую — нет. В блокчейне это может быть сотня-другая рублей за текст размером в полкилобайта, а для хранилища — будем ждать рабочего релиза с системой вознаграждений!


          1. AlexandreFrolov Автор
            17.01.2018 09:56

            По стоимости тут еще такой момент — зависит от цели использования технологии блокчейн. Например, вы заверяете сделку с помощью блокчейн и смарт-контрактов. При этом вы экономите на юристах, нотариусе, на приобретении квалифицированной подписи и различных платежах за оформление документов.

            Разумеется, речь идет об экономии весьма значительных сумм по сравнению со стоимостью записи данных в блокчейн и децентрализованное хранилище.

            Но надо также понимать, что пока не принято соответствующее законодательство, в случае каких-либо проблем со сделкой или смарт-контрактами вы не получите помощи от государственных институтов. С другой стороны, если речь идет об относительно небольших сделках, то судиться все равно будет далеко не каждый. На это и рассчитывают мошенники, обманывая людей на небольшие суммы.