单机区块链理解
区块链是一种分布式的、不可篡改的记录数据的技术。它是由一系列数据块(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; } }
最终生成的区块链内容如下图: