[ГАЙД]Как создать блокчейн?

ETHbitcoin

Member
Регистрация
7 Фев 2020
Сообщения
4
icoforum token
0
Для просмотра URL-ссылок и контента, нужны, Вход или Регистрация пожалуйста, выполните их!



Возможно, вы читали множество теоретических постов о том, как работают криптовалюты, как работает блокчейн, и о некоторых других похожих темах, таких как Proof of Work, sha256. и т.д. Но такие теоретические посты могут дать вам только общее представление о работе, а многие вещи все еще остаются для вас загадкой. Итак, цель темы - дать вам информацию из первых рук о том, как работает Blockchain с использованием программного кода.

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

Во-первых, эта тема только для обучения. Код ниже не готов к работе и имеет несколько уязвимостей. Если вы планируете использовать его для работы, обязательно сначала свяжитесь со мной, и я сообщу вам необходимые дополнения, которые вы должны сделать, чтобы его подготовить.
Во-вторых, в этом руководстве будет использоваться среда Javascript / Node.JS, поэтому если у вас есть общее представление о том, как работает Javascript, то это руководство для вас. Если нет, то даже тогда вы сможете узнать много полезной информации. Если вы где-то "застряли", просто пишите мне в личку или здесь, и я решу все возникающие сложности.
Давайте начнем:




[size=16pt]Часть 1: Блок[/size]

[size=14pt]Часть 1(a):Конструктор[/size]

Ok! Таким образом, блок, как мы все знаем, является фундаментальной единицей блокчейна. Серия взаимосвязанных блоков образует блокчейн. Позвольте привести пример: предположим, 10 детей играют в парке. Каждый из них держит руку другого ребенка, таким образом формируя структуру человеческой цепи, дети на обоих крайних концах будут держать руку одного другого ребенка, в то время как остальные 8 будут держать руки двух детей, по одному с каждой стороны. Блокчейн работает по той же концепции. Первый блок цепочки (известный как генезис блок) будет держать руку только второго блока, в то время как самый последний блок будет держать руку только предпоследнего блока. Все остальные блоки будут держать в руках блоки предыдущих и следующих за ними.

Небольшое наглядное представление того, что я только что сказал:

blockchain-pictorial.png

(Я плохой художник, я знаю. :D)​

Ok! Итак, теперь ясно одно: каждый блок должен держать руку другого блока для формирования цепочки. Чтобы гарантировать, что блокчейн использует концепцию хэша и предыдущего хэша (мне нравится называть это последним хэшем). Каждый блок имеет уникальный хеш, который генерируется с помощью алгоритма SHA256 (подробнее об этом позже). Этот хэш действует как рука каждого блока. Второй блок сохранит хэш блока генезиса, третий блок сохранит хэш второго блока и так далее ... Это подводит нас к базовой схеме блокчейна,каждый блок должен иметь хэш, lastHash (хэш предыдущего блока), данные (что уникального хранится в блоке), отметка времени (время создания блока) и номер (постараюсь объяснить это на примере с PoW). Прежде чем начинать с работу с кодом, пожалуйста, убедитесь, что у вас все готово:

(i) Установите Node.js на вашу систему
(ii) скачать любой редактор кода (я бы предложил код Visual Studio)
(iii) создать новый файл с любым именем, но с расширением .js, например: app.js или index.js
(iv) открыть файл в коде Visual Studio

Вот первый фрагмент кода:
Код:
class Block {
    constructor(timestamp, lastHash, hash, data, nonce) {
        this.timestamp = timestamp;
        this.lastHash = lastHash;
        this.hash = hash;
        this.data = data;
        this.nonce = nonce;
    }
}

Ура! Вот код для части: 1 (а). Теперь позвольте мне объяснить, что мы только что сделали. Начиная со слова «class». Сlass на самом деле скелет. Мы создали скелет с названием «Block». Как у каждого человека есть скелет, но разные мышцы и органы. Точно так же каждый блок в цепочке будет иметь этот скелет блока. Отметка времени, lastHash, hash, data и nonce являются костями. Каждый блок должен иметь эти кости, чтобы сформировать скелет. В дальнейшем слово «constructor» относится к функции, которая будет принимать кости в качестве входных данных и создавать из них скелет. Таким образом, мы фактически вводим значение timestamp, lastHash, hash, data и nonce в функцию конструктора, которая, в свою очередь, устанавливает значение timestamp, lastHash, hash, data и nonce экземпляра Block, эквивалентное этому.
Отлично. Давайте перейдем к Части: 1 (б).

[size=14pt]Часть 1(b): Genesis блок[/size]

Вот код для части: 1 (б), этот код будет следовать после функции конструктора:
Код:
    static createGenesis() {
        return new this("17/01/2020", "dummy-last-hash", "dummy-hash", "data in genesis block", 0)
    }

Превосходно! Итак, позвольте мне рассказать вам, что мы только что сделали: мы создали статическую функцию в классе Block, которая создаст для нас генезис блок. Вы можете заметить, что мы создали жестко запрограммированное значение для этого блока (все, что внутри '' ''- это строковое или жестко запрограммированное значение, а не код). Мы делаем это так, потому что у блока genesis не может быть lastHash. Для него можно создать хеш, что делает рискованным хранение любых данных в genesis блоке , поэтому лучше, если мы определим свойства блока genesis самостоятельно и не используем его для хранения данных.

Двигаясь дальше, позвольте мне описать, что делает приведенный выше код. Начиная со слова «static». Мы можем создать два типа функций в классе, обычные функции и статические функции. Нормальные функции могут использоваться с каждым экземпляром класса (например, каждый блок, созданный с помощью класса Block, может использовать обычную функцию), но невозможно использовать статическую функцию с каждым экземпляром. В нашей цепочке нам нужен только один генезис блок, поэтому было бы неправильно, если бы мы создали для этого нормальную функцию. Следовательно, статическая функция гарантирует, что функция createGenesis () может быть вызвана только один раз в блокчейне.

Вы можете заметить «return» в коде выше. Return на самом деле означает возврат (умный, да :) ). Это гарантирует, что всякий раз, когда эта функция вызывается, функция возвращает значение генезис блока. «New» относится к экземпляру класса Block. Всякий раз, когда мы создаем экземпляр любого класса, мы должны использовать новое ключевое слово. «this» относится к конструктору класса Block. Если мы используем конструктор внутри класса, тогда мы должны ссылаться на него с помощью «this».

Достаточно, давайте двигаться дальше и создадим самую важную функцию, т. Е. CreateBlock.


[size=14pt]Часть 1(c): Создать Block function и Proof of Work[/size]
Код после функции createGenesis ():
Код:
    static createBlock(previousBlock, data) {
        let hash, timestamp, nonce=0;
        const lastHash = previousBlock.hash;
        do {
            timestamp = Date.now();
            nonce++;
            hash = hashGenerator(timestamp, lastHash, data, nonce);
        } while (hash.substr(0,4) !== ‘0’.repeat(4));
        return new this(timestamp, lastHash, hash, data, nonce);
    }

Хорошо! Теперь пришло время понять, что мы написали выше. Функция принимает два входа: предыдущий блок, который является блоком, предшествующим тому, который мы создаем, и данные, т.е. фактические данные, которые мы хотим сохранить в блоке. Затем мы разрешаем начальное значение hash = none, timestamp = nothing и nonce = 0. В Javascript «let» и «const» - это два способа определения переменных. Мы ссылаемся на переменные, которые не меняют свое значение с помощью «const», а переменные, которые меняют свое значение на «let». Затем мы извлекли значение lastHash из предыдущего блока, равное хэшу предыдущего блока.

Затем следует концепция Proof of Work. Мы попытались достичь этого с помощью цикла do / while. Часть «while» цикла do / while принимает условие, и цикл продолжает выполнять в части «do» до тех пор, пока не выполнится условие в условии while. Итак, условие, которое мы упомянули в операторе while: hash.substr (0, 4)! == ‘0’.repeat (4). Теперь давайте нарушим это утверждение. hash.substr (0,4) означает первые 4 символа хеша, начиная с 0, то есть первый символ, затем второй, третий и четвертый. «0» .repeat (4) означает четыре нуля или «0000». Таким образом, мы на самом деле заявляем, что продолжаем выполнять цикл, поскольку первые четыре символа хэша не равны 0. Как только первые 4 символа хэша станут равны 0, цикл прервется, и результирующее значение станет хешем блока. Это не совсем то, как Proof of Work работает, но основная идея та же самая. Мы находим хеш с четырьмя нулями в начале, как 0000vddvd5vd4dv5dvdXXXXXXXXXX. Если вы хотите повысить сложность системы Proof of Work, увеличьте количество нулей до 5 и более, и блоки будут добываться медленнее. Если вы хотите уменьшить сложность, уменьшите количество нулей до 3 или ниже, и блоки будут добываться быстрее.

Теперь перейдем к коду внутри оператора "do". Во-первых, это временная метка, которую мы взяли равной Data.now (), которая является функцией javascript для генерации текущей даты. Следующим является одноразовый номер. Одноразовый номер - это число, которое увеличивается на 1 в каждом цикле, так что значение хеш-функции продолжает изменяться. Если одноразовый номер остается неизменным, то невозможно создать новый хэш в каждом цикле. Последней вещью в коде является hashGenerator, который принимает значения меток времени, lastHash, data и nonce и генерирует хеш, объединяя все 4 значения в одну строку с использованием алгоритма sha256. Мы напишем функцию hashGenerator в следующей части. Давайте приступим.

[size=14pt]Часть 1(d): SHA256[/size]
Давайте сначала напишем код, он будет идти вверху файла перед классом Block:
Код:
const crypto = require(‘crypto’);
const hashGenerator = (...inputs) => {
    const hash = crypto.createHash(‘sha256’);
    hash.update(inputs.map(item => JSON.stringify(item)).join(‘’));
    return hash.digest(‘hex’);
}

Прекрасно! Пришло время объяснений. Crypto - это встроенная библиотека Node.js. Итак, мы просто вызвали её в наш файл, запросив её. Далее идет функция hashGenerator. Во-первых, мы берем входные данные, то есть, если вы помните из части: 1 (c), это отметка времени, lastHash, data и nonce. Затем вы должны заметить три точки перед входами. Эти точки не ошибки, эти точки преобразуют все 4 входа в массив следующим образом: [timestamp, lastHash, data, nonce]. Бинго! Теперь давайте войдем в функцию hashGenerator. В первой строке мы определили значение хеша, равное функции createHash («sha256») криптотеки. Затем мы вводим каждый элемент массива входных данных через метод обновления. Сначала мы сопоставляем массив входов, что означает циклический просмотр элемента массива, преобразование каждого элемента в строку с помощью метода JSON.stringify и последующее объединение всего в одну строку. Наконец, мы возвращаем значение функции digest методом, но сначала преобразуем сгенерированное значение из второй строки в шестнадцатеричное.

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

Это подводит нас к концу первой части нашего руководства из двух частей по созданию Blockchain. Мы успешно создали класс Block. Далее мы создадим класс Blockchain и добавим блоки в наш blockchain.
 

ETHbitcoin

Member
Регистрация
7 Фев 2020
Сообщения
4
icoforum token
0
Часть 2: BLOCKCHAIN

Часть 2(a): Blockchain Class Constructor

Давайте сначала обсудим архитектуру нашего блокчейна. Структура нашего блокчейна будет Array(массив). Это может быть либо Array, либо Object, либо любой другой тип, но структура Array дает нам преимущество использования различных методов Array, предлагаемых Javascript. Ok! Итак, в нашей функции конструктора для Blockchain мы создадим пустой массив и поместим первый элемент массива в блок genesis. Далее мы создадим функцию, которая создаст новый блок с использованием класса Block и добавит его в массив нашей цепочки. Аккуратно, верно? Давайте перейдем к коду для нашей части 2 (а), напишем этот код после окончания class Blockchain:

Код:
class Blockchain {
    constructor() {
        this.blocks = [Block.createGenesis()];
    }
}

Здорово! Теперь время для объяснений. Прежде всего, мы создали скелет нашего блокчейна через класс Blockchain. Далее мы создали функцию конструктора для класса Blockchain. Обратите внимание, что у нас нет никаких входных данных для этой функции конструктора, потому что они нам не нужны. Далее, первая и единственная кость скелета Blockchain - это this.blocks, который является массивом. Новые блоки при создании будут добавлены в этот массив автоматически. Затем в массив вводим функцию Block.createGenesis (). Помните статическую функцию createGenesis () из части 1? Это та же функция. Но поскольку мы используем её вне класса Block, мы должны прикрепить Block перед именем функции, чтобы сообщить Javascript местоположение нашей функции genesis.

Помещение этой функции в массив this.blocks сделает первый элемент массива равным возвращаемому значению функции createGenesis (), которое является жестко запрограммированным значением, помните? Великолепно! Итак, в Части 2 (а) мы достигли двух вещей: сначала мы создали массив, в который будут помещены все блоки при создании. Во-вторых, мы выдвинули генезис блок как первый элемент массива. Это подводит нас к последнему шагу нашей блокчейна, функции для добавления блоков. Давайте добьемся этого в части 2 (б).

[size=14pt]Часть 2(b): Добавление блоков в Blockchain[/size]

Давайте начнем с кода, как мы делали до сих пор, напишите этот код после: constructor function:
Код:
    addBlock(data) {
        const createdBlock = Block.createBlock(this.blocks[this.blocks.length - 1], data);
        this.blocks.push(createdBlock);
    }

Выполнено! Это был последний "гвоздь для гроба". Теперь давайте разберемся с кодом. Единственный вход, который принимает эта функция - это «data». Эти данные будут информацией, которую пользователь будет хранить в блокчейне. Далее идет «const madeBlock». Это экземпляр блока, который создается функцией addBlock путем вызова функций createBlock из класса Block. Теперь помните, что функция createBlock принимает 2 входа: previousBlock и data. Данные будут передаваться из ввода функции addBlock в createBlock, тогда как предыдущий блок будет извлечен из нашего массива this.blocks. Я написал этот код для предыдущего блока: «this.blocks [this.blocks.length - 1]». Теперь попытайтесь понять код, this.blocks - это массив, длина всех массивов равна количеству элементов в массиве. Например, длина нашего массива this.blocks на данный момент равна 1, поскольку на данный момент он содержит только блок genesis. Поэтому this.blocks.length будет равен 1.

Теперь у каждого элемента в массиве есть ключ. Первый элемент будет иметь ключ 0, второй элемент будет иметь 1 в качестве ключа и так далее. Теперь еще раз рассмотрите код: 'this.blocks [this.blocks.length - 1]' и поместите значение this.blocks.length, оно станет: this.blocks [1-1] или this.blocks [0] т.е. блок генезиса. Таким образом, эта строка всегда возвращает последний элемент, доступный в массиве, и передает его функции createBlock.

Надеюсь, понятно, если нет, то вы всегда можете попросить дополнительное объяснение здесь, в этой теме или в личке. Хорошо, двигаемся вперед. Последняя строка нашего кода - this.blocks.push (созданный блок). Эта строка фактически помещает (что означает добавление) вновь созданный блок в массив this.blocks.
Отлично! На этом мы завершили часть 2

Вы можете посетить:
Для просмотра URL-ссылок и контента, нужны, Вход или Регистрация пожалуйста, выполните их!
и увидеть весь код.



[size=16pt]TЕСТИРОВАНИЕ КОДА[/size]

Время для теста. Давайте посмотрим, что мы написали. После окончания класса Blockchain напишите этот тестовый код:

Код:
const webbyChain = new Blockchain();
webbyChain.addBlock(‘This dummy data is saved in the second block of the webbyChain’);
webbyChain.addBlock(‘This immutable data is saved in the third block’);
webbyChain.addBlock(‘Adding top secret in the fourth block’);
console.log(webbyChain.blocks);

Отлично! Мы только что создали экземпляр нашего Blockchain по имени webbyChain. Вы можете дать любое имя вашей блокчейну. Затем мы добавили 3 блока в цепочку с помощью функции addBlock. Наконец, мы поддерживаем логирование массива блоков нашего webbyChain, чтобы мы могли видеть вывод нашей блокчейна в терминале.

Как только вышеуказанные шаги будут выполнены, откройте терминал. Если вы используете код Visual Studio, он автоматически откроется в нижней области. Если нет, нажмите Ctrl + Shift + `. Кроме того, вы можете использовать командную строку или любой другой терминал. Затем откройте ваш файл. Например, если ваш файл находится на рабочем столе, убедитесь, что рабочий стол открыт в вашем терминале. Затем выполните следующую команду:

node index.js (имя вашего файла может быть другим)

Для создания блоков в качестве алгоритма Proof of Work потребуется некоторое время, чтобы убедиться, что поиск хеша занимает много времени. Как только все три блока будут добыты, они будут отображаться рядом с генезис блоком в вашем терминале.

Это конец руководства. Не стесняйтесь задавать любые вопросы. Я пропустил многие вещи, такие как правильная работа алгоритма Proof of Work, автоматическая настройка сложности, проверка цепочки, хэши и т. д. Но руководство уже слишком длинное, так что пусть это будет в следующий раз. :D
Также проголосуйте, если хотите, чтобы я создал руководство по созданию криптовалюты на блокчейне.

Для просмотра URL-ссылок и контента, нужны, Вход или Регистрация пожалуйста, выполните их!
 
Сверху