iOS 書寫簡單的區(qū)塊鏈程序

前言

區(qū)塊鏈(Blockchain)是比特幣等流行的加密貨幣背后的技術(shù)。區(qū)塊鏈的主要概念是去中心化,提供分布式賬本。本文會(huì)為你展示如何在 iOS/macOS 中使用 Swift 語言創(chuàng)建最基本的區(qū)塊鏈。
注意:本文不涉及節(jié)點(diǎn)(nodes/peers)、驗(yàn)證和獎(jiǎng)勵(lì)等。


實(shí)現(xiàn)區(qū)塊類

實(shí)現(xiàn)區(qū)塊類,生成對(duì)象代表一個(gè)區(qū)塊,創(chuàng)建如下:

//MARK: 區(qū)塊
/// 簡單模擬區(qū)塊鏈,假設(shè)是單鏈的
class Block{
    var index : Int = 0          //區(qū)塊所在節(jié)點(diǎn)
    var dateCreated  : String?   //區(qū)塊產(chǎn)生時(shí)間
    var previousHash : String?  //前一個(gè)區(qū)塊的hash
    var hash:String?   //hash值
    var nonce:Int = 0 //生成符合條件的hash值所需次數(shù) -> 模擬難度值
    
     //模擬操作,保證key有值
    var key: String {
        get {
            return String(self.index)+self.dateCreated! + self.previousHash!+String(self.nonce)
        }
    }
    
    init() {
        self.dateCreated = Date().toString()
        self.nonce = 0
    }
}

實(shí)現(xiàn)區(qū)塊鏈類

生成對(duì)象代表一個(gè)區(qū)塊鏈,這個(gè)區(qū)塊鏈需要一個(gè)區(qū)塊來初始化自己,這個(gè)區(qū)塊,成為創(chuàng)世塊. 代碼如下:

//MARK:- 區(qū)塊鏈,假設(shè)是單鏈的(實(shí)際區(qū)塊鏈要復(fù)雜的多)
class BlockChain {
    
    private (set)var blocks = [Block]()
    
    /// 初始化區(qū)塊鏈
    ///
    /// - Parameter genesisiBlock: 區(qū)塊
    init(genesisiBlock:Block) {
        //添加區(qū)塊到區(qū)塊鏈中
        addBlock(block: genesisiBlock)
    }
    
    /// 添加區(qū)塊
    ///
    /// - Parameter block: 區(qū)塊
    func addBlock(block:Block) {
        if blocks.isEmpty {
            //添加創(chuàng)世塊
            //第一個(gè)區(qū)塊沒有hash
            block.previousHash = "0"
            block.hash = generateHash(block: block)
        }else{
            let previousBlock = getPreviousBlock()
            block.previousHash = previousBlock.hash
            block.index = blocks.count
            block.hash = generateHash(block: block)
        }
        blocks.append(block)
        displayBlock(block: block)
    }
    
    func getPreviousBlock() -> Block {
        return blocks[blocks.count-1]
    }
    
    func displayBlock(block:Block) {
        print("---第\(block.index)個(gè)區(qū)塊")
        print("創(chuàng)建日期:\(String(describing: block.dateCreated!))")
        print("Nonce:\(block.nonce)")
        print("前一個(gè)區(qū)塊的hash值:\(String(describing: block.previousHash!))")
        print("hash值:\(String(describing: block.hash!))\n\n\n\n")
    }
    
    //計(jì)算hash值
    private func generateHash(block:Block) ->String{
        //計(jì)算hash
        var hash = block.key.sha1Hash()
        //篩選算出來的hash值
        //假設(shè)限制條件是hash值末尾必須是"00"
        while !hash.hasSuffix("00") {
            block.nonce += 1
            hash = block.key.sha1Hash();
        }
        return hash;
        
    }
}

generateHash 函數(shù)負(fù)責(zé)生成唯一的哈希值并賦值給區(qū)塊。但并不使用完全隨機(jī)的哈希,而是需要以“00”開頭(模擬增加難度,實(shí)際區(qū)塊鏈,這個(gè)值可能一直不同的區(qū)塊計(jì)算,也是不一樣的)的特定哈希。這個(gè)概念叫做“工作量證明系統(tǒng)”。在實(shí)際中工作量證明系統(tǒng)的解法會(huì)更復(fù)雜,解決的人也會(huì)獲得獎(jiǎng)勵(lì)(可能是額外的比特幣,玩客幣等等,看具體交易平臺(tái))。

核心算法

// MARK: - String 類擴(kuò)展
extension String{
    func sha1Hash() -> String {
        let task = Process()//  OC中的NSTask
        //Linux命令
        // 執(zhí)行路徑  -> 設(shè)置 shell 腳本參數(shù)
        // shasum SHA校驗(yàn)
        task.launchPath = "/usr/bin/shasum"
        task.arguments = [] //包含的shell語句
        let inputPipe = Pipe()
        //字符串轉(zhuǎn)化為data寫入文件
        inputPipe.fileHandleForWriting.write(self.data(using: .utf8)!)//寫入文件
        inputPipe.fileHandleForWriting.closeFile()//保存并關(guān)閉
        let outputPipe = Pipe()
        task.standardOutput = outputPipe //標(biāo)準(zhǔn)輸出
        task.standardInput = inputPipe   //標(biāo)準(zhǔn)輸入
        task.launch()
        
        let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
        let hash = String(data: data, encoding: .utf8)!
        return hash.replacingOccurrences(of: "  -\n", with: "")
        
    }
}

擴(kuò)展

// MARK: - Date 時(shí)間
extension Date{
    
    /// 獲取當(dāng)前時(shí)間,轉(zhuǎn)化為字符串
    ///
    /// - Returns: 時(shí)間戳
    func toString() -> String {
        let formatter = DateFormatter();
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter.string(from: self);
    }
}


全部源碼可以復(fù)制全部源碼直接粘貼到Mac Playground中,直接運(yùn)行,或者創(chuàng)建Command Line Tool 把代碼粘貼到main.swift文件里面

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容