У нас уже есть блокчейн с блоками, которые мы можем проверить, если он являются действительными. Но как мы узнаем, что вся сети действительна? — чтобы никто не вмешивался и не заменял всю сеть блоков на другую?
Гениальное решение, которое применяет технология блокчейн. Это идентификация подписей, которые сопряжены с очень большими трудностями при получении (вычислении). Поэтому для создания новой сети, заменяющей существующую, вам потребуется использовать исключительную вычислительную мощность — практически невозможно достичь.
Это то, что делают криптовалютные майнеры — идентифицируют подписи, которые удовлетворяют определенным условиям, и блоки добавляются в сеть. Чем дольше идет майнинг, тем сложнее будет создать сеть, аналогичную существующей.
Но как мы можем сделать подпись более сложной? — понятен только алгоритм — он повторно используется для проверки! Решение простое — при создании подписи мы добавляем параметр, который изменяется до тех пор, пока не будет получена подпись, соответствующая определенному правилу. Пример:
— условие: подпись начинается с 5 нулей (0000 .)
— В дополнение к уже установленным датам блок также будет содержать информацию: целое число, которое будет включено в расчет подписи блока. Шаги для поиска правильного числа: найдите подпись блока, если число = 1, и посмотрите, равны ли первые 5 символов нулю. Если не дать число значение 2, мы переделаем подпись и проверяем, есть ли 5 нулей в начале; и так далее, пока мы не найдем нужную число (в этом случае нам, вероятно, придется попробовать несколько миллионов вариантов)
Первый шаг — добавить блок (класс Block) в новое поле — число:
private int номер; //добавлен новый номер public int getномер() { return номер; } public void setномер(int номер) { this.номер = номер; }
Давайте также не забудем изменить функцию вычисления подписи, чтобы включить наш номер.
public static String calculateHash(Block block) { String calculatedhash = applySha256( block.getPreviousHash() + Long.toString(block.getTimestamp()) + block.getData() + Integer.toString(block.getномер, который теперь является частью подписи );())//номер, который теперь является частью подписи ); return calculatedhash; }
Следующим шагом является добавление функции майнинга в класс Utile (где сложность будет заключаться в наличии нулей перед подписью):
public static String mineBlock(int difficulty, Block block) { //Мы создаем string, состоящии только из нулей, число которых равно сложности (мы будем использовать ее для проверки того, что подпись начинается с такой string) String target = new String(new char[difficulty]).replace('
public static String mineBlock(int difficulty, Block block) { //Мы создаем string, состоящии только из нулей, число которых равно сложности (мы будем использовать ее для проверки того, что подпись начинается с такой string) String target = new String(new char[difficulty]).replace('\0', '0'); int numar = 0; //вычисляем, как долго подпись не соответствует условию while (!block.getHash().substring(0, difficulty).equals(target)) { numar++; //увеличиваем число, чтобы повторить попытку block.setNumar(numar); block.setHash(calculateHash(block));//вычислить подпись } //когда выходим из while, у нас есть подпись, как мы хотим System.out.println("Мы получили блок!!! : " + block.getHash()); System.out.println("Номер=» номер); return block.getHash(); }
', '0'); int numar = 0; //вычисляем, как долго подпись не соответствует условию while (!block.getHash().substring(0, difficulty).equals(target)) { numar++; //увеличиваем число, чтобы повторить попытку block.setNumar(numar); block.setHash(calculateHash(block));//вычислить подпись } //когда выходим из while, у нас есть подпись, как мы хотим System.out.println("Мы получили блок!!! : " + block.getHash()); System.out.println("Номер=» + номер); return block.getHash(); }
Давайте сделаем тест, перейдя в main на уровень сложности = 5:
public static void main(String[] args) { List<Block> blocks = new ArrayList<Block>(); Block block1 = new Block("первое сообщение", "0"); Utile.mineBlock(5, block1); blocks.add(block1); Block block2 = new Block("второе сообщение", block1.getHash()); Utile.mineBlock(5, block2); blocks.add(block2); Block block3 = new Block("третье сообщение", block2.getHash()); Utile.mineBlock(5, block3); blocks.add(block3); Utile.printBlock(blocks); // block2.setData("второе измененное сообщение»);//мы вмешиваемся в сеть System.out.println("Сеть является " + (Utile.isChainValid(blocks) ? "valid" : "INvalid")); }
У меня примерно через три секунды майнировали блоки:
Я получил блок !!! : 00000129515144fcfbee5e054d8c6cc47c3a22c068264fbb39ea15cb04af7d94
Номер = 136 386
Я получил блок !!! : 00000cf5b3778ab748d1604b60479fd85785b87812a34cecb62e7d2cde4bfc1a
Номер = 272 565
Я получил блок !!! : 000003fa79aecc19771d96a4af73cd1e8216ec874aa977aa5291826dba28b08d
Номер = 22787
**********START BLOCK***********
дата = первое сообщение
дата создания = 11.05.2018 11:26:50
подпись = 00000129515144fcfbee5e054d8c6cc47c3a22c068264fbb39ea15cb04af7d94
предыдущая подпись = 0
Номер = 136386
**********END BLOCK***********
**********START BLOCK***********
дата = второе сообщение
дата создания = 11.05.2018 11:26:51
подпись = 00000cf5b3778ab748d1604b60479fd85785b87812a34cecb62e7d2cde4bfc1a
предыдущая подпись = 00000129515144fcfbee5e054d8c6cc47c3a22c068264fbb39ea15cb04af7d94
Номер = 272565
**********END BLOCK***********
**********START BLOCK***********
дата = третье сообщение
дата создания = 11.05.2018 11:26:52
подпись = 000003fa79aecc19771d96a4af73cd1e8216ec874aa977aa5291826dba28b08d
предыдущая подпись = 00000cf5b3778ab748d1604b60479fd85785b87812a34cecb62e7d2cde4bfc1a
номер = 22787
**********END BLOCK***********
Сеть действительна
На более высоких уровнях сложности время обработки увеличивается в геометрической прогрессии.
Теперь у нас есть механизм, с помощью которого мы можем гарантировать, что наша сеть не может быть заменена другой.
Что мы делаем с этим блокчейном? Он действительно не использует нас вообще, если мы не можем торговать с ним. Следующим шагом будет:
- Создайте виртуальный кошелек