Merkle tree en Java blockchain de escritura a mano real

Xiang Biao


Prefacio

Para aprender la tecnología blockchain, entonces el árbol Merkle debe entenderse en profundidad. Este artículo utilizará el árbol Merkle escrito a mano en Java


1. Introducción al árbol Merkle

El árbol de Merkle es una estructura de datos propuesta por Ralph Merkle en 1979 y que lleva su nombre. ¿Qué es un árbol Merkle? La definición de árbol de Merkle en Wikipedia es la siguiente:


En criptografía e informática, un árbol hash o árbol Merkle es un árbol en el que cada nodo hoja está marcado con el hash del bloque de datos, y cada nodo no hoja está marcado con su subsección o etiqueta. El árbol de hash Merkle cifrado permite una verificación eficaz y segura del contenido de grandes estructuras de datos, que es una generalización de listas de hash y cadenas de hash.
La estructura del árbol Merkle se muestra en la siguiente figura:

Inserte la descripción de la imagen aquí
Recopile uno o más bloques de registros nuevos, haga un hash de estos registros, luego empareje los hash, el hash, vuelva a emparejar y hash de nuevo, hasta que un solo hash retiene este hash único que se denomina raíz Merkle del árbol merkle . Como se muestra en la siguiente figura en el navegador de Bitcoin :
Inserte la descripción de la imagen aquí
el 1 2 3 4 dos en uno en la figura, finalmente consiguió el Merkle Root: f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 Si
está interesado, puede leer el artículo MerkleTree de Bitcoin Code .

Dos, implementación java

1. El código es el siguiente:

package org.xiangbiao;

import cn.hutool.crypto.SecureUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author larry.xiang
 */
public class MerkleTrees {
    
    

    // 默克根
    String merkleRoot;

    // 交易集合
    List<String> txLst;

    /**
     * 初始化
     *
     * @param txList 交易集合
     */
    public MerkleTrees(List<String> txList) {
    
    
        this.txLst = txList;
        merkleRoot = "";
    }


    /**
     * 获取Node Hash List
     * @return
     */
    private List<String> getNodeHashList(List<String> tempTxList) {
    
    

        List<String> newTxList = new ArrayList<String>();
        int index = 0;
        while (index < tempTxList.size()) {
    
    
            // left
            String left = tempTxList.get(index);
            index++;
            // right
            String right = "";
            if (index != tempTxList.size()) {
    
    
                right = tempTxList.get(index);
            }
            // 两两加密
            String sha2HexValue = SecureUtil.sha256(left + right);
            // 双重hash
            sha2HexValue = SecureUtil.sha256(sha2HexValue);
            newTxList.add(sha2HexValue);
            index++;
        }
        return newTxList;
    }


    /**
     * 构造默克树,设置默克根
     */
    public void merkle_tree() {
    
    
        List<String> tempTxList = new ArrayList<String>();
        for (int i = 0; i < this.txLst.size(); i++) {
    
    
            tempTxList.add(this.txLst.get(i));
        }
        List<String> newTxList = getNodeHashList(tempTxList);
        //一直循环直到只剩下一个hash值
        while (newTxList.size() != 1) {
    
    
            newTxList = getNodeHashList(newTxList);
        }

        this.merkleRoot = newTxList.get(0);
    }
    

    /**
     * 获取默克根
     *
     * @return
     */
    public String getMerkleRoot() {
    
    
        return this.merkleRoot;
    }

2. Prueba

El código es el siguiente (ejemplo):

public static void main(String[] args) {
    
    

        List<String> tempTxList = new ArrayList<String>();
        tempTxList.add("80c6f121c3e9fe0a59177e49874d8c703cbadee0700a782e4002e87d862373c6");
        tempTxList.add("b86f5ef1da8ddbdb29ec269b535810ee61289eeac7bf2b2523b494551f03897c");

        //Collections.reverse(tempTxList);
        MerkleTrees merkleTrees = new MerkleTrees(tempTxList);
        merkleTrees.merkle_tree();
        System.out.println("root : " + merkleTrees.getMerkleRoot());

    }
}

Inserte la descripción de la imagen aquí


para resumir

Dado que los resultados del algoritmo hash son más largos, usamos la versión simplificada como ejemplo. Suponiendo que un bloque contiene actualmente dos transacciones, después de un doble hash:

Al ejecutar [empalme de dos-dos-grupos], simplemente una 111 y 222 juntos: 111222, y el empalme se completará. (El empalme real requiere decodificar el resultado hash en lenguaje de computadora, desplazamiento, empalme, codificación y desplazamiento para obtener el resultado final).

Antes del empalme, se supone que todas las transacciones tienen n. Después del empalme, el número restante es n / 2.

Varias veces [algoritmo de doble hash + conjuntos de empalme de dos por dos] es realizar las operaciones anteriores varias veces. Al principio, el número total de transacciones es n, se ejecuta una vez, y hay n / 2, y luego se ejecuta de nuevo, y n / 4, la ejecución final se detiene cuando solo hay un resultado, y luego se realizan dos operaciones hash en el resultado, y el resultado es el valor raíz merkle.

Supongo que te gusta

Origin blog.csdn.net/ws327443752/article/details/109208567
Recomendado
Clasificación