Перейти к основному содержимому

Реализация простого блокчейна на Java

· 11 мин. чтения

1. Обзор

В этом уроке мы изучим основные концепции технологии блокчейн. Мы также реализуем базовое приложение на Java, которое фокусируется на концепциях.

Далее мы обсудим некоторые передовые концепции и практическое применение этой технологии.

2. Что такое блокчейн?

Итак, давайте сначала разберемся, что же такое блокчейн…

Что ж, его происхождение восходит к техническому документу, опубликованному Сатоши Накамото о биткойнах еще в 2008 году.

Блокчейн — это децентрализованный реестр информации . Он состоит из блоков данных, соединенных с помощью криптографии. Он принадлежит к сети узлов, соединенных через общедоступную сеть. Мы поймем это лучше, когда позже попытаемся создать базовый учебник.

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

  • Защита от несанкционированного доступа: Прежде всего, данные как часть блока защищены от несанкционированного доступа . На каждый блок ссылается криптографический дайджест, обычно известный как хэш, что делает блок защищенным от несанкционированного доступа.
  • Децентрализованный: вся цепочка блоков полностью децентрализована в сети. Это означает, что главного узла нет, и каждый узел в сети имеет одну и ту же копию.
  • Прозрачный: каждый узел, участвующий в сети, проверяет и добавляет новый блок в свою цепочку на основе консенсуса с другими узлами. Следовательно, каждый узел имеет полную видимость данных.

3. Как работает блокчейн?

Теперь давайте разберемся, как работает блокчейн.

Основными единицами блокчейна являются блоки . Один блок может инкапсулировать несколько транзакций или другие ценные данные:

./42d08e884ff9e7c9edb3004a96da2ae2.jpg

3.1. Добыча блока

Мы представляем блок хеш-значением. Генерация хеш-значения блока называется «майнингом» блока. Майнинг блока, как правило, требует больших вычислительных ресурсов, поскольку он служит «доказательством работы».

Хэш блока обычно состоит из следующих данных:

  • В первую очередь хэш блока состоит из транзакций, которые он инкапсулирует.
  • Хэш также состоит из временной метки создания блока.
  • Он также включает одноразовый номер, произвольное число, используемое в криптографии.
  • Наконец, хеш текущего блока также включает в себя хэш предыдущего блока.

Несколько узлов в сети могут одновременно конкурировать за майнинг блока. Помимо генерации хэша, узлы также должны проверять легитимность транзакций, добавляемых в блок. Победит в гонке тот, кто первым добудет блок!

3.2. Добавление блока в блокчейн

Хотя добыча блока требует больших вычислительных ресурсов, проверка легитимности блока относительно намного проще . Все узлы в сети участвуют в проверке вновь добытого блока.

./a5cd54e21b90d2ce607d3afb7fd1ab37.jpg

Таким образом, вновь добытый блок добавляется в блокчейн по согласованию узлов.

Сейчас доступно несколько согласованных протоколов, которые мы можем использовать для проверки. Узлы в сети используют один и тот же протокол для обнаружения вредоносной ветви цепочки. Следовательно, вредоносная ветвь, даже если она будет введена, вскоре будет отвергнута большинством узлов.

4. Базовый блокчейн в Java

Теперь у нас достаточно контекста, чтобы приступить к созданию простого приложения на Java.

Наш простой пример иллюстрирует основные концепции , которые мы только что рассмотрели. Приложение производственного уровня влечет за собой множество соображений, которые выходят за рамки этого руководства. Однако позже мы коснемся некоторых сложных тем.

4.1. Реализация блока

Во-первых, нам нужно определить простой POJO, который будет содержать данные для нашего блока:

public class Block {
private String hash;
private String previousHash;
private String data;
private long timeStamp;
private int nonce;

public Block(String data, String previousHash, long timeStamp) {
this.data = data;
this.previousHash = previousHash;
this.timeStamp = timeStamp;
this.hash = calculateBlockHash();
}
// standard getters and setters
}

Давайте разберемся, что мы здесь упаковали:

  • Хэш предыдущего блока, важная часть для построения цепочки
  • Фактические данные, любая информация, имеющая ценность, например, контракт
  • Отметка времени создания этого блока
  • Nonce — произвольное число, используемое в криптографии.
  • Наконец, хэш этого блока, рассчитанный на основе других данных

4.2. Вычисление хэша

Теперь, как мы вычисляем хэш блока? Мы использовали метод calculateBlockHash , но еще не видели его реализации. Прежде чем мы реализуем этот метод, стоит потратить некоторое время на то, чтобы понять, что такое хеш.

Хэш — это результат чего-то, известного как хэш-функция. Хэш -функция преобразует входные данные произвольного размера в выходные данные фиксированного размера . Хэш весьма чувствителен к любым изменениям во входных данных, какими бы незначительными они ни были.

Более того, получить исходные данные только из его хэша невозможно. Эти свойства делают хеш-функцию весьма полезной в криптографии.

Итак, давайте посмотрим, как мы можем сгенерировать хэш нашего блока в Java:

public String calculateBlockHash() {
String dataToHash = previousHash
+ Long.toString(timeStamp)
+ Integer.toString(nonce)
+ data;
MessageDigest digest = null;
byte[] bytes = null;
try {
digest = MessageDigest.getInstance("SHA-256");
bytes = digest.digest(dataToHash.getBytes(UTF_8));
} catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
logger.log(Level.SEVERE, ex.getMessage());
}
StringBuffer buffer = new StringBuffer();
for (byte b : bytes) {
buffer.append(String.format("%02x", b));
}
return buffer.toString();
}

Здесь происходит довольно много всего, давайте разберемся в них подробно:

  • Во-первых, мы объединяем разные части блока, чтобы сгенерировать хэш из
  • Затем мы получаем экземпляр хеш-функции SHA-256 из MessageDigest.
  • Затем мы генерируем хеш-значение наших входных данных, которое представляет собой массив байтов.
  • Наконец, мы преобразуем массив байтов в шестнадцатеричную строку, хэш обычно представляется как 32-значное шестнадцатеричное число.

4.3. Мы уже добыли блок?

Пока все звучит просто и элегантно, за исключением того, что мы еще не добыли блок. Итак, что именно влечет за собой майнинг блока, который уже некоторое время захватывает воображение разработчиков!

Что ж, добыча блока означает решение вычислительно сложной задачи для блока. В то время как вычисление хеша блока несколько тривиально, найти хеш, начинающийся с пяти нулей, — нет. Еще сложнее будет найти хеш, начинающийся с десяти нулей, и мы получим общее представление.

Итак, как именно мы можем это сделать? Честно говоря, решение гораздо менее причудливое! Мы пытаемся достичь этой цели с помощью грубой силы. Здесь мы используем nonce:

public String mineBlock(int prefix) {
String prefixString = new String(new char[prefix]).replace('\0', '0');
while (!hash.substring(0, prefix).equals(prefixString)) {
nonce++;
hash = calculateBlockHash();
}
return hash;
}

Давайте посмотрим, что мы пытаемся сделать здесь:

  • Начнем с определения префикса, который мы хотим найти.
  • Затем мы проверяем, нашли ли мы решение
  • Если нет, мы увеличиваем одноразовый номер и вычисляем хэш в цикле.
  • Цикл продолжается до тех пор, пока мы не выиграем джекпот

Здесь мы начинаем со значения nonce по умолчанию и увеличиваем его на единицу. Но есть более сложные стратегии запуска и увеличения одноразового номера в реальных приложениях. Кроме того, мы не проверяем наши данные здесь, что обычно является важной частью.

4.4. Давайте запустим пример

Теперь, когда мы определили наш блок вместе с его функциями, мы можем использовать это для создания простой цепочки блоков. Мы сохраним это в ArrayList :

List<Block> blockchain = new ArrayList<>();
int prefix = 4;
String prefixString = new String(new char[prefix]).replace('\0', '0');

Кроме того, мы определили префикс из четырех, что фактически означает, что мы хотим, чтобы наш хэш начинался с четырех нулей.

Давайте посмотрим, как мы можем добавить блок здесь:

@Test
public void givenBlockchain_whenNewBlockAdded_thenSuccess() {
Block newBlock = new Block(
"The is a New Block.",
blockchain.get(blockchain.size() - 1).getHash(),
new Date().getTime());
newBlock.mineBlock(prefix);
assertTrue(newBlock.getHash().substring(0, prefix).equals(prefixString));
blockchain.add(newBlock);
}

4.5. Проверка блокчейна

Как узел может подтвердить, что блокчейн действителен? Хотя это может быть довольно сложно, давайте подумаем о простой версии:

@Test
public void givenBlockchain_whenValidated_thenSuccess() {
boolean flag = true;
for (int i = 0; i < blockchain.size(); i++) {
String previousHash = i==0 ? "0" : blockchain.get(i - 1).getHash();
flag = blockchain.get(i).getHash().equals(blockchain.get(i).calculateBlockHash())
&& previousHash.equals(blockchain.get(i).getPreviousHash())
&& blockchain.get(i).getHash().substring(0, prefix).equals(prefixString);
if (!flag) break;
}
assertTrue(flag);
}

Итак, здесь мы делаем три конкретные проверки для каждого блока:

  • Сохраненный хеш текущего блока - это то, что он вычисляет.
  • Хэш предыдущего блока, хранящийся в текущем блоке, является хешем предыдущего блока.
  • Текущий блок был добыт

5. Некоторые дополнительные концепции

Хотя наш базовый пример раскрывает основные концепции блокчейна, он, безусловно, не полон. Чтобы применить эту технологию на практике, необходимо принять во внимание несколько других соображений.

Хотя невозможно подробно описать все из них, давайте рассмотрим некоторые из наиболее важных:

5.1. Проверка транзакции

Вычисление хеша блока и нахождение нужного хеша — это только одна часть майнинга. Блок состоит из данных, часто в виде нескольких транзакций. Они должны быть проверены, прежде чем их можно будет сделать частью блока и майнить.

Типичная реализация блокчейна устанавливает ограничение на то, сколько данных может быть частью блока . Он также устанавливает правила проверки транзакции . Несколько узлов в сети участвуют в процессе проверки.

5.2. Альтернативный консенсусный протокол

Мы видели, что алгоритм консенсуса, такой как «Proof of Work», используется для майнинга и проверки блока. Однако это не единственный алгоритм консенсуса, доступный для использования.

Есть несколько других алгоритмов консенсуса на выбор , таких как Proof of Stake, Proof of Authority и Proof of Weight. Все это имеет свои плюсы и минусы. Какой из них использовать, зависит от типа приложения, которое мы собираемся разработать.

5.3. Награда за майнинг

Сеть блокчейна обычно состоит из добровольных узлов. Итак, зачем кому-то хотеть вносить свой вклад в этот сложный процесс и поддерживать его законность и рост?

Это связано с тем, что узлы получают вознаграждение за проверку транзакций и добычу блока . Эти вознаграждения обычно представляют собой монеты, связанные с приложением. Но приложение может решить, что вознаграждение может быть чем-то ценным.

5.4. Типы узлов

Работа блокчейна полностью зависит от его сети. Теоретически сеть полностью децентрализована, и все узлы равны. Однако на практике сеть состоит из нескольких типов узлов.

В то время как полный узел имеет полный список транзакций, легкий узел имеет только частичный список . Более того, не все узлы участвуют в проверке и валидации.

5.5. Безопасная связь

Одной из отличительных черт технологии блокчейна является ее открытость и анонимность. Но как он обеспечивает безопасность транзакций, проводимых внутри? Это основано на криптографии и инфраструктуре открытого ключа .

Инициатор транзакции использует свой закрытый ключ для ее защиты и прикрепляет к открытому ключу получателя. Узлы могут использовать открытые ключи участников для проверки транзакций.

6. Практическое применение блокчейна

Таким образом, блокчейн кажется захватывающей технологией, но она также должна оказаться полезной. Эта технология существует уже некоторое время, и, разумеется, она оказалась прорывной во многих областях.

Его применение во многих других областях активно ведется. Разберемся в самых популярных приложениях:

  • Валюта : Это, безусловно, старейшее и наиболее широко известное использование блокчейна благодаря успеху Биткойна. Они предоставляют безопасные и беспрепятственные деньги людям по всему миру без какого-либо вмешательства центральной власти или правительства.
  • Идентичность : цифровая идентификация быстро становится нормой в современном мире. Однако это связано с проблемами безопасности и взломом. Блокчейн неизбежно произведет революцию в этой области с полностью безопасными и защищенными от несанкционированного доступа идентификационными данными.
  • Здравоохранение : отрасль здравоохранения загружена данными, в основном обрабатываемыми центральными органами. Это снижает прозрачность, безопасность и эффективность обработки таких данных. Технология блокчейн может предоставить систему без какой-либо третьей стороны для обеспечения столь необходимого доверия.
  • Правительство : Возможно, это та область, которая вполне открыта для разрушения технологией блокчейна. Правительство обычно находится в центре нескольких служб для граждан, которые часто страдают неэффективностью и коррупцией. Блокчейн может помочь наладить гораздо лучшие отношения между правительством и гражданами.

7. Торговые инструменты

Хотя наша базовая реализация здесь полезна для выявления концепций, разрабатывать продукт на блокчейне с нуля нецелесообразно. К счастью, сейчас это пространство созрело, и у нас есть несколько весьма полезных инструментов, с которых можно начать.

Давайте рассмотрим некоторые из популярных инструментов для работы в этом пространстве:

  • Solidity : Solidity — это объектно-ориентированный язык программирования со статической типизацией, разработанный для написания смарт-контрактов. Его можно использовать для написания смарт-контрактов на различных блокчейн-платформах, таких как Ethereum .
  • Remix IDE : Remix — это мощный инструмент с открытым исходным кодом для написания смарт-контрактов в Solidity. Это позволяет пользователю писать смарт-контракты прямо из браузера.
  • Truffle Suite : Truffle предоставляет набор инструментов, которые помогут разработчику начать разработку распределенных приложений. Сюда входят трюфель, ганаш и морось.
  • Ethlint/Solium : Solium позволяет разработчикам гарантировать, что их смарт-контракты, написанные на Solidity, не имеют проблем со стилем и безопасностью . Solium также помогает в устранении этих проблем.
  • Parity : Parity помогает настроить среду разработки для смарт-контракта на Эфириуме. Он обеспечивает быстрый и безопасный способ взаимодействия с блокчейном.

8. Заключение

Подводя итог, в этом уроке мы рассмотрели основные понятия технологии блокчейн. Мы поняли, как сеть майнит и добавляет новый блок в блокчейн. Далее мы реализовали основные концепции на Java. Мы также обсудили некоторые передовые концепции, связанные с этой технологией.

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

Как всегда, код можно найти на GitHub .