正如我們所知,區塊鏈的設計是不可變的。在這里,我們將設計一個簡單的區塊鏈,它將幫助您理解散列如何使區塊鏈不可變,只需幾行JAVA代碼。
注:這只是一個演示區塊鏈,真正的區塊鏈涉及很多其他東西,如共識機制、數字簽名、Merkle樹等。。此代碼示例將有助于實現理想的目的。
區塊鏈中的第一個區塊是Genesis區塊。genesis區塊幾乎總是硬編碼到利用其區塊鏈的應用程序的軟件中。
對于隨后生成的每個新塊,我們將使用前一個塊的哈希以及它自己的事務作為輸入來確定它的塊哈希。
Object[] contents ={Arrays.hashCode(transactions),previousHash};
blockHash = Arrays.hashCode(contents);
散列函數是一種數學函數,它接受任意長度數值數據的輸入,并將其轉換為固定長度的數值數據。
不同的散列函數使用不同的算法生成散列值。
此外,哈希函數將始終為任何特定輸入提供相同的輸出。但是,如果您在輸入中做了一點小的更改,那么產生的哈希值將與前一個完全不同。
記住散列不是加密。
在加密中,一旦加密了數據,就可以通過解密將其取回,而在散列中,則無法通過任何方法將輸入取回。
您可能會想知道為什么需要像SHA256(安全哈希算法)這樣的哈希算法?
最重要的原因是這些算法幫助我們避免沖突(不同輸入的哈希值相似)。
現在,讓我們通過代碼來了解區塊鏈如何使塊的散列無法更改,從而使塊一旦寫入區塊鏈,就無法更改。
我們將創建一個塊類。每個塊將有:
- 交易清單(int)
- 上一個塊哈希(String[])
- 散列(int)
對變量塊類應用 getter setter 方法后,如下所示:
import java.util.Arrays;
public class Block
{
private int previousHash;
private String[] transactions;
private int blockHash;
public Block(int previousHash, String[] transactions) {
this.previousHash = previousHash;
this.transactions = transactions;
Object[] contents = {Arrays.hashCode(transactions),previousHash};
this.blockHash = Arrays.hashCode(contents);
}
public int getPreviousHash() {
return previousHash;
}
public String[] getTransactions() {
return transactions;
}
public int getBlockHash() {
return blockHash;
}
public void setPreviousHash(int previousHash) {
this.previousHash = previousHash;
}
public void setTransactions(String[] transactions) {
this.transactions = transactions;
}
public void setBlockHash(int blockHash) {
this.blockHash = blockHash;
}
}
現在讓我們創建一個區塊鏈。
我們將從創建Genesis塊開始。由于Genesis塊是鏈中的第一個塊,我們將硬編碼事務和以前的哈希值。
真正的區塊鏈中的交易肯定是某種交易類別,將使用不同的數據結構。為了簡單起見,我將它們寫成字符串。
主類如下所示:
import java.util.ArrayList;
public class Blockchain {
ArrayList<Block> blockchain = new ArrayList<>();
public static void main(String[] args) {
String[] genesisTransactions = {"Suraj sent Ruja 1542 Bitcoins","Ruja sent 10 Bitcoins to John"};
Block genesisBlock = new Block(0,genesisTransactions);
System.out.println("Genesis Block Hash:"+genesisBlock.getBlockHash());
String[] block2Transactions = {"John sent 10 bitcoins to Suraj","Suraj sent 10 bitcoins to Alex"};
Block block2= new Block(genesisBlock.getBlockHash(), block2Transactions);
System.out.println("Block2 Hash:"+block2.getBlockHash());
String[] block3Transactions = {"Alex sent 999 bitcoins to non"};
Block block3 = new Block(block2.getBlockHash(), block3Transactions);
System.out.println("Block3 Hash:"+block3.getBlockHash());
}
}
輸出:
Genesis Block Hash:-1106827926
Block2 Hash:957910147
Block3 Hash:-716750945
您可以輸出genesis block的HashCode并更改它,您將看到輸出與以前的輸出有很大不同,即使您更改事務字符串中單個字母的大小寫。
將genesis block事務中“Suraj”的“S”更改為“S”后的輸出:
Genesis Block Hash:1528835466
Block2 Hash:-701393757
Block3 Hash:1918912447
這就是塊鏈的形成方式,每個新塊散列都指向它之前的塊散列。這種散列系統保證歷史記錄中的任何事務都不會被篡改,因為如果事務的任何單個部分發生更改,那么它所屬的塊的散列以及隨后任何塊的散列也會發生更改。
因此很容易捕獲任何篡改,因為您只需比較散列即可。