在 iOS 中实现区块链
一夜雨十年灯潞
发表于 2022-12-28 14:03:19
184
0
0
注意:本文不涉及节点(nodes/peers)、验证和奖励等。
我会用 macOS Playground 来演示,快且方便,还有一些实用的函数可以用来生成 SHA 哈希值。
实现区块类# V1 \2 m3 s: v+ r6 T0 w6 y
第一步是实现区块(Block)类,用来表示区块链中的一个区块。实现如下:4 E* u1 M9 m8 N7 ?" I& Z1 Q8 X7 ?; l# B
class Block {
var index: Int = 0% G* ~9 d2 x% U/ s- O4 M z6 ]
var dateCreated: String6 D! ^/ C3 C& x) z. N* Y1 R
var previousHash: String!! J/ Z( n4 P* z
var hash: String!5 {% k& K' ]( Z# p9 O. t+ h7 k
var nonce: Int+ E [/ S9 A) n9 v" o& ]
var data: String- J0 I: a' v( S& E" L* @
var key: String {6 P# b9 Y4 w, u9 t5 \) c
get {
return String(self.index) + self.dateCreated + self.previousHash + self.data + String(self.nonce)
}
}" S, X$ T7 d: [, x5 a
init(data: String) {
self.dateCreated = Date().toString()
self.nonce = 0, k* s* i2 P5 b( t
self.data = data
}/ M+ }5 E9 w: |: P' j5 A; A
}
区块类详解:" L1 g* e+ z$ J b
index——区块位于区块链中的位置。index 为 0 则表示该区块是区块链中的第一个区块。index 为 1 则表示区块链中的第二个区块……以此类推!dateCreated——区块创建的日期previousHash——前一个区块的哈希值hash——当前区块的哈希值nonce——递增的数字,对生成哈希值很关键data——任意有价值的信息。可以是金钱、医疗信息和房地产信息等等key——计算属性,提供给产生哈希值的函数7 J3 z/ ^( v. I* F' [
2 v$ [: ?6 f' ~% e4 _
实现区块链类1 D/ p) N& P4 E/ ]
区块链(Blockchain)类需要用一个区块的实例来初始化自己。这个区块也被称为创世区块(genesis block),正因为它是区块链的第一个区块。区块链类实现如下:5 i" e p- T3 n; {
class Blockchain {
private (set) var blocks = [Block]()0 V! J' O/ M: [2 S5 c+ Z
init(_ genesisBlock: Block) {& V' ]) H" S" a
addBlock(genesisBlock)3 E% D, q5 f1 C7 f
}
" F1 {$ u) e7 h! V- C: X- p3 N/ y
func addBlock(_ block: Block) {2 f% J5 D7 @5 `7 r8 U( P
if blocks.isEmpty {
// 添加创世区块
// 第一个区块没有 previous hash
block.previousHash = "0"" H7 U+ h n Q( G" y
block.hash = generateHash(for: block)
} else {& S$ s- `; O( ^& i. z
let previousBlock = getPreviousBlock()
block.previousHash = previousBlock.hash/ t5 V' W7 l* }) y1 q$ t+ e
block.index = blocks.count
block.hash = generateHash(for: block)
}9 h6 C7 |+ c4 P- s; C$ J: z
4 ^2 x) ~) }! R. O7 M: v$ |' K" y
blocks.append(block)9 r/ X0 w, p: J) A# u9 \) _0 ~
displayBlock(block)# p. I X. p7 e( C; H# c
}" j6 x) f% \/ q. K/ G- v- D5 S% s9 e7 M1 ~
1 F$ @1 \ {1 n0 _8 J
private func getPreviousBlock() -> Block {7 t$ ^, B$ c* v. A
return blocks[blocks.count - 1]; S6 [6 I: Y7 S1 G8 _
}1 g) x# K! b+ c& @' H5 n
1 p" a- b, A8 @. g
private func displayBlock(_ block: Block) {& p7 y% P4 v+ F A& D
print("------ 第 \(block.index) 个区块 --------")
print("创建日期:\(block.dateCreated)")7 F3 n4 p; I$ f6 k
print("数据:\(block.data)")
print("Nonce:\(block.nonce)")
print("前一个区块的哈希值:\(block.previousHash!)")
print("哈希值:\(block.hash!)")
}
" d: ]2 ^3 M, p1 |* _
private func generateHash(for block: Block) -> String {
var hash = block.key.sha1Hash()9 U1 @9 W3 y5 a$ x7 T8 p, K
while !hash.hasPrefix("00") {
block.nonce += 1
hash = block.key.sha1Hash()& f" r/ `+ u0 k9 Y2 X
}
return hash* K) u. |$ o) {; L/ K: q* `" t
}
}
addBlock 函数用于给区块链增加区块。下一个区块则基于前一个区块的哈希值以及其它属性来计算 key。
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币)。
下面实际看看我们的区块链。
视频链接
从 Gist 上下载完整的源码。复制粘贴到 macOS Playground 里就可以运行。
原文 https://juejin.im/post/5a43ae5f51882538650977d1
成为第一个吐槽的人