Зачем этот рассказ? Когда я изучал blockchain по открытым источникам, например по Википедии, информация казалась отрывочной и бессвязной. Прошло время, прежде чем она сложилась в целостную картину. Кажется, я знаю, в каком порядке и какими словами описать введение в blockchain, чтобы любой профессиональный разработчик смог понять общую картину за 1—1,5 часа. В тексте будут некоторые упрощения. Понятно, что в любой теме есть много деталей, куда можно при желании погрузиться.


Начнем. Уже давно существует ассиметричная криптография. Напомню, есть открытый и закрытый ключи. Шифруем открытым, расшифровываем закрытым. Или наоборот. Один из другого получить невозможно. Таким образом, уже пользуясь только ассиметричной криптографией, я могу послать кому-то сообщение, например: «Я перевел 100 рублей», при этом все будут знать, что его послал именно я и что оно доставлено без изменений.


Пусть десять человек договорились, что у каждого из них по миллиону новой валюты. Каждый из них может удостовериться (и все могут удостовериться), что именно он послал 300 тысяч этой валюты другому. При этом неизвестно, были ли у него в распоряжении эти 300 тысяч или нет. Чтобы получить это знание, можно узнать балансы каждого. Для этого надо просто математически сложить все приходы денег и вычесть все расходы человека. Таким образом, требуются все операции прихода и расхода. Отсюда возникает public ledger, публичная бухгалтерская книга. Она позволит сказать, может ли человек послать 300 тысяч.


Bitcoin: начало


Остается одна проблема: что, если я посылаю все свои деньги одновременно двоим? Это двойное расходование, или double-spending. Конечно, эти двое не должны одновременно получить на счета сумму, равную моему балансу до операции. И выяснять между собой, кому все-таки пришел платеж, им тоже неудобно. Ориентироваться на отметки времени (смотреть, кому я послал деньги раньше) ненадежно. Есть решение: упорядочить транзакции. Тогда точно будет понятно, что первый платеж ушел Васе, а второго я просто не могу сделать: нет денег. Но теперь непонятно, кто будет говорить, в каком порядке идут транзакции. В банках и прочих централизованных системах есть доверенное лицо — сам банк, единая точка отказа и точка доверия. Банк говорит, кому ушли мои деньги. В блокчейне единого доверенного лица нет. Это может быть бо?льшая часть сети (понятно, что абсолютно всей сети, ведь каждому участнику доверять нельзя: среди них наверняка есть мошенники). Предполагается, что она не управляется одним лицом и что большинство участников действуют сугубо в своих финансовых интересах.


Но проблема упорядочивания транзакций всё еще не решена: нужен так называемый консенсус среди участников сети. Решением этой проблемы занимается один из ключевых алгоритмов каждого конкретного блокчейна — алгоритм консенсуса.


Прежде чем мы поговорим о конкретном алгоритме консенсуса, скажу пару слов о пресловутых блоках блокчейна. Блоки — техническая мера, пакетная обработка (batching), чтобы считать консенсус «пачкой» и «размазывать» прочие накладные расходы работы сети по нескольким транзакциям. Порядок транзакций внутри блока определяет один участник сети — тот, кто формирует блок (майнер). А вот порядок блоков определяется уже алгоритмом консенсуса. Алгоритмы консенсуса существуют довольно давно. Например, алгоритмы Paxos и Raft в мультимастер-NoSQL-системах. Но для сети с миллионом равноправных участников они вряд ли подойдут.


В Bitcoin был предложен революционный по тем временам алгоритм — консенсус через доказательство работой (proof of work, PoW). Новые блоки формируются одновременно многими участниками сети — майнерами. Нужно решить, чей блок брать в качестве следующего. Чтобы блок стал следующим блоком цепи, майнер должен произвести специально подобранное очень трудоемкое хеширование. Блок (вместе с инкрементируемым числом, nonce) хешируется до тех пор, пока хеш, будучи рассмотренным как большое число, не удовлетворит определенным условиям, например пока не будет содержать 10 нулей в начале. Это потребует миллиардов хеширований — именно той работы, которой майнер «доказывает» свой блок. А проверить правильность работы очень легко: нужно всего одно хеширование. Важно понимать, что работа подбирается так, чтобы во всей сети (т. е. среди тысяч майнеров!) появлялся в среднем всего один блок за десять минут (средний интервал возникновения блоков в Bitcoin). При таких условиях вероятность коллизий, т. е. одновременного представления двух и более блоков в качестве следующего, крайне снижается.


Однако вероятность коллизий всё еще остается. На этот случай есть следующее правило: участники сети принимают тот блок, что образует наиболее длинную цепь (одна из альтернатив станет длиннее, когда появится еще один блок).


На самом деле есть не цепь, а направленный граф без циклов (DAG) со множеством ответвлений и цепей, а цепью обычно называют «общепринятую историю» — цепь с наибольшей длиной. Поскольку консенсус может быть достигнут не сразу, а за несколько блоков, следует подождать. Для уверенности, что тебе не сделают double-spending, обычно ждут шесть блоков (в Биткойне — час, в Эфириуме — несколько минут).


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


Кстати о майнинге. Нужно понимать, что основная работа майнера — это лютое хеширование нового блока, ассиметричной криптографии там нет, она нужна только для проверки транзакций перед добавлением в блок. В Bitcoin используется хеш SHA-256, в Ethereum — Keccak-256. Если майнить одному — придется в среднем очень долго жить на рисе и воде, прежде чем получишь блок (блок — раз в десять минут, конкурентов — сотни тысяч!). Поэтому майнеры объединяются в пулы. В пуле награда как-то (есть разные подходы) распределяется между участниками, т. е. ты чаще получаешь деньги (конечно, меньшие, чем награда за блок). То есть и риск, и выгода «размазываются». При стремлении времени к бесконечности мат. ожидание прибыли от майнинга в пуле (если пренебречь комиссией пула) равно мат. ожиданию прибыли от одиночного майнинга.


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


Итак, мы получили технологию блокчейна биткойна.


Смарт-контракты и ICO


Идем дальше. В Биткойне над каждым аккаунтом выполняются две операции: сложение и вычитание, и они проверяются всеми желающими, прежде всего майнерами. Но что, если добавить внутренние переменные к аккаунту (storage), а к операциям добавить, например, сравнения. Предположим, я хочу перестать принимать деньги на свой аккаунт, когда наберу на нем 10М — т. е. получается уже не просто добавление денег к балансу аккаунта, а добавление при условии. Развивая идею, получаем машину Тьюринга, причем детерминированную — т. е. всё так же все могут проверить состояние аккаунта, — и получаем смарт-контракт. Далее под смарт-контрактами будем понимать смарт-контракты сети Эфириум (Ethereum) как самые популярные на момент написания статьи.


Детерминированность означает, что для одних и тех же аргументов транзакции и одного и того же исходного состояния storage на выходе получаем одинаковый результат и одинаковые изменения, произведенные в storage. Только при таких условиях сеть сможет прийти к консенсусу по каждой транзакции. Нужно понимать, что смарт-контракт довольно изолирован от внешнего мира в силу требования детерминированности, проверяемости и децентрализованности. Например, он не может дернуть Web API в децентрализованном стиле (есть варианты решения, так называемые оракулы, но там всё непросто, и это отдельная тема). Кроме того, контроль контракта над внешним миром также крайне ограничен, например трудно снять квартиру через смарт-контракт, обменяв криптовалюту на электронный ключ (вопреки восторженным проспектам, встречающимся в Сети): я все равно должен доверять арендодателю, чтобы знать, что, когда я подойду к двери, поверх электронного замка не будет висеть большой амбарный.


Чтобы получить результаты работы контракта (новый баланс или изменения storage), ноды сети вынуждены выполнить операции, в нем прописанные. Вычисление на множестве нод не может быть бесплатным, поэтому в Эфириуме введено понятие газ (gas) — чтобы не хардкодить комиссии за вычисления в криптовалюте, а позволить пользователю посчитать объем вычислений и установить их цену. Эта конструкция — дополнительный уровень косвенности, он дает пользователю выбрать между дешевой транзакцией и быстрой транзакцией.


Когда деньги посылаются в контракт как в аккаунт (т. е. просто по адресу) — срабатывает точка входа по умолчанию: fallback function. В отличие от аккаунта, у контракта более одной точки входа — это методы, которые могут принимать параметры. Чтобы изменить контракт (неважно, через какую точку входа), придется посылать транзакцию в сеть: она должна зафиксировать изменения. А просто что-то глянуть в режиме read only можно и локально, имея актуальный блокчейн. Также, в отличие от аккаунтов, у контрактов нет закрытого ключа. Напрямую с их баланса не снять средства — это делают с помощью явно прописанных методов, на которые, конечно, нужно накладывать ограничения безопасности, например проверять адрес того, кто их вызывает.


Итого поверх блокчейна в стиле биткойна мы получили технологию смарт-контрактов.


На смарт-контрактах Эфириума основано много криптовалют, или так называемых токенов. Да, обычно такая криптовалюта — это просто эфириум-контракт (один!). Балансы — это записи в storage контракта в виде map, а передача валюты от одного к другому — это:


map[Alice] –= payment;
map[Bob] += payment;


Для них не нужно своего майнинга и своей сети: они пользуются инфраструктурой Эфириума. ICO/ITO на Эфириуме — это обмен эфира (криптовалюты сети Эфириум) на криптовалюту (токены). Стандарт ERC20 говорит, какие методы должны быть определены у контракта криптовалюты, за счет чего многие криптовалюты могут быть поддержаны биржами и сразу поддерживаются электронными кошельками, работающими с Эфириумом.


Дальнейшее развитие


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


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


$(Y*X)^{a} == Y^{a} * X^{a},$


то получается, что


$encrypted(Y*X) == encrypted(Y)*encrypted(X).$


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


У блокчейнов есть общие для сети параметры, записанные в программном коде самих клиентов сети, например сколько транзакций включать в блок. Обычно их изменение требует принятия сообществом участников сети этих правок (которое выражается в обновлении кода) и грозит форками сети (когда часть участников решают не принимать правку, они просто продолжают работать на «старом» коде). Эти проблемы пытается решить саморегулирование, например блокчейн Tezos. Суть в том, что за каждую правку можно будет проголосовать своими средствами (без их потери, конечно).


Заключение


Итого технологии прошли следующий путь:


подпись транзакций (ассиметричная криптография) + открытость транзакций + упорядочивание транзакций + расширение операций до машины Тьюринга + (нулевое разглашение | саморегулирование | ...)


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


Бонус


Об изучении смарт-контрактов Эфириума. Инфраструктура местами сырая (ее не очень удобно использовать), но достаточно надежная. Вот набор ссылок, по которым изучал написание и безопасность смарт-контрактов я (Не забываем про безопасность! На кону деньги!). Рекомендую читать в такой последовательности:


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


  1. Talkerbox
    25.10.2017 13:47

    Огромное спасибо! Вот та статья, которую я ждал, чтобы быстро понять основы всех этих новых популярных штук.


  1. valentyn
    25.10.2017 14:19

    Один из другого получить невозможно

    Возможно я ошибаюсь, но в криптографии на эллиптических кривых (она и используется в bitcoin) получить публичный ключ из приватного — элементарная операция?


    1. therealal Автор
      25.10.2017 18:26

      Я имел ввиду RSA.


  1. myxo
    25.10.2017 14:21

    Отличное видео по теме.


  1. rkfg
    25.10.2017 14:21

    Поскольку в ходе AES-шифрования выполняется возведение в степень

    Разве? Я думал, там сеть Фейстеля, где выполняется только XOR и сложение по модулю 2??.


    1. therealal Автор
      25.10.2017 18:27

      Да, тут ошибка. Имелось ввиду RSA.


  1. paluke
    25.10.2017 17:46

    Почему-то в руководствах "bitcoin для чайников" рассказывают про хеширование и подписи, но нигде не объясняют, как сеть организована. Ну намайнил кто-то блок — как все остальные об этом узнают? У каждого майнера есть список ip адресов всех остальных майнеров?


    1. therealal Автор
      25.10.2017 18:32

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


    1. rkfg
      25.10.2017 18:39

      Есть список захардкоженных узлов (раньше для сбора этих узлов применялся IRC-канал, теперь же там DNS-имена), к которым подключается новый узел, в протоколе определены сообщения типа «запросить другие известные узлы», и те захардкоженные (бутстрап-ноды) сообщают запросившему случайно выбранные адреса из известных им (т.е. адреса других к ним когда-либо подключавшихся). Обычно принимается модель «малого мира», когда каждый узел подключен к небольшому числу других, 8-20 примерно, но в целом получается достижимость от любого узла к любому через цепочку. Это позволяет оптимизировать трафик и, наверно, уменьшить вероятность кластеризации. Трафик оптимизируется, т.к. если узел получает уже пересланное им сообщение (через кольцо других узлов), он его снова не будет перепосылать, и если бы он был связан с большим числом узлов, такое «эхо» было бы намного сильнее.


      Далее, когда блок намайнен, майнер его просто посылает подключенным к нему узлам, если не ошибаюсь, даже не всем сразу, а 3-4 случайно выбранным из них. Они рассылают своим «соседям» и т.д., в итоге, вся сеть получает новые данные через некоторое время. Но не принимайте мои слова на веру, я давно это всё читал и мог некоторые вещи забыть или исказить. Вообще, с удовольствием бы почитал про низкоуровневую архитектуру крупных P2P-сетей и как там решаются разного рода проблемы. Например, мне совсем неочевидно, как можно гарантировать полную связность, т.е. отсутствие обособленных островков, ни один из пиров в которых не соединён с остальной частью сети. Скорее всего, это объясняется через вероятности, но оно не очевидно.


      1. paluke
        26.10.2017 07:28

        Гы. Распределенная сеть и захардкоженные адреса узлов для подключения… Сразу же возникает вопрос, а кто их контролирует…


        1. rkfg
          26.10.2017 09:48

          Какие-то узлы всё равно должны быть первыми, когда клиент запускается первый раз и вообще никого не знает. В DHT точно так же, например, часто в качестве бутстрап-ноды используется router.utorrent.com и router.bittorrent.com. Конечно, если спецслужбы контролируют большинство этих нод, можно «заманить» новых клиентов в подконтрольный им кластер, но вообще это маловероятно. Скорее всего, бутстрап-адреса раскиданы по всему миру, и клиент выбирает из них несколько случайных, чтобы снизить вероятность описанной ситуации.


        1. worldmind
          26.10.2017 10:11

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


    1. BoogerWooger
      25.10.2017 19:10

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


  1. geekmetwice
    26.10.2017 00:27

    Чисто экономический вопрос: видя, как целые фермы(!!) видеокарт майнят валюту, имеет ли вообще смысл «простым смертным» в это ввязываться с единственной видюхой в ПК и «мамкиным электричеством»? :) Т.е. когда эл.энергию оплачиваешь из своего кармана.


    1. therealal Автор
      26.10.2017 10:51

      Если присоединяешься к пулу, и юнит-экономика сходится (т.е. достаточна ли энергоэффективность, вне зависимости от hash rate), то почему бы и нет. Правда не уверен, что в случае CPU она сойдется. Может на bitcoin gold.


    1. pkruglov
      26.10.2017 12:23

      с единственной видюхой в ПК и «мамкиным электричеством»? :) Т.е. когда эл.энергию оплачиваешь из своего кармана.

      С такой конфигурацией точно нет. Вот тут whattomine.com можно посчитать текущую доходность в зависимости от конфига, валюты и цены электричества.


  1. Furriest
    26.10.2017 04:26

    А есть ли какая-нибудь статья или разъяснение про масштабируемость блокчейнов?

    Вот как я сейчас это вижу — при фактической маргинальности биткойна и нескольких сотнях тысяч транзакций в сутки текущий размер базы 164 GB. Если послушать евангелистов, которые пророчат замену криптовалютами на основе блокчейна текущей финансовой системы, то такой криптовалюте придется обрабатывать десятки тысяч транзакций в секунду, т.е. несколько миллиардов транзакций в сутки. Естественно, в этом случае обеспечить наличие полной базы у каждого из участников платежной системы малореально (если, конечно, не предполагать взрывного роста технологий передачи и хранения данных). А если не хранить базу, то получается, опять же, схема доверия каким-то узлам, которые ее хранят, т.е. мы фактически строим те же «банки» заново.

    С интересом бы почитал, как планируют решать эту проблему.


    1. biseptol
      26.10.2017 05:10

      Биткоин — это не замена карточкам и всяким пейпалам, это способ хранения и передачи ценности в распределенной trustless сети, которую (ценность) нельзя [1][2] конфисковать или украсть, и трудно отследить.

      Как решение проблемы «хотим тысячи транзакций в секунду» может сработать Lightning Network [3], но к нему тоже достаточно вопросов: отход от p2p, необходимость замораживания средств в каналах, невозможность получить больше, чем заморожено, и проч.

      [1] www.theregister.co.uk/2017/08/30/ex_cop_jailed_for_not_decrypting_data
      [2] www.xkcd.com/538
      [3] bitcoin.stackexchange.com/questions/43700/how-does-the-lightning-network-work-in-simple-terms


    1. therealal Автор
      26.10.2017 11:05

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

      Проблема масштабируемости состоит из как минимум двух подпроблем: нарастить число транзакций в секунду (TPS) и спасти жесткие диски от сотен гигабайт занятых под блокчейн.

      TPS проще всего наращивается в различных delegated- алгоритмах консенсуса, напр. в EOS, напр. в Ethereum Casper (не совсем delegated, но важно то, что число нод, формирующих блоки, мало и дисциплина формирования довольно упорядочена).

      Серьезно ужать блокчейн — сложнее. Есть различные легковесные решения, но, кажется, там возникает либо проблема эффективности, либо проблема доверия. Есть идеи шардинга, но, напр., в Ethereum оно только на этапе экспериментов github.com/ethereum/wiki/wiki/Sharding-FAQ.


  1. Laserson
    26.10.2017 11:05

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


    1. therealal Автор
      26.10.2017 11:08

      Да, количество участников. Плюс возросшая эффективность майнинга.


    1. pkruglov
      26.10.2017 11:48

      Алгоритм устроен таким образом, чтобы новый блок выходил каждые 10 минут (плюс-минус). Если блоки добывают быстрее 10 минут, то сложность автоматически повышается. Следовательно, чем больше мощностей подключается к майнингу, тем более сложным становится процесс формирования блока и тем меньше получает каждый отдельный майнер. Однако справедлив и обратный процесс: если вдруг майнеров станет меньше, то алгоритм подстроится в обратную сторону.


  1. Wayfarer15
    26.10.2017 19:12

    Я бы предложил автору в том же духе написать книгу, от простого сложного, с упоминанием всех подводных камней (часть которых уже в комментах) и продавать как электронную книгу. Я бы купил.