在 iOS 中实现区块链
一夜雨十年灯潞
发表于 2022-12-28 14:03:19
185
0
0
注意:本文不涉及节点(nodes/peers)、验证和奖励等。5 X% `2 p% Z$ V& G$ w
我会用 macOS Playground 来演示,快且方便,还有一些实用的函数可以用来生成 SHA 哈希值。
实现区块类; \8 J% ]+ K) p5 d8 K4 J, a u
第一步是实现区块(Block)类,用来表示区块链中的一个区块。实现如下:3 C' X5 p( Q2 r4 g; }
class Block {: {1 t8 @) D, Y' d5 j
var index: Int = 0
var dateCreated: String7 U ]9 t) o/ M Z, p. I
var previousHash: String!
var hash: String!
var nonce: Int9 ?% S6 c0 z' l* r3 o) t, N9 F
var data: String
var key: String {
get {
return String(self.index) + self.dateCreated + self.previousHash + self.data + String(self.nonce)
}
}: X% i, C1 K4 b! H& ~' G
; _" Z4 Y5 Z! }" F0 ^- R+ b
init(data: String) {
self.dateCreated = Date().toString()6 g7 B# A" r% V# a9 ]! w% S
self.nonce = 0* ?6 }: s+ `' l/ y% F
self.data = data/ b7 A& c4 C5 H* P8 N; e' e
}. z& a' V7 z5 w
}
区块类详解:
index——区块位于区块链中的位置。index 为 0 则表示该区块是区块链中的第一个区块。index 为 1 则表示区块链中的第二个区块……以此类推!dateCreated——区块创建的日期previousHash——前一个区块的哈希值hash——当前区块的哈希值nonce——递增的数字,对生成哈希值很关键data——任意有价值的信息。可以是金钱、医疗信息和房地产信息等等key——计算属性,提供给产生哈希值的函数! l6 H2 y. e) B# t+ k$ l9 b: @* V
实现区块链类6 z, u& y! }6 |/ I7 }4 r( e V
区块链(Blockchain)类需要用一个区块的实例来初始化自己。这个区块也被称为创世区块(genesis block),正因为它是区块链的第一个区块。区块链类实现如下:3 g( D9 W P3 t& R- ]. `+ u1 K
class Blockchain {/ S! J" _# R. m7 m5 s: _
private (set) var blocks = [Block](). g A' V* Y$ S
$ E/ V' C% I( e* ]" Q S$ T
init(_ genesisBlock: Block) {2 Q: d# O+ U2 A- f' z! |: I* r
addBlock(genesisBlock)
}
! H. K: e$ w. `6 a) S ]# |
func addBlock(_ block: Block) {2 q6 w) F5 b9 U& Y8 I$ r' P
if blocks.isEmpty {8 W$ P7 T( n4 o% o. f7 T- u
// 添加创世区块; g0 J8 U% F& y
// 第一个区块没有 previous hash
block.previousHash = "0"
block.hash = generateHash(for: block)
} else {
let previousBlock = getPreviousBlock()
block.previousHash = previousBlock.hash& M3 @0 V, b7 n4 i, L0 X6 y6 E
block.index = blocks.count# A$ i4 h" J: e* F' u
block.hash = generateHash(for: block)
}- M$ o( q) I; Q, o* F) b C; R/ ?
1 k: H5 X W& P: H1 m+ h4 h7 w
blocks.append(block)
displayBlock(block)( C1 }" A4 L& A8 B3 m7 O
}0 E+ q0 s8 Z o1 S7 C$ o
4 f( ]% m* w3 E3 ^ F7 i9 [" r
private func getPreviousBlock() -> Block {
return blocks[blocks.count - 1]& b# ]! ^+ i- Z9 i+ I# b
}: f; f, |; s: v! C& s! s# k% O
private func displayBlock(_ block: Block) {9 ~- k( [) r7 z2 [- c# V+ j: k; X" N
print("------ 第 \(block.index) 个区块 --------")
print("创建日期:\(block.dateCreated)")
print("数据:\(block.data)")
print("Nonce:\(block.nonce)")
print("前一个区块的哈希值:\(block.previousHash!)")
print("哈希值:\(block.hash!)")8 V# _/ j: Z4 x. s' W
}9 L' U1 n! I2 d
: Q5 l, C3 p7 h8 h- w! Z7 ~
private func generateHash(for block: Block) -> String {
var hash = block.key.sha1Hash()
while !hash.hasPrefix("00") {
block.nonce += 1
hash = block.key.sha1Hash()) Z5 i" b, v' g' T1 g) \ e: j
}
return hash; Z& x4 x' R% p
}
}1 ]7 a) X U( q2 D o
addBlock 函数用于给区块链增加区块。下一个区块则基于前一个区块的哈希值以及其它属性来计算 key。: @ Z' x- N6 L$ h" _
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币)。
下面实际看看我们的区块链。3 h' F( }! U; H+ }
视频链接
从 Gist 上下载完整的源码。复制粘贴到 macOS Playground 里就可以运行。6 [4 S' c3 }" g$ n
原文 https://juejin.im/post/5a43ae5f51882538650977d1
成为第一个吐槽的人