在 iOS 中实现区块链
一夜雨十年灯潞
发表于 2022-12-28 14:03:19
94
0
0
注意:本文不涉及节点(nodes/peers)、验证和奖励等。
我会用 macOS Playground 来演示,快且方便,还有一些实用的函数可以用来生成 SHA 哈希值。! S! R1 ^0 l# L1 F1 f
实现区块类
第一步是实现区块(Block)类,用来表示区块链中的一个区块。实现如下:: C$ b, r' h$ P1 V( n8 I% n4 q& m7 Z
class Block {
var index: Int = 0
var dateCreated: String
var previousHash: String!2 n2 k( ~( [3 `1 X
var hash: String!
var nonce: Int
var data: String
y" f( X- U2 F
var key: String {
get {
return String(self.index) + self.dateCreated + self.previousHash + self.data + String(self.nonce)+ D; ?* A8 S% S' S
}) `2 D/ ?' W6 I: F F' ^2 x
}
init(data: String) {& t- q9 Y8 g( _& _
self.dateCreated = Date().toString()
self.nonce = 0' t Y+ D2 k% O/ c& r* Y K
self.data = data
} m2 }7 Z6 b% ~' t5 P
}0 V7 z) N' b4 _0 z
区块类详解:7 f, q# g: E: u' u" k1 U+ H
index——区块位于区块链中的位置。index 为 0 则表示该区块是区块链中的第一个区块。index 为 1 则表示区块链中的第二个区块……以此类推!dateCreated——区块创建的日期previousHash——前一个区块的哈希值hash——当前区块的哈希值nonce——递增的数字,对生成哈希值很关键data——任意有价值的信息。可以是金钱、医疗信息和房地产信息等等key——计算属性,提供给产生哈希值的函数
/ G& T) C+ B' g% u$ r, p
实现区块链类
区块链(Blockchain)类需要用一个区块的实例来初始化自己。这个区块也被称为创世区块(genesis block),正因为它是区块链的第一个区块。区块链类实现如下:
class Blockchain {7 N! }. H' s5 d! p# H+ g/ `8 z
private (set) var blocks = [Block]()
init(_ genesisBlock: Block) {
addBlock(genesisBlock)$ c5 i& W9 A9 D5 p' F
}- P+ i: d" {5 s; C
7 d1 @: U' @/ n2 w/ A( P. E
func addBlock(_ block: Block) {
if blocks.isEmpty {
// 添加创世区块! B4 [! J2 E+ @
// 第一个区块没有 previous hash! G6 a3 S4 x; g" g' a# E3 R
block.previousHash = "0"8 D. N/ g; }+ D
block.hash = generateHash(for: block); b" ~! {3 T' n. |1 O) L9 r
} else {
let previousBlock = getPreviousBlock()- b' a9 N8 D2 Z" g$ _" [
block.previousHash = previousBlock.hash" N" r) x% v' `. {) i
block.index = blocks.count
block.hash = generateHash(for: block)
}' I, i$ w9 z! h- O1 z8 l
8 s6 K/ O9 V+ M) t5 L" S( D4 Z
blocks.append(block)9 ^: p( z2 B9 V3 j! l7 u
displayBlock(block)
}
; S; e) ?" c9 x4 H& q
private func getPreviousBlock() -> Block {' U0 a. b! ^, P1 q K4 t6 d3 ?3 ]
return blocks[blocks.count - 1]
}
2 a! G- d& k( \1 }" J" h
private func displayBlock(_ block: Block) {, P/ P F" U h
print("------ 第 \(block.index) 个区块 --------")
print("创建日期:\(block.dateCreated)")+ e) E" C: M3 X) V+ O
print("数据:\(block.data)")# F9 v$ ^- B W5 k H$ ?: t3 Q
print("Nonce:\(block.nonce)")
print("前一个区块的哈希值:\(block.previousHash!)")
print("哈希值:\(block.hash!)")5 M' ]5 y, Y" |; `9 P6 I. z& K' g
}: K: q1 N! h/ s+ v9 K* {
private func generateHash(for block: Block) -> String {
var hash = block.key.sha1Hash()
while !hash.hasPrefix("00") {7 T7 i U' t; z8 U# k- e: }
block.nonce += 15 ~; j- ^# x+ S) m7 C. O0 J
hash = block.key.sha1Hash()
}
return hash
}; N3 L1 {' H/ }/ y. F# Q
}9 H6 t/ s/ ^& A
addBlock 函数用于给区块链增加区块。下一个区块则基于前一个区块的哈希值以及其它属性来计算 key。
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币)。
下面实际看看我们的区块链。
视频链接
从 Gist 上下载完整的源码。复制粘贴到 macOS Playground 里就可以运行。
原文 https://juejin.im/post/5a43ae5f51882538650977d1
成为第一个吐槽的人