區塊鏈是一種分佈式的、不可篡改的記錄數據的技術。它是由一系列數據塊(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; } }
最終生成的區塊鏈內容如下圖: