-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpow.swift
70 lines (59 loc) · 1.7 KB
/
pow.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
struct Block {
var data: String
var previousHash: String
var nonce: Int
var hash: String
init(data: String, previousHash: String) {
self.data = data
self.previousHash = previousHash
nonce = 0
hash = calculateHash()
}
func calculateHash() -> String {
let dataString = data + previousHash + String(nonce)
let dataData = dataString.data(using: .utf8)!
let hash = SHA256.hash(data: dataData)
return hash.map { String(format: "%02x", $0) }.joined()
}
}
class Blockchain {
var chain: [Block]
var difficulty: Int
init() {
chain = [createGenesisBlock()]
difficulty = 2
}
func createGenesisBlock() -> Block {
return Block(data: "Genesis Block", previousHash: "0")
}
func getLatestBlock() -> Block {
return chain[chain.count - 1]
}
func addBlock(newBlock: Block) {
newBlock.previousHash = getLatestBlock().hash
newBlock.mineBlock(difficulty: difficulty)
chain.append(newBlock)
}
func isChainValid() -> Bool {
for i in 1..<chain.count {
let currentBlock = chain[i]
let previousBlock = chain[i - 1]
if currentBlock.hash != currentBlock.calculateHash() {
return false
}
if currentBlock.previousHash != previousBlock.hash {
return false
}
}
return true
}
}
extension Block {
mutating func mineBlock(difficulty: Int) {
let target = String(repeating: "0", count: difficulty)
while hash.prefix(difficulty) != target {
nonce += 1
hash = calculateHash()
}
}
}