Зачем этот рассказ? Когда я изучал 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-шифрования выполняется возведение в степень, а
то получается, что
Таким образом, например, кто угодно может проверить, что баланс моего аккаунта был корректно умножен, причем нет необходимости разглашать, сколько денег у меня было в аккаунте! Продолжая эту идею, можно создать криптовалюту с закрытой информацией о балансах и платежах (и она уже есть — Zcash) и вообще скрыть аргументы вычислений в смарт-контракте.
У блокчейнов есть общие для сети параметры, записанные в программном коде самих клиентов сети, например сколько транзакций включать в блок. Обычно их изменение требует принятия сообществом участников сети этих правок (которое выражается в обновлении кода) и грозит форками сети (когда часть участников решают не принимать правку, они просто продолжают работать на «старом» коде). Эти проблемы пытается решить саморегулирование, например блокчейн Tezos. Суть в том, что за каждую правку можно будет проголосовать своими средствами (без их потери, конечно).
Заключение
Итого технологии прошли следующий путь:
подпись транзакций (ассиметричная криптография) + открытость транзакций + упорядочивание транзакций + расширение операций до машины Тьюринга + (нулевое разглашение | саморегулирование | ...)
Пара слов о ландшафте блокчейнов. Уже говорилось, что есть много криптовалют, представляющих из себя эфириум-контракты, т. е. использующих блокчейн Эфириума. Но есть проекты помимо Биткойна и Эфириума — они могут отличаться как в деталях (например, форки), так и довольно сильно, пытаясь создать принципиально новые блокчейны, например EOS.
Бонус
Об изучении смарт-контрактов Эфириума. Инфраструктура местами сырая (ее не очень удобно использовать), но достаточно надежная. Вот набор ссылок, по которым изучал написание и безопасность смарт-контрактов я (Не забываем про безопасность! На кону деньги!). Рекомендую читать в такой последовательности:
- Bitcoin: A Peer-to-Peer Electronic Cash System — секции 1—8
- Just Enough Bitcoin for Ethereum
- Ethereum White Paper
- Если сразу хочется немного практики: The Hitchhiker’s Guide to Smart Contracts in Ethereum
- Solidity Documentation
- Ethereum Natural Specification Format
- contracts/ в Zeppelin Solidity
- Onward with Ethereum Smart Contract Security
- Ethereum Contract Security Techniques and Tips
- Только релевантное из Hacking, Distributed
Talkerbox
Огромное спасибо! Вот та статья, которую я ждал, чтобы быстро понять основы всех этих новых популярных штук.