前言
区块链(Blockchain)是比特币等流行的加密货币背后的技术。区块链的主要概念是去中心化,提供分布式账本。本文会为你展示如何在 iOS/macOS 中使用 Swift 语言创建最基本的区块链。
注意:本文不涉及节点(nodes/peers)、验证和奖励等。
实现区块类
实现区块类,生成对象代表一个区块,创建如下:
//MARK: 区块
/// 简单模拟区块链,假设是单链的
class Block{
var index : Int = 0 //区块所在节点
var dateCreated : String? //区块产生时间
var previousHash : String? //前一个区块的hash
var hash:String? //hash值
var nonce:Int = 0 //生成符合条件的hash值所需次数 -> 模拟难度值
//模拟操作,保证key有值
var key: String {
get {
return String(self.index)+self.dateCreated! + self.previousHash!+String(self.nonce)
}
}
init() {
self.dateCreated = Date().toString()
self.nonce = 0
}
}
实现区块链类
生成对象代表一个区块链,这个区块链需要一个区块来初始化自己,这个区块,成为创世块. 代码如下:
//MARK:- 区块链,假设是单链的(实际区块链要复杂的多)
class BlockChain {
private (set)var blocks = [Block]()
/// 初始化区块链
///
/// - Parameter genesisiBlock: 区块
init(genesisiBlock:Block) {
//添加区块到区块链中
addBlock(block: genesisiBlock)
}
/// 添加区块
///
/// - Parameter block: 区块
func addBlock(block:Block) {
if blocks.isEmpty {
//添加创世块
//第一个区块没有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)个区块")
print("创建日期:\(String(describing: block.dateCreated!))")
print("Nonce:\(block.nonce)")
print("前一个区块的hash值:\(String(describing: block.previousHash!))")
print("hash值:\(String(describing: block.hash!))\n\n\n\n")
}
//计算hash值
private func generateHash(block:Block) ->String{
//计算hash
var hash = block.key.sha1Hash()
//筛选算出来的hash值
//假设限制条件是hash值末尾必须是"00"
while !hash.hasSuffix("00") {
block.nonce += 1
hash = block.key.sha1Hash();
}
return hash;
}
}
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头(模拟增加难度,实际区块链,这个值可能一直不同的区块计算,也是不一样的)的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币,玩客币等等,看具体交易平台)。
核心算法
// MARK: - String 类扩展
extension String{
func sha1Hash() -> String {
let task = Process()// OC中的NSTask
//Linux命令
// 执行路径 -> 设置 shell 脚本参数
// shasum SHA校验
task.launchPath = "/usr/bin/shasum"
task.arguments = [] //包含的shell语句
let inputPipe = Pipe()
//字符串转化为data写入文件
inputPipe.fileHandleForWriting.write(self.data(using: .utf8)!)//写入文件
inputPipe.fileHandleForWriting.closeFile()//保存并关闭
let outputPipe = Pipe()
task.standardOutput = outputPipe //标准输出
task.standardInput = inputPipe //标准输入
task.launch()
let data = outputPipe.fileHandleForReading.readDataToEndOfFile()
let hash = String(data: data, encoding: .utf8)!
return hash.replacingOccurrences(of: " -\n", with: "")
}
}
扩展
// MARK: - Date 时间
extension Date{
/// 获取当前时间,转化为字符串
///
/// - Returns: 时间戳
func toString() -> String {
let formatter = DateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return formatter.string(from: self);
}
}
全部源码可以复制全部源码直接粘贴到Mac Playground中,直接运行,或者创建Command Line Tool 把代码粘贴到main.swift文件里面
网友评论