✨ Enhance blockchain
This commit is contained in:
127
SwiftChainCore/Models/Blockchain.swift
Normal file
127
SwiftChainCore/Models/Blockchain.swift
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Blockchain.swift
|
||||
// Blockchain
|
||||
//
|
||||
// Created by Victor BODINAUD on 27/02/2020.
|
||||
// Copyright © 2020 Victor BODINAUD. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public class Blockchain {
|
||||
var chain = [Block]()
|
||||
let minDifficulty = 2
|
||||
let maxDifficulty = 6
|
||||
let targetBlockTime = 10.0 // en secondes
|
||||
|
||||
static let genesisBlock: Block = {
|
||||
let block = Block()
|
||||
block.previousHash = "0000genesis0000"
|
||||
block.index = 0
|
||||
block.timestamp = 1701388800
|
||||
block.difficulty = 4
|
||||
block.nonce = 12345
|
||||
block.hash = "000088c1731bed4996680d2c50ea3d9b573c1507d2d61866c0deff33a7f8cf5e"
|
||||
return block
|
||||
}()
|
||||
|
||||
init() {
|
||||
chain.append(Blockchain.genesisBlock)
|
||||
print("Genesis block initialized -- hash: \(Blockchain.genesisBlock.hash)")
|
||||
}
|
||||
|
||||
func calculateNewDifficulty() -> Int {
|
||||
guard chain.count >= 2 else { return minDifficulty }
|
||||
|
||||
let lastBlock = chain.last!
|
||||
let previousBlock = chain[chain.count - 2]
|
||||
let timeSpent = Double(lastBlock.timestamp - previousBlock.timestamp)
|
||||
|
||||
if timeSpent < targetBlockTime / 2 {
|
||||
return min(lastBlock.difficulty + 1, maxDifficulty)
|
||||
} else if timeSpent > targetBlockTime * 2 {
|
||||
return max(lastBlock.difficulty - 1, minDifficulty)
|
||||
}
|
||||
|
||||
return lastBlock.difficulty
|
||||
}
|
||||
|
||||
func validateChain(_ chain: [Block]) -> Bool {
|
||||
guard let firstBlock = chain.first,
|
||||
firstBlock.hash == Blockchain.genesisBlock.hash
|
||||
else {
|
||||
print("Genesis block mismatch")
|
||||
return false
|
||||
}
|
||||
|
||||
for i in 1..<chain.count {
|
||||
let block = chain[i]
|
||||
let previousBlock = chain[i - 1]
|
||||
|
||||
if block.previousHash != previousBlock.hash {
|
||||
print("Invalid chain at block \(i): incorrect previous hash")
|
||||
return false
|
||||
}
|
||||
|
||||
if !block.isValid() {
|
||||
print("Invalid chain at block \(i): invalid block hash")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func validateChainTotally(_ chain: [Block]) -> Bool {
|
||||
// Vérifier le genesis block
|
||||
guard let firstBlock = chain.first,
|
||||
firstBlock.hash == Blockchain.genesisBlock.hash
|
||||
else {
|
||||
print("Chain: Invalid genesis block")
|
||||
return false
|
||||
}
|
||||
|
||||
// Vérifier la séquence des blocs
|
||||
for i in 1..<chain.count {
|
||||
let block = chain[i]
|
||||
let previousBlock = chain[i - 1]
|
||||
|
||||
// Vérifier le chaînage
|
||||
if block.previousHash != previousBlock.hash {
|
||||
print("Chain: Invalid block sequence at height \(i)")
|
||||
return false
|
||||
}
|
||||
|
||||
// Vérifier l'index
|
||||
if block.index != i {
|
||||
print("Chain: Invalid block index at height \(i)")
|
||||
return false
|
||||
}
|
||||
|
||||
// Vérifier la chronologie
|
||||
if block.timestamp <= previousBlock.timestamp {
|
||||
print("Chain: Invalid timestamp at height \(i)")
|
||||
return false
|
||||
}
|
||||
|
||||
// Vérifier la difficulté
|
||||
let expectedDifficulty = calculateExpectedDifficulty(at: i, chain: chain)
|
||||
if block.difficulty != expectedDifficulty {
|
||||
print("Chain: Invalid difficulty at height \(i)")
|
||||
return false
|
||||
}
|
||||
|
||||
// Vérifier le bloc lui-même
|
||||
if !block.isValid() {
|
||||
print("Chain: Invalid block at height \(i)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private func calculateExpectedDifficulty(at index: Int, chain: [Block]) -> Int {
|
||||
return chain[index].difficulty
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user