单机区块链理解

发布时间 2023-11-21 09:21:28作者: 人不疯狂枉一生

  区块链是一种分布式的、不可篡改的记录数据的技术。它是由一系列数据块(Blocks)组成的链式结构,每个数据块包含了一定数量的交易信息和与之相关的元数据。每个数据块都通过密码学哈希函数与前一个数据块连接起来,形成了一个不断增长的链式结构。

    下面用代码来理解一下区块链,首先创建一个块信息对象。块信息主要包含数据,当前hash值,前置节点hash值,当前时间戳,生成hash值的函数和挖矿函数。每个块的hash值是通过之前的hash值和数据data通过hash计算出来的。如果前一个区块的数据一旦被篡改了,那么前一个区块的hash值也会同样发生变化,这样也就导致了所有后续的区块中的hash值有误。所以计算和比对hash值会让我们检查到当前的区块链是否是有效的,也就避免了数据被恶意篡改的可能性,因为篡改数据就会改变hash值并破坏整个区块链。

public class BlockInfo {
    public  String hashCode;
    public  String preHashCode;
    private  String data;
    private  long timeStamp;
    private  int nonce=0;

    public BlockInfo(String data, String preHashCode)
    {
        this.data=data;
        this.preHashCode=preHashCode;
        this.timeStamp=new Date().getTime();
        this.hashCode=countHash();
    }

    public String countHash(){
        String tmpHash=BlockChainUtil.hash256Code(this.preHashCode+Long.toString(this.timeStamp)+Integer.toString(nonce)+this.data);
        return  tmpHash;
    }

    public void mineBlock(int difficulty) {
        String target = new String(new char[difficulty]).replace('\0', '0');
        while(!hashCode.substring( 0, difficulty).equals(target)) {
            nonce ++;
            hashCode = countHash();
        }
    }
}

  有了块信息对象,就需要选择一个生成hash值的算法,生成hash的算法有很多,比如BASE,MD,RSA,SHA等等,这里采用的是SHA-256算法。

public class BlockChainUtil {
public static String hash256Code(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : hashBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

    最后就是添加块,并进行区块链检查,这就形成了一个单机版小型的区块链模型。

public class BlockChain {
    public  static List<BlockInfo> blockChainList=new ArrayList<>();
    public  static int difficultFactor=1;
    public  static  void main(String[] args)
    {
        blockChainList.add(new BlockInfo("第一个块", "0"));
        System.out.println("尝试生成第一个块");
        blockChainList.get(0).mineBlock(difficultFactor);

        blockChainList.add(new BlockInfo("第二块",blockChainList.get(blockChainList.size()-1).hashCode));
        System.out.println("尝试生成第二个块 ");
        blockChainList.get(1).mineBlock(difficultFactor);

        System.out.println("检查区块链是否有效 " + checkChainValid());

    }

    public static   boolean checkChainValid()
    {
        BlockInfo currentBlock;
        BlockInfo preBlock;
        String hashTarget=new String(new char[difficultFactor]).replace('\0','0');
        for(int i=1;i<blockChainList.size();i++)
        {
            currentBlock = blockChainList.get(i);
            preBlock = blockChainList.get(i-1);
            if(!currentBlock.hashCode.equals(currentBlock.countHash()) ){
                System.out.println("当前块hash值不对");
                return false;
            }
            if(!preBlock.hashCode.equals(currentBlock.preHashCode) ) {
                System.out.println("前置块hash值不对");
                return false;
            }
            if(!currentBlock.hashCode.substring( 0, difficultFactor).equals(hashTarget)) {
                System.out.println("这个块没有被挖掘出来");
                return false;
            }
        }

        return  true;
    }
}

  

    最终生成的区块链内容如下图: