在 iOS 中實現區塊鏈

張嘉夫_Joseph發表於2017-12-27

本文參考


區塊鏈(Blockchain)是比特幣等流行的加密貨幣背後的技術。區塊鏈的主要概念是去中心化,提供分散式賬本。本文會為你展示如何在 iOS/macOS 中使用 Swift 語言建立最基本的區塊鏈。

注意:本文不涉及節點(nodes/peers)、驗證和獎勵等。

我會用 macOS Playground 來演示,快且方便,還有一些實用的函式可以用來生成 SHA 雜湊值。

實現區塊類

第一步是實現區塊(Block)類,用來表示區塊鏈中的一個區塊。實現如下:

class Block {
    var index: Int = 0
    var dateCreated: String
    var previousHash: String!
    var hash: String!
    var nonce: Int
    var data: String
    
    var key: String {
        get {
            return String(self.index) + self.dateCreated + self.previousHash + self.data + String(self.nonce)
        }
    }
    
    init(data: String) {
        self.dateCreated = Date().toString()
        self.nonce = 0
        self.data = data
    }
}
複製程式碼

區塊類詳解:

  • index——區塊位於區塊鏈中的位置。index 為 0 則表示該區塊是區塊鏈中的第一個區塊。index 為 1 則表示區塊鏈中的第二個區塊……以此類推!
  • dateCreated——區塊建立的日期
  • previousHash——前一個區塊的雜湊值
  • hash——當前區塊的雜湊值
  • nonce——遞增的數字,對生成雜湊值很關鍵
  • data——任意有價值的資訊。可以是金錢、醫療資訊和房地產資訊等等
  • key——計算屬性,提供給產生雜湊值的函式

實現區塊鏈類

區塊鏈(Blockchain)類需要用一個區塊的例項來初始化自己。這個區塊也被稱為創世區塊(genesis block),正因為它是區塊鏈的第一個區塊。區塊鏈類實現如下:

class Blockchain {
    private (set) var blocks = [Block]()
    
    init(_ genesisBlock: Block) {
       addBlock(genesisBlock)
    }
    
    func addBlock(_ block: Block) {
        if blocks.isEmpty {
            // 新增創世區塊
            // 第一個區塊沒有 previous hash
            block.previousHash = "0"
            block.hash = generateHash(for: block)
        } else {
            let previousBlock = getPreviousBlock()
            block.previousHash = previousBlock.hash
            block.index = blocks.count
            block.hash = generateHash(for: block)
        }
        
        blocks.append(block)
        displayBlock(block)
    }
    
    private func getPreviousBlock() -> Block {
        return blocks[blocks.count - 1]
    }
    
    private func displayBlock(_ block: Block) {
        print("------ 第 \(block.index) 個區塊 --------")
        print("建立日期:\(block.dateCreated)")
		  print("資料:\(block.data)")
        print("Nonce:\(block.nonce)")
        print("前一個區塊的雜湊值:\(block.previousHash!)")
        print("雜湊值:\(block.hash!)")
    }
    
    private func generateHash(for block: Block) -> String {
        var hash = block.key.sha1Hash()
        while !hash.hasPrefix("00") {
            block.nonce += 1
            hash = block.key.sha1Hash()
        }
        return hash
    }
}
複製程式碼

addBlock 函式用於給區塊鏈增加區塊。下一個區塊則基於前一個區塊的雜湊值以及其它屬性來計算 key。

generateHash 函式負責生成唯一的雜湊值並賦值給區塊。但並不使用完全隨機的雜湊,而是需要以“00”開頭的特定雜湊。這個概念叫做“工作量證明系統”。在實際中工作量證明系統的解法會更復雜,解決的人也會獲得獎勵(可能是額外的比特幣)。

下面實際看看我們的區塊鏈。

視訊連結

Gist 上下載完整的原始碼。複製貼上到 macOS Playground 裡就可以執行。

相關文章