在 iOS 中实现区块链
一夜雨十年灯潞
发表于 2022-12-28 14:03:19
97
0
0
注意:本文不涉及节点(nodes/peers)、验证和奖励等。% v; H* W. x E/ |" ]
我会用 macOS Playground 来演示,快且方便,还有一些实用的函数可以用来生成 SHA 哈希值。1 C$ t% |0 N6 h$ L l
实现区块类( s; @0 ~# g8 T% E% U! T
第一步是实现区块(Block)类,用来表示区块链中的一个区块。实现如下:. _8 \) X# q& `
class Block {
var index: Int = 0
var dateCreated: String
var previousHash: String!0 r; k% @; N7 o" }% b2 ~! t
var hash: String!
var nonce: Int
var data: String
* z( V. A& x/ p# |7 ?
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 t0 b, r1 q9 N5 y$ v
}, g# X. |# R7 }! U
}& n* v- c- M/ \" t
区块类详解:
index——区块位于区块链中的位置。index 为 0 则表示该区块是区块链中的第一个区块。index 为 1 则表示区块链中的第二个区块……以此类推!dateCreated——区块创建的日期previousHash——前一个区块的哈希值hash——当前区块的哈希值nonce——递增的数字,对生成哈希值很关键data——任意有价值的信息。可以是金钱、医疗信息和房地产信息等等key——计算属性,提供给产生哈希值的函数2 }' M- h. C8 }% j
实现区块链类3 j0 F2 V* |, R2 w8 L& ~( k- p& ]
区块链(Blockchain)类需要用一个区块的实例来初始化自己。这个区块也被称为创世区块(genesis block),正因为它是区块链的第一个区块。区块链类实现如下:
class Blockchain {/ j; c7 C0 ?- Y$ Z+ F% Q
private (set) var blocks = [Block]()
init(_ genesisBlock: Block) {- g" d/ D, B" B- m4 F
addBlock(genesisBlock), y$ F2 z w. o8 e
}
func addBlock(_ block: Block) {
if blocks.isEmpty {
// 添加创世区块6 l' q6 Z0 b5 o$ }( u
// 第一个区块没有 previous hash( v e* j1 `5 R' Y: s
block.previousHash = "0"' L: Q) _' O; ^- T/ M
block.hash = generateHash(for: block)8 t" C% e0 ~' Y4 X2 j: G/ @
} else {
let previousBlock = getPreviousBlock()
block.previousHash = previousBlock.hash
block.index = blocks.count
block.hash = generateHash(for: block)% ^- i9 `5 ~+ H. l
}
2 N, X0 l9 F7 L* x, A1 @
blocks.append(block)
displayBlock(block)/ _8 _8 Q# ^" `5 v0 C J
}
private func getPreviousBlock() -> Block {
return blocks[blocks.count - 1]7 o, T, e7 J* w$ k
}2 f0 M5 G3 a* O" n6 m _
/ e$ Q: ^0 ~) ]6 g: ]9 J, a7 h! \
private func displayBlock(_ block: Block) {; ?/ q: ]8 }1 D# V9 K/ a3 Z7 X; p
print("------ 第 \(block.index) 个区块 --------")9 p' P* q& S Y' Y5 J3 Z; s/ I% b
print("创建日期:\(block.dateCreated)")- K6 T% G; g+ ]( F4 A4 R
print("数据:\(block.data)"), [( Z$ X, {! u) A' {; ]
print("Nonce:\(block.nonce)"); \5 }+ F+ ], r/ v1 o6 G# e: b3 P
print("前一个区块的哈希值:\(block.previousHash!)")1 w1 F; W8 i& l* ~
print("哈希值:\(block.hash!)")
}1 }* ~( H6 j* z* m1 j
& ~$ h9 `5 Y4 J: ~; i/ `! K
private func generateHash(for block: Block) -> String {% A; K9 B/ M4 r5 ~- R
var hash = block.key.sha1Hash()
while !hash.hasPrefix("00") {
block.nonce += 1
hash = block.key.sha1Hash(); @$ ?! b& k0 m* x
}) Q) P0 I6 l4 e- d9 U& e: r
return hash
}
} b' s t& @4 [$ p
addBlock 函数用于给区块链增加区块。下一个区块则基于前一个区块的哈希值以及其它属性来计算 key。
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币)。9 b/ w! ]$ M* Q% t
下面实际看看我们的区块链。' \: r% L5 Y3 ^# I L$ {9 g
视频链接9 W# ]% R U0 Q3 D5 N
从 Gist 上下载完整的源码。复制粘贴到 macOS Playground 里就可以运行。$ e2 u' P& r; e
原文 https://juejin.im/post/5a43ae5f51882538650977d1
成为第一个吐槽的人