在 iOS 中实现区块链
一夜雨十年灯潞
发表于 2022-12-28 14:03:19
88
0
0
注意:本文不涉及节点(nodes/peers)、验证和奖励等。4 n3 r! w0 ]! A$ g/ w
我会用 macOS Playground 来演示,快且方便,还有一些实用的函数可以用来生成 SHA 哈希值。 T% O9 k+ C, S% j* C* S4 x4 u) G
实现区块类
第一步是实现区块(Block)类,用来表示区块链中的一个区块。实现如下:
class Block {
var index: Int = 0- l; [1 z9 P4 `% R! x: \) w4 i- c
var dateCreated: String) e; R. i7 H( b4 N2 c6 L
var previousHash: String!# J* K: i7 y6 @: b1 B
var hash: String!4 N/ x4 C! c0 d* J- h) o) p4 p
var nonce: Int
var data: String; U( [+ D, h7 p% O3 g: _
- {! O# |9 ~, C2 k% u$ e0 a
var key: String {
get {. g6 }: @$ ~6 e- S
return String(self.index) + self.dateCreated + self.previousHash + self.data + String(self.nonce)$ S+ L- `7 b6 {
}9 u/ g9 k$ Y1 }% [8 C# S# |! T
}
1 {% U3 C% X+ x
init(data: String) {
self.dateCreated = Date().toString()
self.nonce = 01 I2 i( O! K5 M+ o% g8 [
self.data = data
}' F! J |) k" j. X$ R. J8 L
}
区块类详解:* D1 W6 u* V% J6 N f
index——区块位于区块链中的位置。index 为 0 则表示该区块是区块链中的第一个区块。index 为 1 则表示区块链中的第二个区块……以此类推!dateCreated——区块创建的日期previousHash——前一个区块的哈希值hash——当前区块的哈希值nonce——递增的数字,对生成哈希值很关键data——任意有价值的信息。可以是金钱、医疗信息和房地产信息等等key——计算属性,提供给产生哈希值的函数
实现区块链类
区块链(Blockchain)类需要用一个区块的实例来初始化自己。这个区块也被称为创世区块(genesis block),正因为它是区块链的第一个区块。区块链类实现如下:: R: L' m7 |5 O( m2 H; o
class Blockchain {
private (set) var blocks = [Block](): U5 w4 u" G' [% w+ }& n
init(_ genesisBlock: Block) {- ^2 q/ G2 j0 ~
addBlock(genesisBlock)
}
* R' p' I% c# [4 H( [
func addBlock(_ block: Block) {
if blocks.isEmpty {
// 添加创世区块
// 第一个区块没有 previous hash
block.previousHash = "0"
block.hash = generateHash(for: block)
} else {7 V7 N6 J/ F7 C7 [' F0 Y
let previousBlock = getPreviousBlock()
block.previousHash = previousBlock.hash. u) x/ ?9 o# a' c7 N1 N* A; D
block.index = blocks.count
block.hash = generateHash(for: block)
}0 d; P3 Z% J8 x4 S
blocks.append(block)2 i% z7 g9 ?1 C' t' A' O' O
displayBlock(block)
}( p+ m/ @8 H2 r& W' ?. v
private func getPreviousBlock() -> Block {
return blocks[blocks.count - 1]
}# q' c& a9 i- f' [0 w9 G: e
private func displayBlock(_ block: Block) {
print("------ 第 \(block.index) 个区块 --------")
print("创建日期:\(block.dateCreated)")& B, ~( ]# V" V# ?
print("数据:\(block.data)")
print("Nonce:\(block.nonce)")
print("前一个区块的哈希值:\(block.previousHash!)")1 ?4 s5 t5 [( N$ N U4 q: b i9 k
print("哈希值:\(block.hash!)")+ s2 r- \2 h }5 g% X% N& r |% E
}$ i+ [! E2 Q$ Y
private func generateHash(for block: Block) -> String {. S$ [1 B0 {9 a0 n% v$ A
var hash = block.key.sha1Hash()( ?% o6 f7 ~- a5 L) j {3 X8 i
while !hash.hasPrefix("00") {
block.nonce += 1 \& q5 q* a- F
hash = block.key.sha1Hash()& e5 B$ a+ \; a1 i' L
}
return hash3 A. n5 h$ z, w1 s
}" i( Q. [) h/ W. S8 L4 R
}: r7 H+ N9 H7 d8 T( G* y
addBlock 函数用于给区块链增加区块。下一个区块则基于前一个区块的哈希值以及其它属性来计算 key。+ _2 `% O5 A! u- M! o* t$ y$ y
generateHash 函数负责生成唯一的哈希值并赋值给区块。但并不使用完全随机的哈希,而是需要以“00”开头的特定哈希。这个概念叫做“工作量证明系统”。在实际中工作量证明系统的解法会更复杂,解决的人也会获得奖励(可能是额外的比特币)。: V, [; F- j* [% V4 c4 v
下面实际看看我们的区块链。
视频链接
从 Gist 上下载完整的源码。复制粘贴到 macOS Playground 里就可以运行。
原文 https://juejin.im/post/5a43ae5f51882538650977d1
成为第一个吐槽的人