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

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

Основные концепции

Если вы изучали информатику, вы, вероятно, знаете элементарную структуру данных, которая называется связанный список. Такая структура данных состоит из набора узлов , или блоков, связанных друг с другом ссылкой, и в них хранятся какие-то данные, такие как целые числа, строки и т. Д. .

Блокчейн очень похож на список понравившихся: это набор узлов, связанных друг с другом, но в отличие от связанных списков, они связаны своего рода ключом (хешем). То есть каждый узел имеет свой собственный хэш, а также хеш соседнего узла. Как сказано в этой песне Paramore, единственное исключение - это первый узел цепочки, называемый генезисным блоком.

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

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

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

Реализация

Читать об этих концепциях без какой-либо практики не имеет особого смысла, поэтому давайте создадим проект Java Script с использованием функций ES6 и внимательно рассмотрим. Сначала создайте проект под названием блокчейн:

mkdir blockchain
cd blockchain
npm init -y
touch index.js
npm install --save babel-register
npm install --save-dev babel-preset-es2015
npm install crypto-js
touch .babelrc

Внутри файла .babelrc добавьте следующее содержимое:

{ “presets”:[“es2015”] }

И в файле package.json в области скриптов добавьте его:

"start": "babel-node index.js"

Теперь в нашем проекте включен ES6.

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

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

Метод getHash () просто использует атрибуты блока для создания хэша. И поскольку мы не контролируем его возврат, мы можем использовать его, чтобы добавить доказательство работы в майнинг. Если вы посмотрите на метод mine, вы увидите в строке 17, что есть переменная с именем patternOfDifficulty, и идея довольно проста: мы создаем блок с некоторым значением хеша, возврат метода getHash (), затем мы проверяем, соответствует ли первая «сложность» цифр (в нашем случае это строка с количеством 9 секунд, равная сложности ) равны заданному patternOfDifficulty. Если это не так, мы продолжаем выполнение до тех пор, пока условие не станет ложным, то есть первые цифры «трудности» не будут равны patternOfDifficulty. Итак, например, предположим, что мы получили следующий хэш:

232#4533829jmz-2038282s21332dshjaxjhajhuaghahdkvacadhakhdkahdk338283

И если наша сложность равна 4, patternOfDifficulty будет:

9999

Если мы получим первые символы хэша «трудность», мы получим:

232#

И сравнивая с patternOfDifficulty:

9999 != 232#

Мы получаем ложь. Так что нам нужно сделать это снова. Если теперь полученный хеш:

9999jfknejfwhfkwnfkwhkfihiemht7et97-29u3oh38hfoahgufgaouyf7g7g7g7g

Теперь первые символы «сложности»:

9999 

А если сравнить с patternOfDifficulty:

9999 == 9999

Они совпадают, поэтому мы выходим из цикла и добыли блок. Чем выше сложность, тем выше время на добычу блока. Если вы еще раз взглянете на класс Block, вы увидите в строке 9 атрибут изменяемый, этот атрибут отвечает за изменение вывода функции SHA256, потому что все остальные атрибуты никогда не меняйте внутри цикла. Из-за этого, чтобы вызвать другой вывод этой функции, значение changeable увеличивается на каждой итерации.

Когда у нас есть классы Transaction и Block, мы можем реализовать класс BlockChain:

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

Внутри конструктора, в строке 3, когда мы объявляем список блоков, мы уже добавляем блок, причина уже была указана выше, что один из них является генезисным блоком. Этот блок создается методом getGenesisBlock (), определенным в строке 9. Этот метод просто возвращает экземпляр блока без атрибута prevHash.

Имея это, мы можем начать играть: давайте создадим блокчейн под названием fancyChain со сложностью 2 и 100 в качестве вознаграждения за майнинг. Затем мы вставим две транзакции в эту цепочку, где кто-то с идентификатором 505 отправит кому-то с идентификатором 40 сумму 100,0 долларов США, а им - 150,0 долларов США. Воспринимайте это как ситуацию, когда кто-то что-то покупает у своего друга, а наша сеть регистрирует транзакцию.

Если мы напечатаем fancyChain как JSON:

Как видите, все работает как положено: наша цепочка была создана с генезисным блоком, и две транзакции размещены там. Теперь предположим, что кто-то с идентификатором 31 пытается майнить некоторые ожидающие транзакции и посмотреть свой баланс после майнинга:

Сделав это, наш результат будет:

Если взглянуть на эти хэши, вы увидите, что первые два символа (сложность = 2) равны 99, как мы определили создание нашего экземпляра цепочки блоков ранее. И снова распечатав цепочку, получаем:

Взглянув еще раз, вы также увидите, что все эти блоки, кроме Genesis, хранят хэш предыдущего блока.

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

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

console.log(“Is fancyChain valid? “ + fancyChain.isChainValid());

Если вы посмотрите назад в классе BlockChain, метод isChainValid () объяснит: после изменения значения транзакции оператор if в строке 49 получит значение false, потому что вызывается метод getHash (), который использует массив транзакций, чтобы получить его хэш. Таким образом, при простом изменении этого значения вся цепочка становится недействительной.

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

Подводя итоги

Блокчейн может быть очень полезен, если вы хотите создать свою собственную криптовалюту, смарт-контракты или безопасно обрабатывать транзакции.

Как вы видели, блокчейн - это в основном набор блоков, в которых хранятся транзакции, которые кто-то может майнить и заработать какие-то очки.

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

Это все, до следующего!

Код на GitHub: https://github.com/ABuarque/BlockchainArticle