[Перевод] Внедрение блокчейна в код Java

Java Программа перевода самородков биткойн блокчейн
[Перевод] Внедрение блокчейна в код Java

Реализация блокчейна с помощью Java-кода

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

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

Область применения блокчейна еще не изучена. Это также может нарушить автоматизацию предприятия. Существует много доступной информации о том, как работает блокчейн. У нас глубокий блокчейнБесплатный информационный документ(Регистрация не требуется).

В этой статье основное внимание будет уделено архитектуре блокчейна, в частности, на простых примерах кода будет продемонстрировано, как «неизменяемый, предназначенный только для добавления» распределенный реестр работает.

Разработчику проще читать код, чем читать технические статьи. По крайней мере для меня. Итак, приступим!

Краткое описание блокчейна

Во-первых, давайте кратко подытожим блокчейн. Блок содержит некоторую информацию заголовка и любой набор типов данных или набор транзакций. Цепочка начинается с первого (начального) блока. По мере добавления/расширения транзакций новые блоки будут создаваться в зависимости от того, сколько транзакций может храниться в блоке.

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

неизменность

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

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

...
public class Block<T extends Tx>; {
public long timeStamp;
private int index;
private List<T> transactions = new ArrayList<T>();
private String hash;
private String previousHash;
private String merkleRoot;
private String nonce = "0000";

// 缓存事务用 SHA256 哈希
    public Map<String,T> map = new HashMap<String,T>();
...

Обратите внимание, что введенный универсальный типTxтип. Это позволяет изменять данные транзакции. также,previousHashСвойство будет ссылаться на хэш предыдущего блока. будет описано позжеmerkleRootиnonceАтрибуты.

хэш блока

Для каждого блока может быть рассчитан один хэш. На самом деле это хэш всех связанных вместе свойств блока, включая хэш предыдущего блока и результирующий хеш SHA-256, рассчитанный на его основе.

Ниже приведенBlock.javaОпределенный в классе метод для вычисления хеш-значения.

...
public void computeHash() {
     Gson parser = new Gson(); // 可能应该缓存这个实例
     String serializedData = parser.toJson(transactions);  
     setHash(SHA256.generateHash(timeStamp + index + merkleRoot + serializedData + nonce + previousHash));
     }
...

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

цепь

Блокчейн управляет блоками, принимая транзакции. При достижении заданного порога создается блок. НижеSimpleBlockChain.javaЧастичная реализация:

...
...
public class SimpleBlockchain<T extends Tx> {
public static final int BLOCK_SIZE = 10;
public List<Block<T>> chain = new ArrayList<Block<T>>();

public SimpleBlockchain() {
// 创建初始区块
chain.add(newBlock());
}

...

Обратите внимание, что свойство chain поддерживает типTxсписок блоков. также,无参构造器«Начальный» блок инициализируется при создании начального связанного списка. НижеnewBlock()исходный код метода.

...
public Block<T> newBlock() {
int count = chain.size();
String previousHash = "root";

if (count > 0)
previousHash = blockChainHash();

Block<T> block = new Block<T>();

block.setTimeStamp(System.currentTimeMillis());
block.setIndex(count);
block.setPreviousHash(previousHash);
return block;
}
...

Этот метод создаст новый экземпляр блока, сгенерирует соответствующие значения, присвоит хеш предыдущего блока (который будет хешем заголовка цепочки) и вернет этот экземпляр.

Прежде чем добавлять блоки в цепочку, блоки можно проверить, сравнив предыдущий хеш нового блока с последним блоком цепочки (заголовком), чтобы убедиться, что они совпадают.SimpleBlockchain.javaЭтот процесс описан.

....
public void addAndValidateBlock(Block<T> block) {

// 比较之前的区块哈希,如果有效则添加
Block<T> current = block;
for (int i = chain.size() - 1; i >= 0; i--) {
Block<T> b = chain.get(i);
if (b.getHash().equals(current.getPreviousHash())) {
current = b;
} else {

throw new RuntimeException("Block Invalid");
}

}

this.chain.add(block);
}
...

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

Ниже приведеныSimpleBlockChain.java validate()реализация метода.

...
public boolean validate() {

String previousHash = null;
for (Block<T> block : chain) {
String currentHash = block.getHash();
if (!currentHash.equals(previousHash)) {
return false;
}

previousHash = currentHash;

}

return true;

}
...

Как видите, попытаться каким-либо образом сфальсифицировать данные транзакции или любой другой атрибут очень сложно. И по мере того, как цепочка будет расти, это будет по-прежнему очень, очень, очень сложно, практически невозможно — если только не будут доступны квантовые компьютеры!

Добавить транзакцию

Еще одним важным техническим моментом технологии блокчейн является то, что она распределена. Инкрементальный характер блокчейна помогает ему хорошо воспроизводиться среди узлов сети блокчейна. Узлы обычно взаимодействуют в одноранговой сети, как в биткойнах, но это не обязательно. В других реализациях блокчейна используется децентрализованный подход, например, использование API на основе протокола HTTP. Это все не по теме.

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

смарт-контракт: Компьютерный протокол, предназначенный для облегчения, проверки или обеспечения выполнения контракта и исполнения в цифровой форме.

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

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

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

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

Дерево Меркла

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

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

Ниже приведеныBlock.javaМетод класса, создающий дерево Меркла из списка транзакций.

...
public List<String> merkleTree() {
ArrayList<String> tree = new ArrayList<>();
// 首先,
// 将所有交易的哈希作为叶子节点添加到树中。
for (T t : transactions) {
tree.add(t.hash());
}
int levelOffset = 0; // 当前处理的列表中的偏移量。
//  当前层级的第一个节点在整个列表中的偏移量。
// 每处理完一层递增,
// 当我们到达根节点时(levelSize == 1)停止。
for (int levelSize = transactions.size(); levelSize > 1; levelSize = (levelSize + 1) / 2) {
// 对于该层上的每一对节点:
for (int left = 0; left < levelSize; left += 2) {
// 在我们没有足够交易的情况下,
// 右节点和左节点
// 可以一样。
int right = Math.min(left + 1, levelSize - 1);
String tleft = tree.get(levelOffset + left);
String tright = tree.get(levelOffset + right);
tree.add(SHA256.generateHash(tleft + tright));
}
// 移动至下一层
levelOffset += levelSize;
}
return tree;
}

...

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

...
@Test
public void merkleTreeTest() {

// 创建链,添加交易

SimpleBlockchain<Transaction> chain1 = new SimpleBlockchain<Transaction>();

chain1.add(new Transaction("A")).add(new Transaction("B")).add(new Transaction("C")).add(new Transaction("D"));

// 获取链中的区块
Block<Transaction> block = chain1.getHead();

System.out.println("Merkle Hash tree :" + block.merkleTree());

//从区块中获取交易
Transaction tx = block.getTransactions().get(0);

// 查看区块交易是否有效,它们应该是有效的
block.transasctionsValid();
assertTrue(block.transasctionsValid());

// 更改交易数据
tx.setValue("Z");

//当区块的默克尔根与计算出来的默克尔树不匹配时,区块不应该是有效。
assertFalse(block.transasctionsValid());

}

...

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

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

Добыча и доказательство работы

В мире биткойнов процесс объединения транзакций в блоки и отправки их членам цепочки для проверки называется «майнингом».

В более широком смысле в блокчейне это называется консенсусом. Существует несколько проверенных алгоритмов распределенного консенсуса, и какой механизм использовать, зависит от того, есть ли у вас публичная или частная цепочка блоков. В нашем официальном документе это описано более подробно, но основное внимание в этой статье уделяется принципам блокчейна, поэтому в этом примере мы будем использовать механизм консенсуса Proof-of-Work (POW).

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

Пример проекта Javaсуществует одинMiner.javaкласса, из которыхproofOfWork(Block block)Реализация метода показана ниже.

private String proofOfWork(Block block) {

String nonceKey = block.getNonce();
long nonce = 0;
boolean nonceFound = false;
String nonceHash = "";

Gson parser = new Gson();
String serializedData = parser.toJson(transactionPool);
String message = block.getTimeStamp() + block.getIndex() + block.getMerkleRoot() + serializedData
+ block.getPreviousHash();

while (!nonceFound) {

nonceHash = SHA256.generateHash(message + nonce);
nonceFound = nonceHash.substring(0, nonceKey.length()).equals(nonceKey);
nonce++;

}

return nonceHash;

}

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

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

модульный тест

Вы можете увидеть тесты JUnit с примерами Java, которые объединяют эти концепции на GitHub.

Запустите его и посмотрите, как работает этот простой блокчейн.

Кроме того, если вы программист на C#, на самом деле (я никому не скажу), у нас также есть примеры, написанные на C#. Ниже представлена ​​реализация блокчейна C#.Пример.

Последние мысли

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

Все примеры, представленные в этой статье, используются в нашейБелая книга о глубоком блокчейне(Для чтения не требуется регистрация.) Эти примеры более подробно объясняются в официальном документе.

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

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


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.