使用Java實現簡單的區塊鏈程序的方法

在本文中,我們將學習區塊鏈技術的基本概念。我們還將用Java實現一個基本的應用程序,重點介紹這些概念。

此外,我們還將討論該技術的一些先進概念和實際應用。

什麼是區塊鏈?

那麼,讓我們先來瞭解一下區塊鏈到底是什麼…

好吧,它的起源可以追溯到Satoshi Nakamoto在2008年發表的關於比特幣的白皮書。

區塊鏈是一個分散的信息分類帳。它由通過使用密碼學連接的數據塊組成。它屬於通過公共網絡連接的節點網絡。當我們稍後嘗試構建一個基本教程時,我們將更好地理解這一點。

我們必須瞭解一些重要的屬性,讓我們來瞭解一下:

  • 防篡改 :首先,數據作為塊的一部分是防篡改的。每個塊都由一個加密摘要(通常稱為散列)引用,使得塊能夠防篡改。
  • 去中心化 :整個區塊鏈在網絡上完全去中心化。這意味著沒有主節點,網絡中的每個節點都有相同的副本。
  • 透明 :每個參與網絡的節點通過與其他節點協商一致,對其鏈進行驗證並添加新的塊。因此,每個節點都具有數據的完全可見性。

區塊鏈是如何工作的?

現在,讓我們來瞭解區塊鏈是如何工作的。

區塊鏈的基本單位是區塊。單個塊可以封裝多個事務或其他有價值的數據:

開采區塊

我們用散列值表示一個塊。生成塊的哈希值稱為“挖掘”塊。開采一個區塊通常計算成本很高,因為它是“工作證明”。

塊的散列通常由以下數據組成:

  • 首先,塊的散列由它封裝的事務組成
  • 散列還包括塊創建的時間戳
  • 它還包括一個nonce,一個用於密碼學的任意數字
  • 最後,當前塊的散列還包括前一塊的散列
  • 網絡中的多個節點可以同時競爭挖掘塊。除瞭生成散列,節點還必須驗證添加到塊中的事務是否合法。第一個挖方塊的人贏得比賽!

向區塊鏈中添加區塊

雖然挖掘塊的計算成本很高,但驗證塊是否合法相對容易得多。網絡中的所有節點都參與驗證新開采的區塊。

因此, 在節點一致的情況下,一個新挖掘的區塊被添加到區塊鏈中。

現在,有幾種共識協議可供我們用於驗證。網絡中的節點使用相同的協議來檢測鏈的惡意分支。因此,即使引入惡意分支,也會很快被大多數節點拒絕。

Java中的基本區塊鏈
現在我們已經有足夠的上下文開始用Java構建一個基本的應用程序。

我們這裡的簡單示例將說明我們剛才看到的基本概念。生產級應用程序需要考慮很多問題,這些問題超出瞭本教程的范圍。不過,我們稍後將討論一些高級主題。

實現塊

首先,我們需要定義一個簡單的POJO來保存塊的數據:

public class Block {
    private String hash;
    private String previousHash;
    private String data;
    private long timeStamp;
    private int nonce;
 
    public Block(String data, String previousHash, long timeStamp) {
        this.data = data;
        this.previousHash = previousHash;
        this.timeStamp = timeStamp;
        this.hash = calculateBlockHash();
    }
    // standard getters and setters
}

讓我們瞭解一下我們在這裡打包的東西:

nonce

計算散列

現在,我們如何計算塊的散列呢?我們已經使用瞭 calculateBlockHash 方法,但還沒有看到實現。在我們實現這個方法之前,花點時間來理解什麼是散列是值得的。

散列是散列函數的輸出。 哈希函數將任意大小的輸入數據映射為固定大小的輸出數據。 哈希對輸入數據中的任何更改都非常敏感,無論更改多麼小。

此外,僅僅從散列中獲取輸入數據是不可能的。這些屬性使得哈希函數在密碼學中非常有用。

那麼,讓我們看看如何在Java中生成塊的哈希:

public String calculateBlockHash() {
    String dataToHash = previousHash 
      + Long.toString(timeStamp) 
      + Integer.toString(nonce) 
      + data;
    MessageDigest digest = null;
    byte[] bytes = null;
    try {
        digest = MessageDigest.getInstance("SHA-256");
        bytes = digest.digest(dataToHash.getBytes(UTF_8));
    } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
        logger.log(Level.SEVERE, ex.getMessage());
    }
    StringBuffer buffer = new StringBuffer();
    for (byte b : bytes) {
        buffer.append(String.format("%02x", b));
    }
    return buffer.toString();
}
public String calculateBlockHash() {
    String dataToHash = previousHash 
      + Long.toString(timeStamp) 
      + Integer.toString(nonce) 
      + data;
    MessageDigest digest = null;
    byte[] bytes = null;
    try {
        digest = MessageDigest.getInstance("SHA-256");
        bytes = digest.digest(dataToHash.getBytes(UTF_8));
    } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
        logger.log(Level.SEVERE, ex.getMessage());
    }
    StringBuffer buffer = new StringBuffer();
    for (byte b : bytes) {
        buffer.append(String.format("%02x", b));
    }
    return buffer.toString();
}

這裡發生瞭很多事情,讓我們詳細瞭解一下:

MessageDigest

我們在那塊地上挖礦瞭嗎?

到目前為止,一切聽起來都簡單而優雅,隻是我們還沒有開采這個區塊。那麼,究竟需要挖掘一個區塊,這已經吸引瞭開發人員一段時間的想象力!

嗯,挖掘一個區塊意味著為這個區塊解決一個計算復雜的任務。雖然計算一個塊的散列有點瑣碎,但找到以五個零開始的散列卻不是。更復雜的是找到一個以十個零開始的散列,我們就得到瞭一個大概的想法。

那麼,我們到底該怎麼做呢?老實說,這個解決方案沒有那麼花哨!我們是用蠻力來達到這個目標的。我們在這裡使用 nonce :

public String mineBlock(int prefix) {
    String prefixString = new String(new char[prefix]).replace('\0', '0');
    while (!hash.substring(0, prefix).equals(prefixString)) {
        nonce++;
        hash = calculateBlockHash();
    }
    return hash;
}

讓我們看看我們要做的是:

nonce

我們從默認值 nonce 開始,並將其遞增1。但是,在現實世界的應用程序中,有更復雜的策略來啟動和增加一個瞬間。另外,我們這裡沒有驗證我們的數據,這通常是一個重要的部分。

讓我們運行這個示例

現在我們已經定義瞭塊及其函數,我們可以用它來創建一個簡單的區塊鏈。我們將此存儲在 ArrayList 中:

List<Block> blockchain = new ArrayList<>();
int prefix = 4;
String prefixString = new String(new char[prefix]).replace('\0', '0');

此外,我們還定義瞭一個前綴4,這實際上意味著我們希望哈希以4個零開始。

讓我們看看如何在這裡添加塊:

@Test
public void givenBlockchain_whenNewBlockAdded_thenSuccess() {
    Block newBlock = new Block(
      "The is a New Block.", 
      blockchain.get(blockchain.size() - 1).getHash(),
      new Date().getTime());
    newBlock.mineBlock(prefix);
    assertTrue(newBlock.getHash().substring(0, prefix).equals(prefixString));
    blockchain.add(newBlock);
}

區塊鏈驗證

節點如何驗證區塊鏈的有效性?雖然這可能相當復雜,但讓我們考慮一個簡單的版本:

@Test
public void givenBlockchain_whenValidated_thenSuccess() {
    boolean flag = true;
    for (int i = 0; i < blockchain.size(); i++) {
        String previousHash = i==0 ? "0" : blockchain.get(i - 1).getHash();
        flag = blockchain.get(i).getHash().equals(blockchain.get(i).calculateBlockHash())
          && previousHash.equals(blockchain.get(i).getPreviousHash())
          && blockchain.get(i).getHash().substring(0, prefix).equals(prefixString);
            if (!flag) break;
    }
    assertTrue(flag);
}

因此,我們對每個街區進行三次具體檢查:

  • 當前塊存儲的哈希值實際上是它計算的值
  • 當前塊中存儲的前一塊的哈希就是前一塊的哈希
  • 當前區塊已被開采

一些先進的概念

雖然我們的基本示例介紹瞭區塊鏈的基本概念,但它肯定不完整。要將這項技術投入實際應用,還需要考慮其他幾個因素。

雖然不可能詳細說明所有這些問題,但我們還是來看看其中一些重要的問題:

交易驗證

計算塊的散列並找到所需的散列隻是挖掘的一部分。數據塊由數據組成,通常以多個事務的形式出現。在將其作為區塊的一部分並開采之前,必須對其進行驗證。

區塊鏈的典型實現 對一個區塊可以包含多少數據設置瞭限制。它還設置瞭如何驗證事務的規則。網絡中的多個節點參與驗證過程。

替代協商一致議定書

我們看到像“工作證明”這樣的共識算法被用來挖掘和驗證一個塊。然而,這並不是唯一可用的一致性算法。

還有其他幾種共識算法可供選擇,如利害關系證明、權威性證明和權重證明。所有這些都有其利弊。使用哪一種取決於我們打算設計的應用程序的類型。

采礦獎勵

區塊鏈網絡通常由自願節點組成。現在,為什麼會有人想為這個復雜的過程做出貢獻,並保持它的合法性和增長?

這是因為 節點因驗證事務和挖掘塊而獲得獎勵 。這些獎勵通常是與申請相關聯的硬幣形式。但是一個應用程序可以決定獎勵是任何有價值的東西。

節點類型

區塊鏈完全依賴其網絡來運作。理論上,網絡是完全分散的,每個節點都是平等的。然而,在實踐中,一個網絡由多種類型的節點組成。

完整節點有完整的事務列表,而輕型節點隻有部分列表。此外,並非所有節點都參與驗證和確認。

保密通信

區塊鏈技術的一個特點是它的開放性和匿名性。但它如何為內部進行的交易提供安全性呢?這是基於密碼學和公鑰基礎設施。

事務的發起方使用他們的私鑰來保護它,並將它附加到接收方的公鑰上。節點可以使用參與者的公鑰來驗證事務。

區塊鏈的實際應用

因此,區塊鏈似乎是一項令人興奮的技術,但它也必須證明是有用的。這項技術已經存在瞭一段時間,而且——不用說——它已被證明在許多領域具有破壞性。

它在許多其他領域的應用正在積極進行。讓我們瞭解一下最流行的應用程序:

  • 貨幣 :由於比特幣的成功,這是迄今為止最古老和最廣為人知的區塊鏈應用。它們為全球人民提供安全無摩擦的資金,而無需任何中央當局或政府幹預。
  • 身份 :數字身份正在迅速成為當今世界的常態。然而,這是深陷安全問題和篡改。區塊鏈以完全安全和防篡改的身份徹底改變這一領域是不可避免的。
  • 醫療保健 :醫療保健行業充滿瞭數據,主要由中央當局處理。這會降低處理此類數據的透明度、安全性和效率。區塊鏈技術可以提供一個沒有任何第三方提供急需信任的系統。
  • 政府 :這也許是一個很容易被區塊鏈技術破壞的領域。政府通常是一些公民服務的中心,這些服務往往充斥著低效和腐敗。區塊鏈可以幫助建立更好的政府與公民關系。

行業工具

雖然我們在這裡的基本實現有助於引出概念,但從頭開始在區塊鏈上開發產品是不實際的。謝天謝地,這個領域現在已經成熟瞭,我們確實有一些非常有用的工具可以開始。

讓我們來看看一些流行的工具,以便在這個空間中工作:

  • Solidity :Solidity是一種靜態類型的面向對象編程語言,用於編寫智能合約。它可以用於在以太坊等各種區塊鏈平臺上編寫智能合約。
  • RemixIDE :Remix是一個強大的開源工具,可以穩定地編寫智能合約。這樣用戶就可以直接從瀏覽器中編寫智能合約。
  • Truffle套件 :Truffle提供瞭一系列工具來幫助開發人員開始開發分佈式應用程序。這包括松露、甘納切和細雨。
  • Ethlint/Solium :Solium允許開發人員確保他們在Solidity上編寫的智能合約沒有樣式和安全問題。Solium也有助於解決這些問題。
  • Parity :Parity有助於建立以太智能合約的開發環境。它提供瞭一種與區塊鏈交互的快速和安全的方式。

小結

總之,在本文中,我們介紹瞭區塊鏈技術的基本概念。我們瞭解瞭網絡如何挖掘並在區塊鏈中添加新區塊。此外,我們還用Java實現瞭基本概念。我們還討論瞭與此技術相關的一些高級概念。

最後,我們總結瞭區塊鏈的一些實際應用以及可用的工具。

完整代碼地址: https://github.com/eugenp/tutorials/tree/master/java-blockchain

到此這篇關於使用Java實現簡單的區塊鏈程序的文章就介紹到這瞭,更多相關java區塊鏈程序內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀:

    None Found