Источник: https://jysperm.me/2016/05/blockchain-slides/
Эта статья была написана в результате моего обмена технологиями в LeanCloud в конце марта, и предполагает, что читатель уже имеет базовые знания криптологии и предварительное понимание реализации Биткойна.
Блокчейн, также называемый блокчейн, можно рассматривать как HashTree, и поэтому он имеет некоторые свойства, похожие на HashTree:

Изображение из фото:<http://happypeter.github.io/bitcoin_basics/book/017_merkle_tree.html
То есть в деревянной структуре каждый конечный узел имеет дисперсионное значение, а дисперсионное значение неконечного узла происходит от дисперсионного значения всех его непосредственных подузлов, поэтому каждый узел прямо или косвенно содержит информацию обо всех своих подузлов. Таким образом, если дисперсионное значение любого конечного узла изменяется, дисперсионные значения всех его родительских узлов изменяются, и корневые узлы также должны изменяться.
Я могу привести пример приложения HashTree: “100% доказательство резерва”, которое относится к категории “доказательств нулевого знания”. Можно рассмотреть ситуацию, когда владельцу Bitcion для совершения сделки необходимо хранить биткойны на бирже, и, теоретически, биржа может использовать эти деньги (баланс счетов всех пользователей), что пользователи не хотят видеть, а биржа также хочет доказать свою невиновность: биржа сначала публикует адрес биткойнов, который она держит, и все подтверждают, что у биржи действительно есть столько биткойнов в резерве, но как доказать, что эти деньги действительно больше, чем сумма всех остатков пользователей?

Изображение из фото:<http://blog.bifubao.com/2014/03/16/proof-of-reserves
Мы можем построить HashTree, где все конечные узлы представляют одного пользователя, включая баланс пользователя ((Σ) и hash пользовательского идентификатора (например, почтовый адрес)h), а родительский узел содержит сумму остатков своих подключенных узлов (sum) и сортировку информации всех подузловhashДля каждого пользователя достаточно показать ему его собственный конечный узел и сестринский узел, а также сестринский узел всех его родительских узлов и родительских узлов, так как этот пользователь может подтвердить, что его баланс включен в родительский узел и, в конечном итоге, в корневой узел, путем постепенного восстановления от родительского узла.
Таким образом, для каждого пользователя отображается только его собственная информация и некоторая суммированная информация, и каждый пользователь может подтвердить, что его баланс включен в корневой узел, не зная, что другие используют баланс.hДля чего?e4df9d12Ноут не должен быть конечной точкой, которая представляет пользователя, а должен быть агрегированным информационным узлом (который может содержать пользователя с 3333 балансом и виртуального пользователя с 0 балансом), чтобы избежать утечки конфиденциальной информации пользователя.
Теперь давайте посмотрим на Git, который является типичным приложением для блокчейна:

Изображение из фото:http://gitbook.liuhui998.com/1_2.html (GPL v2)
В Git, будь то файл (Blob), индекс (Tree) или отправка (Commit), каждый имеет свой Hash, который определяется его содержанием, и если два объекта имеют одинаковое содержание, у них есть одинаковый Hash. В Git, история всего хранилища - это блокчейн, каждый Commit соответствует блоку, в Commit содержится Hash предыдущего Commit, а также Hash соответствующего объекта, который был изменен на этот раз, Hash самого Commit определяется его содержанием и этой информацией.
Git использует блокчейн, чтобы определить уникальную историю для хранилища. Если один Commit изменяется, все последующие Commit изменяются. Конечно, поскольку Git является инструментом версионного контроля, это не мешает вам изменять историю.push --forceВ то же время, это изменение будет замечено всеми соавторами.
Еще одно классическое применение блокчейна - биткойн, именно биткойн распространил слово “блокчейн” (хотя эта концепция существует уже давно):

Изображение из фото:https://commons.wikimedia.org/wiki/File:Bitcoin_Block_Data.png(CC-BY-SA-3.0)
В Биткойне каждый блок содержит серию транзакций и хэш предыдущего блока, а весь блокчейн представляет собой децентрализованную единую учетную запись. Поскольку новый блок создается каждые десять минут, а блок, созданный, остается на блокчейне навсегда, блокчейн фиксирует последовательность транзакций, сохраняет последовательность транзакций и определяет, есть ли на счету достаточно баланса, чтобы начать транзакцию.
Первая часть этого сообщения - это краткий обзор Биткоина.
Создание блоков в биткоине осуществляется с помощью “доказательства объема работы”, то есть все “майнеры”, участвующие в “майнинге”, должны выполнить некоторое вычислительное, связанное с вычислительной мощностью, сходные вычисления, имеющие случайный характер, до тех пор, пока не будет вычислен случайный номер, удовлетворяющий определенным условиям, для получения права на выпуск блока.
По умолчанию, каждый майнер всегда доверяет “самой длинной цепочке” и вычисляет следующий блок на основе самой длинной известной цепочки, удовлетворяющей правилам, иначе ваша вычислительная мощность будет напрасно потрачена, потому что другие майнеры всегда признают самую длинную цепочку, а если вы не начнете работать на основе самой длинной цепочки, то это будет противостоять вычислительной мощности всех других майнеров.
Биткойн был разработан так, чтобы создавать новый блок каждые 10 минут, и это время было достигнуто путем совместного наблюдения за промежутками времени между предыдущими блоками, чтобы скорректировать сложность создания следующего блока. Когда скорость создания предыдущих блоков выше, чем ожидалось, мы считаем, что создание следующего блока должно быть более сложным.
Обычно каждый биткойн-узел должен хранить полную блокчейн-данную, чтобы подтвердить, является ли сделка законной. Но теперь полный блокчейн насчитывает 66 Г, и он растет примерно на 0.1 Г в день. Если требовать, чтобы каждый пользователь биткоина хранил полную блокчейн, это не слишком требовательно, поэтому у биткоина есть механизм “упрощенной проверки платежей” (SPV), так называемый “легкий клиент”, который может выбрать не хранить полную блокчейн, а прикрепить к одному или нескольким полным узлам, чтобы хранить только информацию о всех элементах блока, а затем проверить работу каждого блока.

Изображение из фото:<https://github.com/ethereum/wiki/wiki/White-Paper
Фактически, мы можем представить себе блокчейн Bitcoin как “машину состояния”, весь блокчейн - это “книга” со состоянием, в которой хранятся записи о каждой транзакции, и на основе этих записей о транзакциях можно вычислить “статус” всей книги в любое время, то есть, сколько балансов у каждого счета в сети Bitcoin. Каждая транзакция - это изменение состояния, а каждый блок - это “консенсус” по поводу текущего состояния майнеров всей сети Bitcoin, потому что Bitcoin генерирует новый блок каждые 10 минут, что равносильно тому, что каждые 10 минут мы достигаем консенсуса по балансам всех счетов, а в течение этих десяти минут состояние книги - “хаотическое состояние”.
На основе биткоина были созданы многие другие криптовалюты, часто называемые “альт-коин”, которые имеют два варианта реализации:
Первый - использование собственной сети, независимой от биткоина, с преимуществом того, что копия может очень гибко разрабатывать свои собственные протоколы и правила, но из-за того, что количество пользователей будет трудно достичь аналогичного количества биткоина, защита от злонамеренных атак будет очень слабой.
Второй способ - использовать сеть Bitcoin для реализации “мета-протокола” и присоединять к Transaction Bitocin пользовательскую информацию для реализации своей логики. Такая выгода заключается в том, что вы можете использовать вычислительную мощность Bitcoin для защиты от атак, но в то же время, поскольку привязанность к сети Bitcoin, не все майнеры будут соблюдать правила копия, поэтому невозможно предотвратить вход в блокчейн, который не соответствует правилам, и только отфильтровать не соответствующие правилам транзакции на клиенте, а также не использовать упрощенную функцию подтверждения, упомянутую ранее в Bitcoin.
Для этих копий биткойн может обеспечить блокчейн с большим количеством участников, способных противостоять крупномасштабным злонамеренным атакам, а транзакции биткоина также могут содержать пользовательские данные, что оставляет определенный простор для реализации копий.
Bitocin также предлагает один из них.Bitcoin ScriptНо поскольку это не является основной функцией биткоина, то можно проводить только относительно простые операции, читать только очень ограниченные данные на блокчейне, а также из-за отсутствия циклического механизма трудно писать общую, полноценную логику.

Изображение из фото:https://www.ethereum.org/assets (CC 3.0)
“Ethereum” - это платформа децентрализованных приложений на основе блокчейна, которая создает общедоступную платформу, основанную на технологии блокчейна криптологии, и дополняет некоторые недостающие функции сети Bitcoin, чтобы разработчики могли запускать свои децентрализованные приложения на блокчейне.
Перед тем, как подробно рассказать о Ethereum, я расскажу о двух основных основах децентрализованной сети: криптография и игра. Криптология, естественно, не более чем математическая гарантия безопасности с помощью шифрования с открытым ключом, цифровой подписи, атрибутики и алгоритмов резюме; а игра означает, что в децентрализованной сети может участвовать любой человек, включая тех, кто намеренно хочет атаковать эту сеть.
Однако в цифровом мире выпуск данного не требует затрат, нет “выгод” и “убытков”, поэтому для определения “выгод” необходимо установить какую-то связь с физическим миром. Например, в сети Bitocin, если злоумышленник хочет искусственно изменить ход Blcokchain, необходимо иметь вычислительную мощность, превышающую мощность всех других майнеров, в то время как в физическом мире вычислительная мощность требует вычислительного оборудования, которое необходимо приобрести из физического мира.
Поэтому в децентрализованной сети не все проблемы решаются “технологией”, а те, которые не достигаются технологией, должны решаться с помощью прибыли, с помощью экономических стимулов. Также из-за потребности в “экономических стимулах” у Ethereum также есть система кошельков (валютная единица называется “Ether”), у каждого пользователя есть адрес кошелька в качестве его единственного идентификатора, в этом отношении он похож на Bitcion.
“Контракт” - это самая важная концепция, введенная Ethereum. В Bitcoin все адреса принадлежат одному пользователю. Когда мы говорим “пользователь”, мы имеем в виду пары публичного и частного ключей. Но в Ethereum, помимо адреса, принадлежащего паре ключей, есть еще один адрес, принадлежащий “коду”, то есть Contract.
В качестве примера можно привести “многопользовательский кошелек”, в официальном клиенте Ethereum есть функция для создания многопользовательских кошельков:

Как показано на рисунке, с помощью этой функции можно создать адрес кошелька, который будет принадлежать двум другим людям, и каждый человек будет использовать не более 100 эфиров в день, а если превысить этот предел, то с согласия другого человека.
Эта функция фактически создает контракт, а вышеупомянутая логика описывается кодом в контракте. Когда вы хотите произвести платеж из этого общего кошелька, вам нужно отправить сообщение в этот общей кошелек ((транзакция - это сообщение, сумма транзакции может быть равна нулю, но только с данными), а затем код из общего кошелька будет выполнен, и если запрос на расход соответствует вышеупомянутой логике, то будет произведена реальная транзакция на расход, в противном случае запрос на расход будет отклонен ((нет реальных расходов)).
В качестве другого примера можно привести “хеджированный контракт”, который постоянно обсуждается как криптовалюта, в которой биткоин (и его обменный курс по отношению к фискальной валюте) является нестабильным, часто наблюдается удвоение или удвоение стоимости валюты в течение одного дня, но это может быть в некоторой степени решено, если реализовать хеджированный контракт с помощью контракта.
Мы будем называть “рисковером” человека, который хочет сохранить неизменную стоимость валюты, и “рисковером” человека, который готов взять на себя риск колебаний валютной стоимости и получать от этого прибыль, чтобы они могли договориться о сумме (например, 1000 CNY) и временном окне (например, месяц) и создать контракт, выполняющий следующую логику:
Если стоимость эфира повышается, то рискователь получает прибыль, а если стоимость эфира снижается, то рискователь теряет, но рискователь всегда не теряет. Конечно, рискователь и рискователь могут заранее договориться о “страховании”, которое рискователь должен заплатить, а также о том, что рискователь должен предоставить несколько раз больше гарантии, чем 1000 CNY (чем выше коэффициент удвоения, тем больше риск может быть принят).
В приведенном выше примере есть еще одна проблема, которая не очень хорошо решена, а именно, как определить обменный курс между эфиром и криптовалютой. Как мы упоминали ранее, контракт имеет доступ только к данным на блокчейне, а криптовалюта - это данные, которые существуют в реальном мире, а не в криптографическом мире.
Мы можем спроектировать еще один контракт, чтобы задать логику, которая позволяет нам получать обменный курс между эфиром и фиктивной валютой из физического мира в каждом временном окне (например, в час):
Для любого из участников, не зная о предложениях других, представление истинного курса имеет большую вероятность получить вознаграждение, а представление очень странного курса будет иметь большую вероятность потерять гарантийную сумму.
Конечно, в этом правиле есть несколько пробелов, например, если у человека очень много гарантий, то он может притянуть среднее значение до цены выше или ниже, чем реальный обменный курс, и при этом получить вознаграждение, а другие люди, которые предоставили точный обменный курс, потеряют гарантии. Но на самом деле это то же самое в реальном мире, если у вас очень много денег, вы также можете поднять или понизить цену товара, только по сравнению с реальным миром, объем электронной валюты очень мал, и не требуется много денег, чтобы это сделать; но на самом деле такой злонамеренный подъем или давление на курс также очень рискован, потому что вы не можете быть уверены, сколько гарантий вы заплатили, и в случае неудачи потеряете все гарантии.
Еще одна уязвимость заключается в том, что “каждый может внести вклад в контракт и предоставить обменный курс”, который реализуется путем создания транзакций, и все транзакции будут записаны на блокчейне, поэтому обменный курс, который вы предоставляете, будет виден другим людям, что создаст дополнительные возможности для злонамеренных злоумышленников.
Мы упоминали ранее, что Contract может читать данные на блокчейне, но данные на блокчейне являются определенными, и если мы хотим реализовать приложение, похожее на азартные игры, откуда мы получим случайные числа?
В большинстве случаев такой уровень случайности достаточно. Но на самом деле майнеры могут в какой-то степени манипулировать этим случайностью. Предположим, что майнер участвует в определенной игре, и выигрыш от игры больше, чем выигрыш от добычи блока.
Поэтому нам нужно ввести механизм, похожий на обменный курс, для сбора случайных чисел, а затем использовать эти семена для вычисления случайного числа в конце каждого временного окна и . Но, как и в случае с обменным курсом, поскольку участники создают обменный курс путем создания сделки, поэтому между временными окнами случайные числа, которые каждый человек предоставляет, видны всем остальным, поэтому человек, который уже участвует в определенном азартном виде, может тщательно подобрать случайный номер семени, чтобы случайные числа, полученные в результате добавления новых семян, которые уже были представлены другими, соответствовали его ожиданиям.
Поэтому нам необходимо разделить окно сбора семян на две части, чтобы получить случайное число, которое никто не может предсказать и вмешаться:
На первом этапе вы знаете только ассимиляцию поданных других людей семян, но не знаете реальных семян, поэтому не можете тщательно сконструировать семя, чтобы вмешаться в результаты; а на втором этапе все просто подтверждают поданные в первом этапе семян, но не могут представить новые, и не могут помешать другим представить семена.
Возможно, биткойн был создан для того, чтобы контролировать время выполнения биткойн-скриптов, поскольку, согласно “теорету остановки” Тюринга, программы, написанные на языке программирования, дополненном Тюрингом, не могут всегда определять только с точки зрения статического анализа, закончатся ли они после ограниченного количества шагов. Таким образом, злонамеренные атакующие, которые полагаются на это, могут создать транзакцию, которая вызывает мертвый цикл, чтобы помешать нормальной работе шахтеров.
Ethereum опять обходит эту проблему с помощью “экономического стимула”. Контракт работает в виде opcode на виртуальной машине, называемой EVM (Ethereum Virtual Machine). EVM - это виртуальная машина с собственным “платежом”. В стандарте EVM каждый opcode потребляет Gas, который является вычислительным ресурсом, купленным Ether.
И тогда мы снова обсудим вопрос о “консенсусном интервале”, о котором говорилось ранее, что в биткоине каждые 10 минут появляется новый блок, то есть вся сеть достигает “консенсуса” каждые 10 минут, поэтому обычная биткоин-транзакция должна ждать несколько десятков минут, прежде чем она будет подтверждена, а в ранние годы, когда вычислительная мощность не очень высока, может потребоваться дождаться часа (~ 6 блоков), прежде чем люди будут считать эту транзакцию надежной.
Это потому, что более быстрый интервал согласия в некоторой степени увеличивает преимущества “централизованного пула”. “Пуль” означает, что биткоин-майнеры собираются вместе, чтобы добывать, и майнеры безусловно следуют указаниям пула, и, в конце концов, получают доход от соглашения с пулом. Очевидно, что Биткойн, как децентрализованная система, не хочет, чтобы такой централизованный пуль имел дополнительные преимущества.
Когда один из шахтеров A добывает новый блок, он транслирует этот блок, и другие, получив это сообщение, сразу же начинают работать на основе нового блока. В то время как у других людей расчет времени между “добытием нового блока” и “получением сообщения о трансляции A” фактически растрачивается, а у других шахтеров в централизованном шахтёрском бассейне нет этой проблемы, поскольку они могут быстрее получить информацию о новом блоке и сразу же начать работу на основе нового блока.

Время для этой трансляции может занимать несколько секунд, что не так важно для 10 минут, но преимущества централизованного пула будут становиться все более очевидными, если сократить промежуток между согласиями. Но Ethereum решила эту проблему, введя концепцию “Uncle Block”, сократив промежуток между согласиями до 15 секунд.
В блокчейне биткоина блок может иметь только один родительский блок и только один дочерний блок. Но в Ethereum новый блок может иметь родительский блок и несколько дядей. Возвращаясь к примеру выше, если кто-то выкопал новый блок в A, но другие не получили его во время трансляции, если кто-то выкопал новый блок, но не был принят во время трансляции позже, то этот блок может стать “дядядям” следующего блока.

Изображение из фото:<https://blog.ethereum.org/2014/07/11/toward-a-12-second-block-time
В следующей части я расскажу вам о некоторых проблемах, которые Ethereum пока не решает.
Во-первых, Ethereum, как и Bitcoin, по-прежнему гарантируется через POW (доказательство рабочей нагрузки), и только узлы, которые выполняют определенный объем работы, могут участвовать в работе по созданию блоков. Проблема с доказательством рабочей нагрузки заключается в том, что для обеспечения безопасности сети тратится огромное количество вычислительной мощности.
Поскольку эфир сам по себе является ценным, почему бы не использовать его для экономического стимулирования? POS - это то, что каждый узел, который хочет участвовать в создании блока (в традиционном смысле - майнинг), называется верификатором.
Эта модель очень похожа на POW, в которой майнеры используют свою собственную вычислительную мощность для “залога” и, если есть более длинная цепочка, необходимо переключиться на эту цепочку, чтобы продолжить добычу. Потому что чем больше участников, тем больше вероятность, что это будет правильная цепочка, и в конечном итоге все достигнут консенсуса.
POS, безусловно, увеличит пропускную способность всей сети Нам больше не нужно будет проводить бессмысленные вычисления, чтобы достичь консенсуса, и количество операций на каждом узле приблизится к количеству вычислений, выполняемых в коде контракта и проверке данных.
Причина, по которой POS пока не используется, заключается в том, что есть еще не решенные проблемы, такие как 51% атаки, в которых 51% вычислительной мощности в POW имеет определенные физические ограничения, поскольку вычислительная мощность требует вычислительного оборудования; в то время как Ether с 51% вычислительной мощности в POS сравнительно легка, если у вас есть достаточно денег.
Другая тема - “фрагментация” - как Bitcoin, так и Ethereum, в настоящее время все подтверждения транзакций выполняются на одном блокчейне, что значительно ограничивает вычислительную мощность распределенной сети. Каждый узел должен принимать, хранить и проверять каждую транзакцию, и вычислительная мощность всей сети фактически равна вычислительной мощности одного узла.
Таким образом, Ethereum хочет в будущем ввести механизм “раскола”, чтобы разделить всю сеть на несколько частей, между которыми проводится независимая проверка транзакций. Но между расколами будет использоваться структура указателя для ссылки на данные других частей, асинхронное вызов способом влияния на другие части, так что вся сеть в глазах пользователей остается единой, только обработка всей сети будет иметь очень сильную расширяемость.
В этой части я покажу вам несколько практических, работающих кодов для Contract. Contract может быть написан на многих разных языках, и в конечном итоге они будут компилированы в opcode, который будет выполняться на EVM, и сегодня мы выбрали Solidity в качестве JavaScript, который является одним из наиболее поддерживаемых языков EVM.
contract Test {
uint storedData; // State variable
struct Voter { // Struct
uint weight;
bool voted;
address delegate;
uint vote;
}
event HighestBidIncreased(address bidder, uint amount); // Event
function func() { // Function
if (msg.sender.balance < 10 finney) {
msg.sender.send(10 finney);
}
sha256("...");
address nameServer = 0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2;
nameServer.delegatecall("isAvailable", "MyName");
nameServer.call("register", "MyName");
}
}
В Solidity вы можете объявить переменные состояния (в Solidity вы можете объявить переменные состояния)uint storedData;В этом случае, значения этих переменных будут навсегда сохранены в блокчейне.structДля объявления сложных структур данных; также можно определить функции, которые будут выполнены при получении сделки, и инициатор сделки может выбрать, какие функции выполнять, поэтому контракт может предоставить несколько функций, в которых можно логически судить, циклировать и изменять значения.
В языке встроены некоторые удобные маленькие функции, такие как распространенные криптографические алгоритмы.sha256)), единица пересчета (((10 finneyНаписать адрес кошелька.0x72ba7d8e73fe8eb666ea66babc8116a41bfb10e2И так далее.msgЭто встроенная глобальная переменная, из которой можно прочитать информацию, относящуюся к данной сделке, такую как инициатор, сумма и т. д.delegatecallЭто то же самое, что поместить код другого контракта в текущий контекст, как если бы вы ввели библиотечную функцию;callЭто логика начала новой сделки, чтобы запустить другую.
Эта сложная работа абстрагирована для “переменных состояния”, где storedData - это переменные состояния. На самом деле, изменения в переменных состояния в процессе исполнения контракта не сохраняются в блокчейне, потому что контракт выполняется с определенной точностью.
Теперь я хочу показать вам реальный Contract Coin, который выпускает свой собственный токен на базе сети Ethereum:
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Sent(address from, address to, uint amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() {
minter = msg.sender;
}
function mint(address receiver, uint amount) {
if (msg.sender != minter) return;
balances[receiver] += amount;
}
function send(address receiver, uint amount) {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver] += amount;
Sent(msg.sender, receiver, amount);
}
}
Код взят из:http://solidity.readthedocs.io/en/latest/introduction-to-smart-contracts.html#subcurrency-example (MIT)
Например, если вы хотите, чтобы ваш контракт был прозрачным, то вы можете использовать его в качестве инструмента, чтобы сделать контракт прозрачным.minterСоздатели, которые использовали этот токен для хранения, создали функцию ((function Coin()Первая транзакция, которая была использована для создания контракта, была присвоена этой переменной; также был заявлен адрес кошелька в таблице цифрового отображения.balances, используется для обозначения баланса каждого адреса, в котором находится этот токен.
mintЭта функция предварительно определяет, является ли инициатор сделки создателем токена, и если да, то в соответствии с параметрами функции добавляет определенное количество токенов к указанному адресу.sendЭта функция может быть вызвана всеми и будет вычитать из адреса инициатора сделки определенный баланс (если есть достаточный баланс) и добавить к адресу назначения, что соответствует функции перечисления.
Мы также объявили, чтоSentНа самом деле, события не будут иметь никакого практического значения, они будут просто печатать ключевые события при дебютировании, что в будущем также будет способствовать реализации легких клиентов (легкие клиенты принимают только события, но не выполняют контракты).

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