Автор оригинала: Xavier Decuyper.
Создайте блокчан с помощью JavaScript PT.2
Это часть 2 серии о том, как построить простой блокчан с помощью JavaScript. В предыдущей части мы создали простой блокчан, который позволил нам обнаружить, когда кто-то подделал содержимым цепочки.
Есть две проблемы с нашими простыми блокчанами, которые мы должны решить:
Современные компьютеры очень быстро и могут добавлять тысячи блоков в нашу цепочку. Очевидно, мы не хотим, чтобы люди спам наш блокчан!
Еще можно вместить в нашу блокчан. Вы можете изменить содержимое блока, а затем просто пересчитать хэши (и предыдущие хеши) для всех блоков после него. Вы получите допустимую цепочку, даже если вы подделали его.
Очевидно, что это не то, что мы хотим! Итак, чтобы решить эти проблемы, блокировки имеют то, что называется «доказательством работы». С помощью этого механизма вы должны доказать, что вы устанавливаете много вычислительной мощности в блоке. Этот процесс также называется добыча Отказ
Доказательство работы требует хеша блока, чтобы начать с определенного количества нулей. Но как вы можете убедиться, что ваш хэш удовлетворяет этому правилу? Хеш блока определяется его содержанием. Так что, если мы не изменим содержимое, мы всегда получаем одно и то же хеш.
Решение для добавления Nonce
Значение для каждого блока. Это в основном некоторые случайные данные, которые мы можем измениться до тех пор, пока хэш нашего блока не начнется с достаточного количества нулей. И поскольку вы не можете влиять на вывод хеш-функции, вы должны попробовать много комбинаций и надеюсь, что вам повезет!
Количество необходимых нулевых нулей также называют «трудностью», и он установлен, поэтому есть постоянное количество новых блоков. В случае биткойна целью состоит в том, чтобы создать один новый блок каждые 10 минут. Поскольку компьютеры становятся быстрее со временем, они будут мои новые блоки быстрее. Чтобы компенсировать это, сложность автоматически увеличивается.
Итак, давайте реализуем это в нашем простом блокчане!
Давайте начнем с добавления Nonce
к нашему классу блока:
class Block{ constructor(timestamp, data, previousHash = '') { this.previousHash = previousHash; this.timestamp = timestamp; this.data = data; this.hash = this.calculateHash(); this.nonce = 0; }
Nonce
Единственное значение внутри нашего блока, которое мы можем измениться, чтобы повлиять на хеш блока. Мы не можем изменить временные метки или данные!
Далее давайте создадим MINEBLOCK ()
Метод, который фактически выполнит магию добычи блока. Этот метод получит необходимую сложность в качестве параметра и будет продолжать работать до тех пор, пока хэш нашего блока не начнется с достаточного количества нулей:
mineBlock(difficulty) { // Keep changing the nonce until the hash of our block starts with enough zero's. while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")) { this.nonce++; this.hash = this.calculateHash(); } console.log("BLOCK MINED: " + this.hash); }
Я только что создал простой цикл, который продолжает работать до тех пор, пока наш хэш не начнется с достаточного количества нулей. Мы используем сложность, чтобы узнать, сколько нужных нулей требуется. Сложность 5 означает, что наше хеш должно начать с 5 нулей.
Каждый раз, когда наш хэш не имеет достаточных нулей, мы увеличиваем NONCE на 1 и снова рассчитали хеш. И если мы нашли хеш, который соответствует сложности, мы вхожу в систему на консоль. Легкий!
Есть еще одна вещь, которую нам нужно сделать. В нашем Calcultinghash
Функция, мы на самом деле не принимаем Nonce
Переменная во внимание, поэтому я добавлю его:
calculateHash() { return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data) + this.nonce).toString(); }
Задача решена!
Давайте будем использовать эту новую систему в нашем классе Blockchain и посмотрим, как она работает. Я начну с определения сложности нашего блокчана в конструкторе. Мы определяем это здесь, потому что нам может понадобиться в нескольких местах позже:
constructor() { this.chain = [this.createGenesisBlock()]; this.difficulty = 3; }
Тогда мы должны адаптировать AddBlock
Способ так, чтобы он миниал блок, прежде чем нажать на нашу цепочку:
addBlock(newBlock) { newBlock.previousHash = this.getLatestBlock().hash; newBlock.mineBlock(this.difficulty); this.chain.push(newBlock); }
Хорошо, все сделано! Давайте теперь будем использовать наш новый блокчан с помощью алгоритма доказательства работы!
Давайте на самом деле используем это. Добавьте несколько заявлений Console.log здесь:
let savjeeCoin = new Blockchain(); console.log('Mining block 1...'); savjeeCoin.addBlock(new Block(1, "20/07/2017", { amount: 4 })); console.log('Mining block 2...'); savjeeCoin.addBlock(new Block(2, "20/07/2017", { amount: 8 }));
Когда мы запустим этот код, мы можем видеть, что процесс добычи не очень быстро. Алгоритм занимает некоторое время для производства блоков, которые начинаются с 3 ноль (как настроен за трудность).
Теперь попробуйте увеличить сложность от 3 до 5 и снова запустить его, и вы увидите, что для моих новых блоков требуется намного больше времени.
Алгоритм доказательства работы позволяет нам контролировать, как быстрые новые блоки могут быть добавлены в наш блокчан. Это, пожалуй, самый важный механизм безопасности блоков, и теперь вы знаете, как это работает!
Исходный код на Github И есть Видеоуправление Для этой второй части тоже.