Author

Topic: [ГАЙД]Как создать блокчейн? (Read 426 times)

legendary
Activity: 1456
Merit: 5874
light_warrior ... 🕯️
September 21, 2020, 04:59:27 AM
#13
Во-первых, эта тема только для  обучения.
Очень просто, доходчиво и с примерами, спасибо! Надеюсь этот материал будет тоже полезен, ниже представлены гайды, конструкторы и аудит платформы.


  • Список ресурсов в Etherscan реестре и Основы от Hyperledger: Клик image



Добавил: https://developer.bitcoin.org/reference/

jr. member
Activity: 81
Merit: 6
Имхо, время доверия к  самописным проектам -  ушло
обертка красивая - а вот начинка.....
Ну а биткоин Сатоши - не "самописный проект"? Это "спонсорские проекты" как раз таки должны вызывать подозрение, больше вероятность что кинут через дик в самый неожиданный момент.
jr. member
Activity: 87
Merit: 1
Это даже не 1% от блокчейна

нет подписей,
нет протокола создания транзакций,
нет протокола формирования блоков,
нет сетевого протокола,
нет консенсуса (перебор хешей по SHA256 еще не PoW, ключевое в консенсусе - правила форджинга)

что есть?
программа генерирующая массив js объектов(зачем-то дублирующих внутри себя индекс) и содержащих в себе тупо текст с его хешем.

статья трехлетней давности "блокчейн на 200 строк" - в разы содержательнее

Пост выглядит как "замаскированная" продажа мерита ТСу
legendary
Activity: 2744
Merit: 1588

1) Не бывает "интерпретируемых языков", бывают интерпретаторы и компиляторы. Для C тоже можно написать интерпретатор, и это не сделает его "интерпретируемым".
2) Современные JIT компиляторы, такие как в движке v8, очень сообразительны по части оптимизации. И зачастую генерируемый ими код по скорости не особо-то отличается от аналогичного на C, если отличается вообще.


На любом Тьюринг-полном языке можно написать все что угодно, но например компиляторы или интерпретаторы очень сильно удобней писать все таки на С++ чем на жабе или питоне ))

Спасибо за пояснение, такой особенности я не знал. Всегда думал, что есть интерпретуемые языки и компилируемые, а тут оказывается, что это еще одна программа и она не зависит от самого языка.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
что на том же JAVA можно делать высокомасштабируемые проекты, а вот на том же Python уже так не получиться. Да и тот же Python интерпретируемый язык, а потому у него слабая скорость исполнения по сравнению с компилируемыми языками.
Строго говоря, жаба тоже не компилируемый язык, но это вообще ни о чем не говорит. Гораздо важней разделение языков на императивные и функциональные, со статистической и с динамической типизацией. Но это опять же с точки зрения удобства для программистов, а не с точки зрения потенциальных возможностей.
На любом Тьюринг-полном языке можно написать все что угодно, но например компиляторы или интерпретаторы очень сильно удобней писать все таки на С++ чем на жабе или питоне ))
legendary
Activity: 3108
Merit: 1359
Да и тот же Python интерпретируемый язык, а потому у него слабая скорость исполнения по сравнению с компилируемыми языками.
1) Не бывает "интерпретируемых языков", бывают интерпретаторы и компиляторы. Для C тоже можно написать интерпретатор, и это не сделает его "интерпретируемым".
2) Современные JIT компиляторы, такие как в движке v8, очень сообразительны по части оптимизации. И зачастую генерируемый ими код по скорости не особо-то отличается от аналогичного на C, если отличается вообще.
newbie
Activity: 9
Merit: 0
Имхо, время доверия к  самописным проектам -  ушло
обертка красивая - а вот начинка.....
legendary
Activity: 2744
Merit: 1588

От того, что Сатоши писал левой пяткой, С++ хуже не стал. Утечки памяти случаются если велосипеды какие-нибудь писать в стиле 80-х годов прошлого века. С тех пор как в std появились "умные указатели", про у течки памяти как-то даже и вспоминать не принято уже...
Haskell это кошерно, но если бы Сатоши написал биткоин на хаскеле, то он так бы и остался единственным программистом в своем проекте имхо. Сишка все таки популярна и понятна, а хаскель это больше для компутер сцайнс игрушка.
Мне вообще больше всех языков Лисп нравится, но для реальной разработки нужно ориентироваться на язык с мощным комунити, чтобы на любой вопрос было как минимум по 10 ответов на стаковерфлоу и по несколько статей на хабре.

Т.е. я правильно понимаю, что разобраться и поддерживать код можно одинаково хорошо на любом языке, где есть большое сообщество. Так как встречал на ютубе высказывания программистов, что на том же JAVA можно делать высокомасштабируемые проекты, а вот на том же Python уже так не получиться. Да и тот же Python интерпретируемый язык, а потому у него слабая скорость исполнения по сравнению с компилируемыми языками.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Раз уж заговорили здесь о блокчейне, то хотелось бы услышать ответ на такой вопрос. Какой язык программирования наиболее подходит для создания криптовалют?

Ведь в свое время говорили, что Сатоши сильно плохой код написал на С++, кроме того, там ведь надо постоянно следить за утечками памяти.

Может упор делать на такие языки, как Haskell там вроде он может поддерживать очень крупные проекты и ошибок практически не бывает.

От того, что Сатоши писал левой пяткой, С++ хуже не стал. Утечки памяти случаются если велосипеды какие-нибудь писать в стиле 80-х годов прошлого века. С тех пор как в std появились "умные указатели", про у течки памяти как-то даже и вспоминать не принято уже...
Haskell это кошерно, но если бы Сатоши написал биткоин на хаскеле, то он так бы и остался единственным программистом в своем проекте имхо. Сишка все таки популярна и понятна, а хаскель это больше для компутер сцайнс игрушка.
Мне вообще больше всех языков Лисп нравится, но для реальной разработки нужно ориентироваться на язык с мощным комунити, чтобы на любой вопрос было как минимум по 10 ответов на стаковерфлоу и по несколько статей на хабре.
legendary
Activity: 2744
Merit: 1588
Раз уж заговорили здесь о блокчейне, то хотелось бы услышать ответ на такой вопрос. Какой язык программирования наиболее подходит для создания криптовалют?

Ведь в свое время говорили, что Сатоши сильно плохой код написал на С++, кроме того, там ведь надо постоянно следить за утечками памяти.

Может упор делать на такие языки, как Haskell там вроде он может поддерживать очень крупные проекты и ошибок практически не бывает.
kzv
legendary
Activity: 1722
Merit: 1285
OpenTrade - Open Source Cryptocurrency Exchange
Интересно конечно.
Только без пропущенных вещей: "как правильная работа алгоритма Proof of Work, автоматическая настройка сложности, проверка цепочки, хэши и т. д. " получается просто забавная визуализация не более.

Алгоритм расчета сложности автор смешной придумал, но для домохозяек потянет:
Quote
while (hash.substr(0,4) !== '0'.repeat(4));

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

legendary
Activity: 1932
Merit: 4602
Часть 2: BLOCKCHAIN

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

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

Code:
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 (б).

Часть 2(b): Добавление блоков в Blockchain

Давайте начнем с кода, как мы делали до сих пор, напишите этот код после: constructor function:
Code:
   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
  • т.е. блок генезиса. Таким образом, эта строка всегда возвращает последний элемент, доступный в массиве, и передает его функции createBlock.

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

Вы можете посетить: https://webtricks.website/blockchainCode.html и увидеть весь код.


TЕСТИРОВАНИЕ КОДА

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

Code:
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, автоматическая настройка сложности, проверка цепочки, хэши и т. д. Но руководство уже слишком длинное, так что пусть это будет в следующий раз. Cheesy
Также проголосуйте, если хотите, чтобы я создал руководство по созданию криптовалюты на блокчейне.

Это перевод поста пользователя webtricks. Спасибо ему за информацию!
legendary
Activity: 1932
Merit: 4602
Это перевод поста пользователя webtricks. Спасибо ему за информацию!

Header designed by: HBKMusiK                              


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

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

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



Часть 1: Блок

Часть 1(a):Конструктор

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

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


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

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

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

Вот первый фрагмент кода:
Code:
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 (б).

Часть 1(b): Genesis блок

Вот код для части: 1 (б), этот код будет следовать после функции конструктора:
Code:
   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 на самом деле означает возврат (умный, да Smiley ). Это гарантирует, что всякий раз, когда эта функция вызывается, функция возвращает значение генезис блока. «New» относится к экземпляру класса Block. Всякий раз, когда мы создаем экземпляр любого класса, мы должны использовать новое ключевое слово. «this» относится к конструктору класса Block. Если мы используем конструктор внутри класса, тогда мы должны ссылаться на него с помощью «this».

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


Часть 1(c): Создать Block function и Proof of Work
Код после функции createGenesis ():
Code:
   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 в следующей части. Давайте приступим.

Часть 1(d): SHA256
Давайте сначала напишем код, он будет идти вверху файла перед классом Block:
Code:
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.
Jump to: