Доброго времени суток!
Blockchain! Он начал свое победоносное шествие по планете! Проник в мозг бизнесменов, политиков, дворников!
Сам Герман Греф - рассказывает нам о том, как мы заживем с этой чудной технологией!
Поскольку бежать и закупать на последнюю зарплату пригоршню биткоинов уже поздно - расскажу как это устроено, чтобы вы могли сделать свои биткоины - с блэкджеком - и транзакциями=)
Blockchain - как технология - исторически неразрывно связан с понятием Bitcoin, поэтому придется - несмотря на то, что на фоне Грефа я смотрюсь недостаточно убедительно - сначала поговорить о биткоинах.
Итак, что нам известно?
Некто, называющий себя Сатоши Накамото в 2008 году опубликовал Bitcoin Whitepaper - документ, в котором описываются принципы работы биткоина. 3 января 2009 года был сгенерирован первый блок этой платежной системы - и все заверте...
Что интересно - реальная личность Сатоши не раскрыта до сих пор, так что за этим псевдонимом может прятаться кто угодно и в любом количестве. Версий много - ЦРУ, ФСБ, рептилоиды. Пока не доказано обратного - для простоты будем считать, что биткоины создал я=)
Что более интересно - в биткоине используется интересный способ хранения данных в определенном формате в виде цепочек блоков - блокчейна - о котором дальше и пойдет речь
При инициализации блокчейна - автоматически создается и добавляется genesis-блок без данных и с произвольно выбранным хэшем.
Для хэширования данных добавим в класс BlockChain методы hash:
Понятно, что любое изменение данных в блоках приведет к тому, что метод checkValidity вернет false.
Реализуем последний метод - добавления новых блоков в цепочку. Данный метод будет хэшировать данные блока и его время создания, корректно инициализировать блок - и добавлять в цепочку. Время рождения блока тут используется для того, чтобы независимо от данных сделать хэш уникальным:
Blockchain! Он начал свое победоносное шествие по планете! Проник в мозг бизнесменов, политиков, дворников!
Сам Герман Греф - рассказывает нам о том, как мы заживем с этой чудной технологией!
Поскольку бежать и закупать на последнюю зарплату пригоршню биткоинов уже поздно - расскажу как это устроено, чтобы вы могли сделать свои биткоины - с блэкджеком - и транзакциями=)
Итак, что нам известно?
Некто, называющий себя Сатоши Накамото в 2008 году опубликовал Bitcoin Whitepaper - документ, в котором описываются принципы работы биткоина. 3 января 2009 года был сгенерирован первый блок этой платежной системы - и все заверте...
Что интересно - реальная личность Сатоши не раскрыта до сих пор, так что за этим псевдонимом может прятаться кто угодно и в любом количестве. Версий много - ЦРУ, ФСБ, рептилоиды. Пока не доказано обратного - для простоты будем считать, что биткоины создал я=)
Что более интересно - в биткоине используется интересный способ хранения данных в определенном формате в виде цепочек блоков - блокчейна - о котором дальше и пойдет речь
Терминология
Итак, блокчейн - это просто последовательность блоков. Каждый блок имеет свой хэш и содержит хэш предыдущего блока и некоторые данные (например данные о транзакции - но в общем случае - совершенно произвольные данные):
Или, в более наглядном виде, блокчейн это:
Самый первый блок - паровозик - зовется genesis-блоком. Его хэш является точкой отсчета блокчейна.
Что такое хэш?
Хэш - это необратимая функция данных. При изменении данных - хэш будет изменяться. Этот простой механизм позволяет отслеживать валидность блокчейна. Если кто-либо попытается изменить данные в блокчейне - блокчейн станет невалидным, так как хэши в блоках и вновь вычисленные хэши данных блоков будут не совпадать.
Самый первый блок - паровозик - зовется genesis-блоком. Его хэш является точкой отсчета блокчейна.
Что такое хэш?
Хэш - это необратимая функция данных. При изменении данных - хэш будет изменяться. Этот простой механизм позволяет отслеживать валидность блокчейна. Если кто-либо попытается изменить данные в блокчейне - блокчейн станет невалидным, так как хэши в блоках и вновь вычисленные хэши данных блоков будут не совпадать.
Таким образом, чтобы сохранить валидность блокчейна - необходимо заново перехэшировать данные всех блоков.
Чтобы избежать этой ситуации, системы, основанные на базе блокчейн, используют дополнительные меры верификации. Например в сети Bitcoin запись блока должна быть подтверждена другими участниками сети. Хотя теоретически - возможность обойти это остается.
Реализация
Итак, напишем простую реализацию, которая демонстрирует описанную выше концепцию. Для начала - создадим класс, представляющий собой блок:
package com.blogspot.toolkas.blockchain;
public class Block {
/**
* Данные блока.
*/
private final byte[] data;
/**
* Хэш блока.
*/
private final byte[] hash;
/**
* Хэш предыдущего блока.
*/
private final byte[] prevHash;
/**
* Время создания блока.
*/
private final long created;
public Block(byte[] data, byte[] hash, byte[] prevHash, long created) {
this.data = data;
this.hash = hash;
this.prevHash = prevHash;
this.created = created;
}
public byte[] getData() {
return data;
}
public byte[] getHash() {
return hash;
}
public byte[] getPrevHash() {
return prevHash;
}
public long getCreated() {
return created;
}
}
Создадим класс BlockChain,
который управляет блоками:package com.blogspot.toolkas.blockchain;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlockChain {
private final List blocks = new ArrayList();
public BlockChain() {
blocks.add(new Block(null, new byte[]{1, 2, 3}, null));
}
}
При инициализации блокчейна - автоматически создается и добавляется genesis-блок без данных и с произвольно выбранным хэшем.
Для хэширования данных добавим в класс BlockChain методы hash:
private byte[] hash(Block block) throws NoSuchAlgorithmException {
return hash(block.getData());
}
private byte[] hash(byte[] data) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest(data);
}
Теперь добавим метод, проверяющий валидность блокчейна. Алгоритм проверки
в нашем случае довольно прост. Для каждого блока необходимо:
- Проверить на совпадение хэш предыдущего блока со значением prevHash;
- Вычислить хэш данных каждого блока и проверить его на совпадение с переменной hash;
Если для какого либо блока одна из проверок провалилась - блок считается невалидным. Таким образом, добавим метод checkValidity, который реализует описанный выше алгоритм:
public boolean checkValidity() throws NoSuchAlgorithmException {
for (int i = 1; i < blocks.size(); i++) {
Block prev = blocks.get(i - 1);
Block block = blocks.get(i);
byte[] newHash = hash(block);
if (!Arrays.equals(newHash, block.getHash())) {
return false;
}
if (!Arrays.equals(prev.getHash(), block.getPrevHash())) {
return false;
}
}
return true;
}
Реализуем последний метод - добавления новых блоков в цепочку. Данный метод будет хэшировать данные блока и его время создания, корректно инициализировать блок - и добавлять в цепочку. Время рождения блока тут используется для того, чтобы независимо от данных сделать хэш уникальным:
public void add(byte[] data) throws IOException,
NoSuchAlgorithmException {
Objects.requireNonNull(data);
long now = System.currentTimeMillis();
byte[] fullData = getFullData(data, now);
byte[] hash = hash(fullData);
Block last = blocks.get(blocks.size() - 1);
Block block = new Block(fullData, hash,
last.getHash(), now);
blocks.add(block);
}
private byte[] getFullData(byte[] data, long now)
throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(DataOutputStream output = new DataOutputStream(baos)) {
output.write(data);
output.writeLong(now);
}
return baos.toByteArray();
}
Проверка
Для того, чтобы быстро проверить корректность работы нашей реализации
алгоритма blockchain, выполним простой код:
алгоритма blockchain, выполним простой код:
BlockChain blockChain = new BlockChain();
blockChain.add("AAA".getBytes("UTF-8"));
blockChain.add("BBB".getBytes("UTF-8"));
blockChain.add("CCC".getBytes("UTF-8"));
System.out.println(blockChain.checkValidity());
Результатом работы приведенного кода будет true. Если же вы перед вызовом метода checkValidity() средствами IDE поменяете в одном из блоков (кроме первого) данные, то результатом вызова метода checkValidity() будет false.
Итого
Итак, дорогой будущий мультимиллиардер, мы написали примитивную реализацию алгоритма blockchain. Исходный код нашего супер-продукта находится тут. Блоки хранятся в памяти, их можно добавлять и валидировать всю цепочку.
Мы не коснулись множества вопросов - сохранения данных на диск, майнинг и т.п. Но всему свое время. Ждите известий в следующей серии=)
Мы не коснулись множества вопросов - сохранения данных на диск, майнинг и т.п. Но всему свое время. Ждите известий в следующей серии=)
Комментариев нет:
Отправить комментарий